如何让Quaternion.RotateTowards()实现平滑旋转而非瞬间旋转?
解决Quaternion.RotateTowards瞬间旋转问题及X轴鼠标旋转限制
问题根源
- RotateTowards参数顺序错误:你将目标旋转(CubeObj的rotation)放在第一个参数位置,但该方法第一个参数应为当前旋转状态,第二个才是目标旋转。参数颠倒导致直接跳转到目标姿态,无法实现平滑过渡。
- 目标旋转逻辑混淆:用鼠标累积的
rotation.x生成目标四元数,与“自动转向CubeObj”的需求冲突,应基于CubeObj的方位生成目标朝向,再叠加鼠标的有限调整。 - 鼠标输入与自动转向逻辑耦合:当前代码同时处理鼠标累积旋转和自动转向,导致逻辑混乱,既无法实现平滑转向,也不能正确限制X轴旋转范围。
修正代码示例
首先在类中新增变量存储目标水平旋转:
private Quaternion targetHorizontalRotation;
修改clampHorizontalRotation方法:
void clampHorizontalRotation() { // 1. 处理垂直轴旋转(保留原有限制逻辑) float mouseY = Input.GetAxis(yAxis) * sensitivity; rotation.y += mouseY; rotation.y = Mathf.Clamp(rotation.y, -yRotationLimit, yRotationLimit); var yQuat = Quaternion.AngleAxis(rotation.y, Vector3.left); transform.localRotation = yQuat; // 2. 计算朝向CubeObj的水平目标旋转(忽略垂直高度差) Vector3 lookDir = climbing.CubeObj.transform.position - player.transform.position; lookDir.y = 0; Quaternion desiredTargetRot = Quaternion.LookRotation(lookDir); // 3. 平滑过渡到目标旋转(实现自动转向效果) targetHorizontalRotation = Quaternion.RotateTowards( targetHorizontalRotation, desiredTargetRot, rotationSpeed * Time.deltaTime ); // 4. 处理鼠标X轴输入,并限制在目标旋转的±xRotationLimit范围内 float mouseX = Input.GetAxis(xAxis) * sensitivity; Quaternion mouseDeltaRot = Quaternion.AngleAxis(mouseX, Vector3.up); Quaternion tempRot = targetHorizontalRotation * mouseDeltaRot; // 检查旋转角度是否超出限制,超出则截断到最大允许值 float angleDiff = Quaternion.Angle(targetHorizontalRotation, tempRot); if (angleDiff > xRotationLimit) { tempRot = Quaternion.RotateTowards(targetHorizontalRotation, tempRot, xRotationLimit); } // 应用最终旋转到玩家对象 player.transform.localRotation = tempRot; }
补充触发器进入时的初始化逻辑(避免首次进入的突兀跳转):
private void OnTriggerEnter(Collider other) { if (other.CompareTag("CubeTrigger")) // 替换为你的触发器标签 { trigger.clampRotation = true; // 初始化目标旋转为玩家当前的水平姿态 Vector3 currentEuler = player.transform.localEulerAngles; targetHorizontalRotation = Quaternion.Euler(0, currentEuler.y, 0); } }
关键修改说明
- 修正RotateTowards参数顺序,用
targetHorizontalRotation作为当前旋转状态,实现平滑向CubeObj转向的效果。 - 分离垂直/水平轴逻辑,垂直轴保持原有限制,水平轴先处理自动转向,再叠加鼠标的有限调整。
- 通过
Quaternion.Angle计算鼠标调整后的旋转与目标旋转的夹角,确保X轴旋转范围不超过设定的xRotationLimit。 - 触发器进入时初始化目标旋转,避免首次触发时的姿态突变。
内容的提问来源于stack exchange,提问作者dangoqut132
相关产品推荐
相关产品推荐

