Pro*_*mer 3 c# unity-game-engine lerp
我想在x秒内和协程函数中将GameObject从位置A 移动到B. Vector3.MoveTowards我知道如何使用这个,Vector3.Lerp但这次更喜欢这样做,Vector3.MoveTowards因为两个函数的行为都不同.
有了Vector3.Lerp,这样做是这样的:
IEnumerator moveToX(Transform fromPosition, Vector3 toPosition, float duration)
{
float counter = 0;
//Get the current position of the object to be moved
Vector3 startPos = fromPosition.position;
while (counter < duration)
{
counter += Time.deltaTime;
fromPosition.position = Vector3.Lerp(startPos, toPosition, counter / duration);
yield return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我试图做同样的事情Vector3.MoveTowards,但它没有正常工作.问题是移动在x时间或持续时间之前结束.而且,它不能顺利移动.它跳到两个位置的中间而不是位置B的末尾.
这是Vector3.MoveTowards与上述问题一起使用的函数:
IEnumerator MoveTowards(Transform objectToMove, Vector3 toPosition, float duration)
{
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
Vector3 currentPos = objectToMove.position;
float time = Vector3.Distance(currentPos, toPosition) / duration;
objectToMove.position = Vector3.MoveTowards(currentPos, toPosition,
time);
Debug.Log(counter + " / " + duration);
yield return null;
}
}
Run Code Online (Sandbox Code Playgroud)
如何Vector3.MoveTowards在x秒内和协程函数中将GameObject从位置A移动到B ?
请不要暗示,Vector3.Lerp因为那不是我想要使用的.
编辑:
更换
float time = Vector3.Distance(currentPos, toPosition) / duration;
Run Code Online (Sandbox Code Playgroud)
同
float time = Vector3.Distance(startPos, toPosition) / (duration * 60f);
Run Code Online (Sandbox Code Playgroud)
但是当焦点从Unity转移到另一个应用程序时会产生问题.这样做会导致运动无法完成.在启动计时器之前每帧而不是一次计算它似乎更合理.
MatrixTai的答案解决了这两个问题.
因为我很久没有接触过Unity ......但我确实相信你搞砸了计算.
首先,Vector3.MoveTowards(currentPos, toPosition, time)正在谈论
从步行
currentPos到toPosition与每个帧中移动一定的距离time.
因此使用time名称令人困惑,但很好,让我们保持它.
但是,您会在声明中注意到,time每个帧都会移动.但是Vector3.Distance(currentPos, toPosition) / duration速度(m/s),而不是(m /帧).为了使它(m /帧),简单的时间Time.deltatime是(s /帧).
其次,
在协程中,这意味着每个帧都迭代了函数.在这一行中float time = Vector3.Distance(currentPos, toPosition) / duration * Time.deltatime;,你会注意到time随着距离变得越来越小,下一帧时继续减少.
更具体一点,我们可以做一些数学计算.通常这应该用微积分来完成,但我们只需考虑2个点就可以简化它.当对象位置d = 0,并且对象位置d~ = 9.9时,假设端点为10.
在点1处,对象具有time=(10-0)/持续时间,全速.在点2处,对象具有time=(10-9.9)/持续时间,全速的1/10.
除非你希望它每帧都移动得慢,否则你不能保持持续时间的值不变.在每帧之后,您希望保持速度,因此持续时间应随距离而减小.
使物理工作,减去时间的持续时间.
所以最终的解决方案是
float time = Vector3.Distance(currentPos, toPosition) / (duration-counter) * Time.deltaTime;
Run Code Online (Sandbox Code Playgroud)
这是完整的功能:
IEnumerator MoveTowards(Transform objectToMove, Vector3 toPosition, float duration)
{
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
Vector3 currentPos = objectToMove.position;
float time = Vector3.Distance(currentPos, toPosition) / (duration - counter) * Time.deltaTime;
objectToMove.position = Vector3.MoveTowards(currentPos, toPosition, time);
Debug.Log(counter + " / " + duration);
yield return null;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
858 次 |
| 最近记录: |