Grid Movement - Lerp that ends with precise values

Hey there,

This is about grid based movement. I’m trying to move a character from unit 1 to unit 5 with a smooth movement. I already have a nice script that shoots a ray on a plane that also works out the gridSpacing, so I always get values back like 0, 4 or 5, 2, etc.

Still have a couple of problems achieving the rest though:

  1. If I’m using lerp with time.deltaTime and trigger the movement through if target.x > player.x, I always end up with values like 4.9996 or something like that. I absolutely need the player to move to precise values. I thought I could use a Mathf.Round at the end of it, but I wasn’t yet able to figure out what the code should look like to make that happen.

  2. Using lerp, I get a slowdown effect. The player starts moving and the closer he gets to the target, the more he slows down. Ultimately it takes him a ton of time to actually stop at the target. I want to be able to define the walkSpeed and the players movement should always be based on that.

Would be great if you guys could help me out on this one. I’m having a very hard time trying to figure out how to get this to work. Btw, I’m using JavaScript.

I’ll write a solution with half pseudo - half javascript as I’m using c# and can’t remember exact syntax:

var movementDirection = (targetPosition - currentPosition).normalized;
currentPosition += movementDirection * movementSpeed * Time.deltaTime;

if(Vector3.Magnitude(targetPosition - currentPosition)<0.1) //you can change 0.1 to something smaller or bigger
    currentPosition = targetPosition;

this would probably work or at least give you an idea how to handle it.

Don’t use Update, use coroutines.

Use Vector3.MoveTowards, preferably in conjunction with coroutines as they are handy.

function MoveTo(target: Vector3) {
  while (transform.position != target) {
    var delta = Time.deltaTime * speed; // Assuming existing speed variable.
    transform.position = Vector3.MoveTowards(transform.position, target, delta);
    yield;
  }
}

You probably want to change the method of movement, but using Vector3.MoveTowards will likely help you.

Awesome, thank you guys!

Statement, this works great, the only problem left is that there’s still a speedup from the Time.deltaTime * speed - so if I move something from the bottom left of the screen to the top right, it speeds up considerably in the middle and stops abruptly at the top.

Is there a smart way of having the units speed always stay the same while moving?

Oh, I’m a bozo. I forgot to turn off the trigger that was used to start the coroutine in the update function, that’s why it went crazy.

Thanks so much for the help!

I’m no expert and this is 4 years later but… Unity 5 is out and they have some new features…

A possible solution is to add a StateMachineBehaviour with OnStateEnter() for the Idle state and MatchTarget for where you want to be?