Smooth Forward Movement with a CoRoutine
Hi All,
I have been playing around with coroutines and have smooth movement to slowly rotate a game object 90 degrees, as apposed to instantly slipping it 90 degrees on a button press.
What i have been trying to do this afternoon is slowly move a Game Object forward 5 units on it's Forward Vector, but again, this needs to be a smooth forward movement rather than an instant movement.
I have tried the below code, but it only navigates to position 5, and when I rotate it and move it forward again, it simply moves towards the NEW forward location of (0, 0, 5).
I know it has something to do with finding and Lerping to the new position but I just can't seem to set it. I am calling this from a button press if statement in void update.
IEnumerator MoveForward()
{
float inTime = 0.8f;
Vector3 fromPos = transform.position;
Vector3 Endpos = transform.forward * 5f;
for (float t = 0f; t <= 1; t += Time.deltaTime / inTime) {
transform.position = Vector3.Lerp (fromPos, Endpos, t);
yield return null;
}
}
Thanks in advance.
Answer by arrnav · May 09, 2020 at 09:43 AM
I know it's been 2 years and this must have been solved long ago by OP, but the answer may still come of use for beginners looking at this question. So here goes..
Don't use Update to Lerp unless absolutely necessary. If statements can make your code quickly messy. Coroutines give you way more control.
Also, the problem is at the 6th line of your code. You were using transform.forward instead of transform.position + transform.forward as your final position everytime this function is called, causing the object to go to the (0, 0, 5) position every time instead of using it's previously updated position.
What you want to do is add (transform.forward 5)* to your current position to move in that direction by 5 units correctly every time on your button press.
The following code should work, it is a simple Lerp within a Coroutine, so it should work with transform.forward with ease :
private IEnumerator SmoothLerp (float time)
{
Vector3 startingPos = transform.position;
Vector3 finalPos = transform.position + (transform.forward * 5);
float elapsedTime = 0;
while (elapsedTime < time)
{
transform.position = Vector3.Lerp(startingPos, finalPos, (elapsedTime / time));
elapsedTime += Time.deltaTime;
yield return null;
}
}
Call the Coroutine using -
StartCoroutine (SmoothLerp (3f)); // 3f is the time in seconds the movement will take.
As both Lerp & Coroutine functions are completely orthogonal, they work well together, so you don't really NEED DoTween or iTween unless working with UI elements.