Unity C#中使用Vector3.Slerp移动角色出现曲线偏移问题排查
问题:使用Vector3.Slerp实现玩家移动时出现轴偏差
我写了一段代码,想用Slerp让玩家在X轴和Z轴上以10单位为增量移动,但现在Slerp的设置有问题。比如起始位置是(10, 1, 0),目标位置是(20, 1, 0)时,移动过程中玩家的Y轴和Z轴会出现微小偏差,但起止位置完全正确,问题肯定出在Slerp本身。我忽略了什么导致移动出现曲线?
代码片段
... public void Forward(InputAction.CallbackContext context){ if (context.started && Rotating == false && Moving == false) { // 检查玩家是否可以移动 percentageComplete = 0; // 插值进度百分比 startPosition = rb.transform.position; endPosition = rb.transform.position + rb.transform.rotation * Vector3.forward * 10; endPosition[1] = 1; endPosition[0] = Mathf.Round(endPosition[0]); endPosition[2] = Mathf.Round(endPosition[2]); CheckPOS(); // 检查目标位置是否合法,合法则将Moving设为true } } ... public void Update() { if (Moving == true){ if (percentageComplete < 1) { elapsedTime += Time.deltaTime; percentageComplete = elapsedTime / desiredDuration; rb.transform.position = Vector3.Slerp(startPosition, endPosition, percentageComplete); if (percentageComplete > 1) { posX = Mathf.Round(rb.transform.position.x / 10); posY = Mathf.Round(rb.transform.position.z / 10); rb.transform.position = new Vector3(posX * 10, 1, posY * 10); Moving = false; }} } }
问题原因
Vector3.Slerp是球面插值函数,它的作用是将两个三维点当作球面上的点,沿着球面弧线完成插值,而非直线。即使你的起止点在同一平面(Y=1),Slerp也会默认以原点为球心计算弧线路径,这就导致移动过程中Y轴、Z轴出现微小偏差——因为它走的不是两点之间的直线。
解决方案
如果需要的是两点间的直线移动,直接替换成线性插值函数Vector3.Lerp即可,它会严格沿着起止点的直线路径插值,不会出现轴偏差。修改后的Update方法代码如下:
public void Update() { if (Moving == true){ if (percentageComplete < 1) { elapsedTime += Time.deltaTime; percentageComplete = elapsedTime / desiredDuration; // 替换为线性插值 rb.transform.position = Vector3.Lerp(startPosition, endPosition, percentageComplete); if (percentageComplete > 1) { posX = Mathf.Round(rb.transform.position.x / 10); posY = Mathf.Round(rb.transform.position.z / 10); rb.transform.position = new Vector3(posX * 10, 1, posY * 10); Moving = false; } } } }
内容的提问来源于stack exchange,提问作者Chris W.
相关产品推荐
相关产品推荐

