求助:鼠标视角控制函数灵敏度随俯仰角变化问题
鼠标视角控制灵敏度随俯仰角变化的问题
我已经迭代这段鼠标视角控制代码好几周了,但始终存在一个问题:输出的灵敏度会随着俯仰角(pitch)变化。代码基本功能正常,但这个问题很影响体验。
相关代码如下:
//Grab mouse input float rotateHorizontal = Input.GetAxis("Mouse X"); float rotateVertical = -Input.GetAxis("Mouse Y"); Vector3 rotation = new Vector3(rotateVertical, rotateHorizontal, 0); transform.Rotate(sensitivity * Time.deltaTime * rotation); Vector3 eAngles = transform.eulerAngles; float pitch = eAngles.x; pitch = ClampAngle(pitch, -camClamp, camClamp); transform.localEulerAngles = new Vector3(pitch, eAngles.y, eAngles.z);
我可以确定问题不在ClampAngle函数上(它来自可靠来源),请问我到底遗漏了什么?感谢各位的帮助。
问题出在哪
你这问题核心是用了transform.Rotate()直接给局部坐标系加旋转增量——当俯仰角(Pitch)不是0的时候,鼠标垂直输入对应的旋转轴方向变了,导致实际转的角度在世界空间里的有效分量不一样,灵敏度自然就跟着变了。
另外每次从transform.eulerAngles读角度修正也有坑,eulerAngles的数值会在0-360之间跳,搞不好就会出现角度计算异常。
怎么改
正确的做法是分开存Yaw(左右转)和Pitch(上下转)的累积角度,分别处理:Yaw绕世界Y轴转,Pitch绕局部X轴转,最后把累积的角度直接赋值给transform的旋转。
改完的代码大概是这样:
// 先在类里定义两个成员变量存累积角度 private float currentYaw = 0f; private float currentPitch = 0f; public float sensitivity = 2f; public float camClamp = 89f; void Update() { // 读取鼠标输入 float rotateHorizontal = Input.GetAxis("Mouse X"); float rotateVertical = -Input.GetAxis("Mouse Y"); // 累加角度增量 currentYaw += rotateHorizontal * sensitivity * Time.deltaTime; currentPitch += rotateVertical * sensitivity * Time.deltaTime; // 限制俯仰角的范围 currentPitch = ClampAngle(currentPitch, -camClamp, camClamp); // 直接应用旋转:Yaw绕世界Y轴,Pitch绕局部X轴 transform.rotation = Quaternion.Euler(currentPitch, currentYaw, 0f); }
这么改的好处:
- 自己存角度变量:不用从
transform.eulerAngles读,避免了数值循环的问题,增量计算更稳定。 - 明确旋转空间:左右转(Yaw)固定绕世界Y轴,不管抬头低头都不会影响左右的灵敏度;上下转(Pitch)绕局部X轴,保证上下移动的手感始终一致。
- 直接用四元数赋值:绕开了
transform.Rotate()的局部坐标系叠加问题,旋转逻辑更清晰。
这样改完之后,不管俯仰角在什么位置,鼠标灵敏度都会保持一致。
内容的提问来源于stack exchange,提问作者spacemann
相关产品推荐
相关产品推荐

