transform.Translate Vector3.Lerp doesn't move smoothly
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerController_1 : MonoBehaviour
{
void Update()
{
if (Input.GetKeyUp("w"))
{
StartCoroutine(moveUpCoroutine());
}
}
IEnumerator moveUpCoroutine()
{
yield return new WaitForSeconds(1); // Wait 1 sec
//MOVE 1 Z UNIT
transform.Translate(Vector3.forward);
//transform.Translate(Vector3.Lerp(transform.position, Vector3.forward, 1f));
StopAllCoroutines();
}
}
Hello guys, I am trying out a 3D FPS grid turn-based movement (Dungeon Master, Grimrock) and having trouble with it.
Now, instead of moving smoothly per Z unit, I am getting "Teleporting" movements even with Lerp.
Also, I am not sure whether it is a good idea to use Coroutine to prevent the player from spamming the key. Any advice would be greatly appreciated.
Answer by streeetwalker · Jul 04, 2020 at 04:57 AM
Hi @Johnkook the 3rd parameter of any LERP represents to be the percentage of completion between the start and end. In the case of a Vector3 LERP, it represents the linear interpolation between the start and end position vectors.
Thus if it is 0 (0%), the start position is returned. If it is 1 (100%) the end position If it is 0.5, a position halfway on a line between start and end is returned. You get the idea?
So in your situation, your end position is always (0,0,1) - ie. Vector3.forward - and the percentage you pass is always 1, you always get the end position.
It's not clear exactly what you want to do, because you are using transform.localPosition as the first parameter.
If this object is not a child of another object, transform.localPosition is the same as tranform.position.
If it is a child, it appears you want to move the parent by the local position of the child (that is, the positon of the child with respect to the parent.)
So your intention is a bit confusing.
[Edit] @Johnkook OK based on your further reply, If you want the object to move to the next position, which is one meter - or unit - forward from its current position, smoothly, and also prevent users from spamming the key, then you can use a Vector3 LERP inside a Coroutine.
A Coroutine for animation is a good idea if it keeps your Update or FixedUpdate loops cleaner that would be otherwise. In your case, it probably doesn't matter. But for to follow your example, you could do it this way - I haven't tested this, so check for typos and what not:
private bool moveUpIsRunning = false;
private float moveUpTime = 1f;
void Update() {
if (Input.GetKeyUp("w")) {
if( !moveUpIsRunning ) StartCoroutine(moveUpCoroutine());
}
}
IEnumerator moveUpCoroutine() {
moveUpIsRunning = true;
Vector3 startPos = transform.position;
Vector3 endPos = transform.position + Vector3.forward;
float countTime = 0;
while( countTime <= moveUpTime ) {
float percentTime = countTime / moveUpTime;
transform.position = Vector3.Lerp(startPos, endPos, percentTime);
yield return null // wait for next frame
countTime += Time.deltaTime;
}
// because of the frame rate and the way we are running LERP,
// the last timePercent in the loop may not = 1
// therefore, this line ensures we end exactly where desired.
transform.position = endPos;
moveUpIsRunning = false;
}
Yes, indeed it does move perfectly now. I now can see why. Thank you @streeetwalker
Answer by Johnkook · Jul 04, 2020 at 06:16 AM
Hello @streeetwalker . Apologies for a very confusing question. I have corrected my code. To reiterate my question again, I use transform.Translate(Vector3.forward); to move Z-axis once every user pressed.
However, it didn't smoothly transform my position, hence the lerp. My intention is to grab my current transform.position as my starting position and moves to (0,0,1) - end position, smoothly.