Smooth movement on click.

Hello. I’m newbie in unity3d. I’m trying to do that: when I click on a plane (ground) character (plane), character should go to that point (right now just go straight w/o any pathfinding). So I wrote^W found that code:

var rayCastPlane : Transform;
function Update () {

 if (!Input.GetMouseButton (0))
 	return;
 var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
 var hit : RaycastHit;

  if (Physics.Raycast (ray, hit, 100)) {
  Debug.DrawLine (Camera.main.transform.position, hit.point, Color.red);
         Debug.Log(hit.point);
  var wantedPosition= Vector3(hit.point.x, transform.position.y, hit.point.z);
  transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime);
  }
}

But at first it goes only if button is pressed. second, it spends always the same time for any distance.

this is the code, that causes the object to only move when the mouse is down. ‘return’ means that the rest of the Update function is ignored and therefore no objects can be moved.

i’d use

if (Input.GetMouseButtonDown(0)) {
//all the raycast stuff in here
}

to determine the target position
then use

moveVector = Vector3(targetPosition - currentPosition);

transform.position = currentPosition + moveVector.normalized * speed;

.normalized means the vector is only 1 unit long, which means that the object always moves 1 step forward. with the variable speed you can modify the speed of the object, 0 means its standing still, 1 means the speed isn’t modified, the larger the numbers get the faster the object will be, negative numbers will make the object move away from the target.

once moveVector (not normalized) has a length smaller than the speed you should move the object to the target position, otherwise the object will kinda jump around the target position

note that the speed is dependant on the framerate in this solution, you might want to use FixedUpdate instead

to sum it all up:

var rayCastPlane : Transform;
private var wantedPosition : Vector3;
var speed : int = 5;
private var moving : System:Boolean = false;

function FixedUpdate () {

 if (Input.GetMouseButtonDown(0)) {
  var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 var hit : RaycastHit;

  if (Physics.Raycast (ray, hit, 100)) {
   Debug.DrawLine (Camera.main.transform.position, hit.point, Color.red);
   Debug.Log(hit.point);
   var wantedPosition = Vector3(hit.point.x, transform.position.y, hit.point.z);
   moving = true;
  }
 }

 if(moving) {
  var moveVector = Vector3(wantedPosition - transform.position);
  if (moveVector.magnitude < speed)
  {
   transform.position = transform.position + moveVector.normalized * speed;
  }
  else
  {
   transform.position = wantedPosition;
   moving = false;
  }
 }
}

there might be some mistakes in the code, i just threw it together very quickly and didn’t test it, but this should get you the basic idea

To solve this, use the operatior Mathf.SmoothStep.

This gives smooth “acceleration” and “decelleration”.

The format is something like this:

var moveSpeed : float;
var constant : float; // This is the variable that changes how fast you accelerate and decellerate

moveSpeed = Mathf.SmoothStep(moveSpeed,moveSpeed,constant*Time.deltaTime);

We use that code:

var obj:Transform;
var hit:RaycastHit;
var move: boolean = false;
var moveSpeed:float;
var moveTime:float;
private var startTime:float;
var rayCastPlane : Transform;
var speed : float =25;
function Update () {

 //if (!Input.GetMouseButton (0))
  //return;
 
   if (Input.GetButtonDown ("Fire1"))
   {
  var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

if (Physics.Raycast (ray, hit, 10000)) {
move =true;
startTime=Time.time;
}
}
//Debug.DrawLine (Camera.main.transform.position, hit.point, Color.red);
//Debug.Log(hit.point);
//var wantedPosition= Vector3(hit.point.x, 1, hit.point.z);
//transform.LookAt(wantedPosition);
//transform.Translate(Vector3.forward *  Time.deltaTime, Space.Self);

   if(move){
      var curTime = Time.time;
      var elapsedTime = curTime - startTime;
      var amountToMove = elapsedTime / moveTime;
      print(amountToMove);
      var wantedPosition= Vector3(hit.point.x, 1, hit.point.z);
      transform.Find("Compas").LookAt(wantedPosition);
      transform.Translate(Vector3.forward *  Time.deltaTime, transform.Find("Compas"));
	  var camera = GameObject.FindWithTag("MainCamera");
	  camera.transform.Translate(Vector3.forward *  Time.deltaTime, transform.Find("Compas"));

   //transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.time*speed);
   if(Vector3.Distance(transform.position, wantedPosition) < 0.5){
         move = false;
      }

   }

}