You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:鼠标视角控制函数灵敏度随俯仰角变化问题

鼠标视角控制灵敏度随俯仰角变化的问题

我已经迭代这段鼠标视角控制代码好几周了,但始终存在一个问题:输出的灵敏度会随着俯仰角(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:40:36