我不太明白如何管理协程中的旋转,我通过协程管理它们,因为每个交互对象都通过通用交互脚本,我尝试了这样的操作,但期望的效果不是我所希望的,我想要一个用于打开和关闭门的简单平滑运动,但使用我的脚本,它只会变慢一次,然后你必须等待它重置的时间,然后它再次变慢,如果我反复单击按钮进行交互,门关/开得很快..你能帮我吗?
using System.Collections;
using UnityEngine;
public class DoorsWithoutKey : MonoBehaviour
{
public bool open = false;
[SerializeField] private float smooth = 2.0f;
[SerializeField] private float DoorOpenAngle = 90.0f;
private Vector3 defaulRot;
private Vector3 openRot;
[SerializeField] public float lerpDuration = 0;
void Start()
{
defaulRot = transform.eulerAngles;
openRot = new Vector3(defaulRot.x, defaulRot.y + DoorOpenAngle, defaulRot.z);
}
public void NewOpenClosed()
{
open = !open;
StartCoroutine(OpenDoor());
}
private IEnumerator OpenDoor()
{
float timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
if (open)
{
gameObject.transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, openRot, timeElapsed / lerpDuration);
}
else
{
gameObject.transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, defaulRot, timeElapsed / lerpDuration);
}
timeElapsed += Time.deltaTime;
yield return null;
}
}
}
我希望门能顺利移动
lerp的参数值需要提前缓存。
这确保了 lerp 在每次迭代中使用相同的参数。
如果第一个参数
a
不固定,则 lerp 每次迭代都会改变。
Vector3.Lerp的定义
通过插值 t 在点 a 和 b 之间进行插值
例如。当
a
不固定时:
Lerp(0, 10, t)
Lerp(1, 10, t)
Lerp(2, 10, t)
Lerp(3, 10, t)
..
很明显,对于相同的 t 值,这些会产生不同的值。
如果我们存储起始值,那么 lerp 将为每次迭代使用相同的值,并正确插值。
我更新了您的函数,使其更加简洁。
private IEnumerator OpenDoor()
{
var t = 0f;
var start = transform.eulerAngles;
var target = open ? openRot : defaulRot;
while (t < 1)
{
gameObject.transform.eulerAngles = Vector3.Slerp(start, target, t);
t += Time.deltaTime / lerpDuration;
}
}
如果您希望在程序运行时能够打开/关闭,您需要计算从当前角度旋转到目标角度需要多少时间,并使用计算出的时间值来获取
t
。