Unity旧输入系统实现鼠标左键拖拽旋转相机相关问题咨询
现有基础脚本
你已编写完成的基础鼠标旋转相机代码如下:
using UnityEngine; public class RotatingTheCamera { [SerializeField] private float sensitivityVert; [SerializeField] private float sensitivityHor; [SerializeField] private float minimumVert; [SerializeField] private float maximumVert; private float _rotationX = 0; private void Update() { if (Time.timeScale == 1) { _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert; _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert); float delta = Input.GetAxis("Mouse X") * sensitivityHor; float rotationY = transform.localEulerAngles.y + delta; transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0); } } }
提示:如果需要将该脚本直接挂载到场景GameObject上运行,需要让类继承
MonoBehaviour,否则无法正常获取transform等组件对象、也无法被Unity识别为可挂载脚本。
问题对应解答
1. 实现按住鼠标左键才触发拖拽旋转的方法
直接在现有旋转逻辑的判断条件中,增加鼠标左键持续按住的校验即可。在判断Time.timeScale == 1的同级,加上Input.GetMouseButton(0)判断,只有两个条件同时满足时才执行旋转计算。Input.GetMouseButton(0)的规则是:参数0对应鼠标左键,按住左键期间每帧返回true,松开左键立刻返回false,刚好匹配拖拽交互的触发逻辑。
修改后的判断结构示例:
if (Time.timeScale == 1 && Input.GetMouseButton(0)) { // 原有旋转计算逻辑放在这里即可 }
如果需要避免按下左键瞬间相机因为鼠标位置偏移产生跳变,可以在Input.GetMouseButtonDown(0)(左键按下的第一帧)时记录当前鼠标位置和相机初始角度,后续旋转计算用偏移量做差值即可,基础交互需求直接加上述判断就能满足。
2. 不使用新输入系统的兼容性说明
完全可以实现。上述提到的Input.GetMouseButton、Input.GetAxis等所有用到的输入API,都是Unity原生旧输入系统(Legacy Input Manager)内置的接口,不需要安装新输入系统包,只要项目Player Settings中Active Input Handling选项保持默认的Input Manager或者Both,就能直接运行,不需要额外配置。
旧输入系统内置了默认的Mouse X、Mouse Y输入轴,不需要手动添加轴配置即可直接读取鼠标移动偏移。常用鼠标相关接口如下:
Input.GetMouseButtonDown(0):鼠标左键按下的第一帧返回true,适合做按下瞬间的状态初始化Input.GetMouseButton(0):鼠标左键持续按住期间每帧返回true,适合做持续触发的拖拽旋转逻辑Input.GetMouseButtonUp(0):鼠标左键松开的第一帧返回true,适合做拖拽结束的状态重置
3. 旋转逻辑是否需要添加Time.deltaTime的说明
不需要。Input.GetAxis("Mouse X")和Input.GetAxis("Mouse Y")返回的是帧间隔内鼠标实际移动的像素偏移值,这个数值本身和帧率、帧间隔时长没有关联。如果错误给鼠标偏移值乘Time.deltaTime,反而会导致旋转速度随设备帧率波动:高帧率下旋转速度会变得极慢,低帧率下旋转速度异常快,严重破坏操作手感。
只有当逻辑是基于时间的连续增量(比如键盘按住持续旋转、相机自动旋转)时,才需要乘Time.deltaTime把每帧增量转换为和帧率无关的时间单位,鼠标输入驱动的旋转不需要加这个参数。
可直接运行的完整修改版脚本
using UnityEngine; public class RotatingTheCamera : MonoBehaviour { [SerializeField] private float sensitivityVert = 2f; [SerializeField] private float sensitivityHor = 2f; [SerializeField] private float minimumVert = -60f; [SerializeField] private float maximumVert = 60f; private float _rotationX = 0; private void Start() { // 初始化读取当前相机X轴角度,避免启动时旋转值跳变 Vector3 startEuler = transform.localEulerAngles; _rotationX = startEuler.x > 180 ? startEuler.x - 360f : startEuler.x; } private void Update() { if (Time.timeScale == 1 && Input.GetMouseButton(0)) { _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert; _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert); float rotationY = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityHor; transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0); } } }
内容的提问来源于stack exchange,提问作者Anonymous

