- Home /
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.
Answer by Statement · Jun 06, 2011 at 12:19 PM
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.
Answer by homeros · Jun 06, 2011 at 08:29 AM
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.
Answer by Eric5h5 · Jun 06, 2011 at 12:09 PM
Don't use Update, use coroutines.
http://www.unifycommunity.com/wiki/index.php?title=MoveObject http://www.unifycommunity.com/wiki/index.php?title=GridMove
Answer by DorkNemesis · Jun 06, 2011 at 01:01 PM
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?
The reason you might be having speedups sounds like the speed variable is changing while the character is moving, and it probably shouldn't. $$anonymous$$aybe you have some old code still poking around with that variable? You should also only call this function once as a co routine, not continuously. Try making the speed variable a constant number, it should move with a constant speed unless you have any other scripts influencing the character. Note that if you are using character controllers and such, gravity might come into play, or collision vs steep slopes. This $$anonymous$$oveTowards solution is probably quite crude animation wise, since it will start and stop with the same constant speed, and won't appear as accelerating nor decelerating during start and end.
Answer by DorkNemesis · Jun 06, 2011 at 01:27 PM
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!
Your answer
Follow this Question
Related Questions
Lerp incomplete movement problem 1 Answer
Grid-based movement: How to face forward 2 Answers
How to smooth my camera (Vector3.Lerp) 0 Answers
Movement Script 1 Answer
Coroutine Moving 1 Answer