Vector3.Lerp 不工作
Vector3.Lerp is not working
我正在努力顺利地从我当前的位置移动到我硬编码的新位置,但即使使用 Vector3.Lerp 和 Vector3.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 等等,你明白了。
但是这种做事方式给你一个断断续续的动画,所以你想使用传递的时间来计算每个 Update
的 perc
参数是多少(示例代码在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());
我正在努力顺利地从我当前的位置移动到我硬编码的新位置,但即使使用 Vector3.Lerp 和 Vector3.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 等等,你明白了。
但是这种做事方式给你一个断断续续的动画,所以你想使用传递的时间来计算每个 Update
的 perc
参数是多少(示例代码在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());