Vector3.Lerp 不工作

Vector3.Lerp is not working

我正在努力顺利地从我当前的位置移动到我硬编码的新位置,但即使使用 Vector3.LerpVector3.MoveTowards只是正常移动玩家,没有任何延迟效果。

我也尝试在 Vector3.Lerp 方法中添加 Time.deltaTime,但它只是稍微移动了播放器。我只是想让玩家顺利地走向设定的位置。

我是 Unity 的新手,非常感谢任何帮助。

public class PlayerControl : MonoBehaviour {
    //change position
    private float leftX = -1.65f;
    private float leftY = 0.00f;
    private float rightX = -1.00f;
    private float rightY = -1.13f;

    private Vector3 carPosition;
    private float slowTime = 2f;

    void Start () {
        //set the player to its current position
        carPosition = transform.position;
    }

    void Update () {
        //control the player
        if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) {
            Debug.Log("Pressed!");

            if(transform.position.y <= -0.5) {
                carPosition.x = leftX;
                carPosition.y = leftY;
            }

            if(transform.position.y >= 0) {
                carPosition.x = rightX;
                carPosition.y = rightY;
            }

            //transform.position = carPosition;
            transform.position = Vector3.Lerp(transform.position, carPosition, slowTime);
        }
    }
}

你的错误在这里:

transform.position = Vector3.Lerp(transform.position, carPosition, slowTime);

不要使用 transfrom.position 作为参数。使用一些 startPosition 变量,如

transform.position = Vector3.Lerp(startPosition, carPosition, slowTime);

此外,slowTime 应该是固定到 [0, 1] 的行进距离的一小部分。当你把 2f 放在那里时,你会立即移动到终点。把 0.5f 放在那里看看我在说什么。

请检查: https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

编辑:重写答案以更好地解释 Lerp 的工作原理。

Lerp 以一种非常简单的方式工作:让我们调用参数 V1、V2 和 perc - result = Vector3.Lerp(V1, V2, perc).

假设 V1 = (0,0,0)V2 = (1,0,0)perc = 0,2f。使用这些固定参数,您会得到 result = 0.2f 或者换句话说,您会得到一个更接近 V2 的 Vector3,从 V1 开始,按百分比 perc.

现在,如果要以固定步长将对象从 V1 移动到 V2,则需要在每次 Update() 调用时修改参数 perc。例如,如果你想在 5 步内到达目的地,那么你需要使用 perc 的序列调用 Lerp 5 次:0.2 - 0.4 - 0.6 - 0.8 - 1。您想使用 10 步移动对象吗?然后你使用序列 0.1 - 0.2 - 0.3 等等,你明白了。

但是这种做事方式给你一个断断续续的动画,所以你想使用传递的时间来计算每个 Updateperc 参数是多少(示例代码在link 由 Lukasz 提供)以获得从开始到结束的平滑和线性运动。

所以你的 class 应该是这样的:

using UnityEngine;

public class PlayerControl : MonoBehaviour {    

    private float leftX = -1.65f;
    private float leftY = 0.00f;
    private float rightX = -1.00f;
    private float rightY = -1.13f;
    private float speed = 2f, startTime, totalDistance = 0f;
    private Vector3 carPosition, startPos;

    void Start () {
        carPosition = transform.position;
        startPos = carPosition;
    }

    void Update () {
        if (Input.GetKeyDown (KeyCode.Space) || Input.GetMouseButtonDown (0)) {
            Debug.Log ("Pressed!");
            startTime = Time.time;
            if (transform.position.y <= -0.5) {
                startPos = transform.position;
                carPosition.x = leftX;
                carPosition.y = leftY;
            }
            if (transform.position.y >= 0) {
                startPos = transform.position;
                carPosition.x = rightX;
                carPosition.y = rightY;
            }
            totalDistance = Vector3.Distance(startPos, carPosition);
        }
        if (startPos != carPosition) {
            float newPercentageBetweenVectors = (Time.time - startTime) * speed / totalDistance;
            transform.position = Vector3.Lerp (startPos, carPosition, newPercentageBetweenVectors);
        }
    }
}

另一种使用 Lerp 移动对象的方法是保持固定 perc 并使用对象的位置作为第一个参数。这会给你一个对数类型的运动,开始时越快越接近目的地越慢,但要注意你永远不会到达它,因为它是一个渐近线 - 这意味着你需要自己检查如果当前位置足够接近最终位置特定距离,例如 10^-2,代码如下:

using UnityEngine;

public class PlayerControl : MonoBehaviour {

    private float leftX = -1.65f;
    private float leftY = 0.00f;
    private float rightX = -1.00f;
    private float rightY = -1.13f;
    private float speed = 2f, totalDistance;
    private Vector3 carPosition;

    void Start () {
        carPosition = transform.position;
    }

    void Update () {
        if (Input.GetKeyDown (KeyCode.Space) || Input.GetMouseButtonDown (0)) {
            Debug.Log ("Pressed!");
            if (transform.position.y <= -0.5) {
                carPosition.x = leftX;
                carPosition.y = leftY;
            }
            if (transform.position.y >= 0) {
                carPosition.x = rightX;
                carPosition.y = rightY;
            }
        }
        if (transform.position != carPosition) {
            transform.position = Vector3.Lerp (transform.position, carPosition, speed * Time.deltaTime);
            totalDistance = Vector3.Distance(transform.position, carPosition);
            if (totalDistance < Mathf.Pow(10,-2)) transform.position = carPosition;
        }
    }
}

如果您提供的 speed 足够低,则在这种情况下没有必要使用 Time.deltaTime。 Lerp 的第二次使用特别指出(并且确实被广泛使用)用于将相机移向游戏对象。

这是我学会的方法:

制作一个新协程(IEnumerator 标题){}。

创建一个名为 t 的浮点数。将其值赋给 0。

做一个 while 循环:

while(t < 1){

}

输入“t += Time.deltaTime / speed

做transform.position = Vector3.Lerp(transform.position, carPosition, t);

做 yield return null。

我就是这样学的。你完成的代码应该是这样的:

IEnumerator Drive(){  
    float t = 0;  
    while(t < 1){    
         t += Time.deltaTime / speed;    
         transform.position = Vector3.Lerp(transform.position, carPosition, t);  
         yield return null;     
    }  
}

还要记得启动协程。 (StartCoroutine(Drive());