Input System Package 鼠标输入
一、核心前提:鼠标的核心全局实例对象
和键盘的 Keyboard.current 对应,鼠标的所有输入都基于一个全局唯一的核心实例:
Mouse.current
✅ 说明:Mouse.current 是Input System封装的鼠标单例对象,包含鼠标的所有硬件信息和输入状态,是纯代码方案的核心,无需要创建任何配置文件、无需绑定,直接调用即可。
⚠️ 安全判断:和键盘一样,建议每次获取前做空值判断,防止无鼠标设备(如移动端)运行时报错:
Mouse mouse = Mouse.current; if(mouse == null) return; // 无鼠标设备则直接退出
二、方案一:纯代码直接调用鼠标输入(首选!极简无配置)
这是最常用、最推荐的写法,和旧的 Input.mousePosition 写法接近,学习成本极低,无需任何配置文件,代码量少,适合所有独立开发、快速原型、中小型项目,能实现鼠标的全部功能,优先级最高!
✔️ 核心:先记住【鼠标输入的5大核心类型】
鼠标的输入逻辑分为5类,几乎覆盖所有开发需求,所有API调用格式统一,和键盘的isPressed/wasPressedThisFrame逻辑完全一致,非常容易记忆,所有API都挂载在 Mouse.current 下:
✅ 1. 获取【鼠标当前屏幕位置】mousePosition
功能说明
获取鼠标在屏幕坐标系下的实时坐标值,返回 Vector2 类型。
- 屏幕坐标系原点:屏幕左下角为 (0,0)
- 屏幕右上角坐标为
(Screen.width, Screen.height) - 和旧输入系统
Input.mousePosition完全等价,只是API写法不同
调用代码
Mouse mouse = Mouse.current;
if(mouse == null) return;
// 获取鼠标屏幕位置
Vector2 mouseScreenPos = mouse.position.ReadValue();
Debug.Log("鼠标屏幕坐标:" + mouseScreenPos);
✅ 2. 获取【鼠标移动增量】delta (重中之重!鼠标拖动/视角旋转核心)
功能说明
获取鼠标在「当前帧」的移动偏移量,返回 Vector2 类型,x对应左右移动、y对应上下移动。
- 这是鼠标最核心的功能之一:比如 FPS游戏的镜头旋转、RTS游戏的视角拖动、物体旋转、鼠标拖拽跟随 都是基于这个API实现
- 该值是相对偏移量:鼠标不动时返回
(0,0),向左移动x为负,向右为正;向上移动y为正,向下为负 - 完美替代旧输入系统的
Input.GetAxis("Mouse X")和Input.GetAxis("Mouse Y")
调用代码
Mouse mouse = Mouse.current;
if(mouse == null) return;
// 获取鼠标帧移动增量
Vector2 mouseDelta = mouse.delta.ReadValue();
Debug.Log("鼠标帧移动增量 X:" + mouseDelta.x + ",Y:" + mouseDelta.y);
// 常用场景:乘以灵敏度,实现平滑的鼠标移动逻辑
float mouseSensitivity = 0.1f;
float rotateX = mouseDelta.x * mouseSensitivity;
float rotateY = mouseDelta.y * mouseSensitivity;
✅ 3. 鼠标【左键/右键/中键】的按键状态判断(点击/长按/松开)
鼠标的左键、右键、中键(滚轮键) 都属于「按键」,和键盘按键的3个核心状态API完全一致,这是Input System的统一设计,一次记忆,终身受用,优先级极高,必记!
鼠标三大按键的官方API名称(严格大小写,直接复制)
- 鼠标左键 →
leftButton - 鼠标右键 →
rightButton - 鼠标中键(滚轮按下) →
middleButton
按键的3个核心状态(所有鼠标按键通用,格式完全统一)
Mouse mouse = Mouse.current;
if(mouse == null) return;
// ✔️ 1. 按下瞬间 → wasPressedThisFrame :当前帧按下,只触发1次(点击、攻击、选中物体)
if(mouse.leftButton.wasPressedThisFrame)
{
Debug.Log("鼠标左键 按下瞬间 → 选中物体/攻击");
}
// ✔️ 2. 松开瞬间 → wasReleasedThisFrame :当前帧松开,只触发1次(松开选中、取消拖拽)
if(mouse.rightButton.wasReleasedThisFrame)
{
Debug.Log("鼠标右键 松开瞬间 → 取消右键瞄准");
}
// ✔️ 3. 持续按住 → isPressed :按键一直按住,每一帧触发(长按拖拽、长按施法)
if(mouse.middleButton.isPressed)
{
Debug.Log("鼠标中键 持续按住 → 拖动视角");
}
✅ 4. 鼠标【滚轮滚动】输入(向上/向下滚动)
功能说明
获取鼠标滚轮的滚动增量,返回 Vector2 类型,99%的场景只用y轴的值:
- 滚轮向上滚动 →
scroll.y为 正值 - 滚轮向下滚动 →
scroll.y为 负值 - 常用场景:缩放相机视角、调整UI大小、物品栏翻页、视角拉近拉远
调用代码
Mouse mouse = Mouse.current;
if(mouse == null) return;
// 获取鼠标滚轮滚动值
Vector2 mouseScroll = mouse.scroll.ReadValue();
if (mouseScroll.y > 0)
{
Debug.Log("鼠标滚轮向上滚动 → 视角拉近/放大");
}
else if (mouseScroll.y < 0)
{
Debug.Log("鼠标滚轮向下滚动 → 视角拉远/缩小");
}
✅ 5. 鼠标侧键(额外按键)输入(拓展)
很多鼠标有前进/后退侧键,Input System也完美支持,API调用格式和左键右键一致,直接用即可:
Mouse mouse = Mouse.current;
if(mouse == null) return;
// 鼠标前进键(侧键1)
if(mouse.forwardButton.wasPressedThisFrame) Debug.Log("鼠标前进键按下");
// 鼠标后退键(侧键2)
if(mouse.backButton.wasPressedThisFrame) Debug.Log("鼠标后退键按下");
✨ 纯代码方案 - 鼠标完整功能综合示例(可直接复制运行)
这个脚本整合了鼠标所有核心输入功能:位置、移动增量、左键/右键/中键、滚轮,是你开发中可以直接参考的完整模板,挂载到任意GameObject上即可运行测试:
using UnityEngine;
using UnityEngine.InputSystem; // 必须引入!
public class MouseInputTest : MonoBehaviour
{
[Header("鼠标灵敏度")]
public float mouseSensitivity = 0.1f;
[Header("相机缩放速度")]
public float scrollSpeed = 0.5f;
private Camera mainCamera;
void Start()
{
mainCamera = Camera.main;
}
void Update()
{
// 1. 获取鼠标实例 + 安全判断
Mouse mouse = Mouse.current;
if (mouse == null) return;
// 2. 获取鼠标当前屏幕位置
Vector2 mousePos = mouse.position.ReadValue();
Debug.Log("鼠标屏幕坐标:" + mousePos);
// 3. 获取鼠标移动增量 → 核心!实现视角旋转/物体拖动
Vector2 mouseDelta = mouse.delta.ReadValue();
// 用鼠标增量旋转物体(示例:绕Y轴左右转,绕X轴上下转)
transform.Rotate(-mouseDelta.y * mouseSensitivity, mouseDelta.x * mouseSensitivity, 0);
// 4. 鼠标左键/右键/中键 按键判断
if (mouse.leftButton.wasPressedThisFrame)
{
Debug.Log("左键按下 → 选中/攻击");
}
if (mouse.rightButton.isPressed)
{
Debug.Log("右键长按 → 瞄准/拖动");
}
if (mouse.middleButton.wasReleasedThisFrame)
{
Debug.Log("中键松开 → 取消视角拖动");
}
// 5. 鼠标滚轮缩放相机
Vector2 scroll = mouse.scroll.ReadValue();
mainCamera.fieldOfView -= scroll.y * scrollSpeed;
// 限制相机视野范围,防止缩放过度
mainCamera.fieldOfView = Mathf.Clamp(mainCamera.fieldOfView, 20f, 80f);
// 6. 鼠标侧键(拓展)
if (mouse.forwardButton.wasPressedThisFrame)
{
Debug.Log("鼠标前进键按下");
}
}
}
三、方案二:Input Action 可视化配置鼠标输入(进阶解耦,团队项目推荐)
这是Input System的标准设计理念,和键盘的可视化配置逻辑完全相同,核心优势是:将「鼠标输入逻辑」和「业务逻辑完全解耦」,无需修改代码,即可在可视化窗口中修改鼠标按键绑定、一键切换「鼠标+键盘+手柄」输入,支持多按键映射同一个行为,适合中大型项目/团队协作,也是官方推荐的进阶用法。
✅ 核心特点
- 鼠标的
位置、增量、滚轮、按键都可以在可视化窗口中配置为「Action」 - 脚本中只需要调用配置好的Action,无需关心具体绑定的是鼠标哪个按键/轴
- 配置一次,后续修改按键逻辑无需改代码,直接在配置窗口调整即可
✅ 完整实现步骤(4步搞定,无坑)
Step 1:创建Input Actions配置文件
在Project窗口右键 → Input Actions → 创建一个配置文件(比如命名为 MouseInputActions)
Step 2:可视化配置鼠标所有输入(核心!图文步骤)
双击创建好的MouseInputActions,打开配置窗口,按以下步骤配置,所有鼠标输入都在这里配置完成:
- 左侧点击
+→ 新建 Action Map,命名为MouseControl(代表鼠标的所有输入行为) - 选中
MouseControl,右侧点击+,根据需求创建Action(输入行为),并设置对应的「类型」和「绑定」,鼠标必配的5个Action如下(复制即可):- ✔️ MousePosition(鼠标位置):类型选「Value」,控制类型选「Vector2」→ 点击+绑定 → 选择
Mouse→Position - ✔️ MouseDelta(鼠标增量):类型选「Value」,控制类型选「Vector2」→ 绑定 →
Mouse→Delta - ✔️ MouseScroll(鼠标滚轮):类型选「Value」,控制类型选「Vector2」→ 绑定 →
Mouse→Scroll - ✔️ MouseLeftClick(鼠标左键):类型选「Button」→ 绑定 →
Mouse→Left Button - ✔️ MouseRightClick(鼠标右键):类型选「Button」→ 绑定 →
Mouse→Right Button
- ✔️ MousePosition(鼠标位置):类型选「Value」,控制类型选「Vector2」→ 点击+绑定 → 选择
- 配置完成后,Ctrl+S保存配置窗口,关闭即可。
Step 3:脚本中绑定并使用配置好的鼠标Action
配置完成后,脚本中的调用逻辑极其简单,和键盘的Action调用一致,核心只有3步:启用Action、读取值/判断状态、销毁时禁用Action,防止内存泄漏。
✨ 完整脚本示例(可直接复制)
using UnityEngine;
using UnityEngine.InputSystem; // 必须引入!
public class MouseActionTest : MonoBehaviour
{
// 拖拽步骤1创建的 MouseInputActions 配置文件到这个字段
public MouseInputActions mouseInputActions;
[Header("鼠标灵敏度")]
public float mouseSensitivity = 0.1f;
[Header("滚轮缩放速度")]
public float scrollSpeed = 0.5f;
private Camera mainCamera;
private void Awake()
{
mainCamera = Camera.main;
// 必做:启用鼠标的Action Map,否则无法响应输入
mouseInputActions.MouseControl.Enable();
}
void Update()
{
// ========== 1. 读取鼠标位置 ==========
Vector2 mousePos = mouseInputActions.MouseControl.MousePosition.ReadValue<Vector2>();
// ========== 2. 读取鼠标移动增量 → 视角旋转 ==========
Vector2 mouseDelta = mouseInputActions.MouseControl.MouseDelta.ReadValue<Vector2>();
transform.Rotate(-mouseDelta.y * mouseSensitivity, mouseDelta.x * mouseSensitivity, 0);
// ========== 3. 读取鼠标滚轮 → 相机缩放 ==========
Vector2 scroll = mouseInputActions.MouseControl.MouseScroll.ReadValue<Vector2>();
mainCamera.fieldOfView -= scroll.y * scrollSpeed;
mainCamera.fieldOfView = Mathf.Clamp(mainCamera.fieldOfView, 20f, 80f);
// ========== 4. 判断鼠标左键/右键 按下状态 ==========
if (mouseInputActions.MouseControl.MouseLeftClick.WasPressedThisFrame())
{
Debug.Log("左键按下 → 选中物体");
}
if (mouseInputActions.MouseControl.MouseRightClick.IsPressed())
{
Debug.Log("右键长按 → 瞄准");
}
}
// 必做:销毁时禁用Action,防止内存泄漏
private void OnDestroy()
{
mouseInputActions.MouseControl.Disable();
}
}
Step 4:挂载脚本并赋值
将脚本挂载到场景中的任意物体上 → 在Inspector面板,把创建好的MouseInputActions配置文件拖拽到脚本的mouseInputActions字段 → 运行即可生效!
四、鼠标输入 高频实战需求实现(直接用!)
这里补充开发中最常用的鼠标相关需求的实现代码,都是基于上面的核心API,直接复制到项目中即可,解决你的实际开发问题:
✅ 需求1:鼠标拖拽物体(按住左键拖动3D/2D物体)
using UnityEngine;
using UnityEngine.InputSystem;
public class MouseDrag : MonoBehaviour
{
private Mouse mouse;
private bool isDragging = false;
private Vector3 offset; // 鼠标和物体的偏移量,防止拖动时瞬移
void Update()
{
mouse = Mouse.current;
if (mouse == null) return;
// 左键按下 → 开始拖拽,记录偏移量
if (mouse.leftButton.wasPressedThisFrame)
{
Ray ray = Camera.main.ScreenPointToRay(mouse.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit))
{
if (hit.collider.gameObject == gameObject)
{
isDragging = true;
offset = transform.position - hit.point;
}
}
}
// 左键松开 → 结束拖拽
if (mouse.leftButton.wasReleasedThisFrame)
{
isDragging = false;
}
// 持续拖拽 → 物体跟随鼠标移动
if (isDragging)
{
Ray ray = Camera.main.ScreenPointToRay(mouse.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit))
{
transform.position = hit.point + offset;
}
}
}
}
✅ 需求2:FPS游戏 鼠标控制相机视角旋转(经典需求)
using UnityEngine;
using UnityEngine.InputSystem;
public class FPSMouseLook : MonoBehaviour
{
public float mouseSensitivity = 2f;
public Transform playerBody; // 玩家物体Transform
private float xRotation = 0f;
private Mouse mouse;
void Update()
{
mouse = Mouse.current;
if (mouse == null) return;
Vector2 mouseDelta = mouse.delta.ReadValue() * mouseSensitivity * Time.deltaTime;
// 鼠标X轴 → 玩家左右旋转,鼠标Y轴 → 相机上下旋转
xRotation -= mouseDelta.y;
xRotation = Mathf.Clamp(xRotation, -90f, 90f); // 限制上下视角,防止仰头过度
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseDelta.x);
}
}
五、鼠标输入 避坑指南 & 常见问题(必看!解决99%报错)
❌ 问题1:Mouse.current 一直为null,鼠标输入无响应
✅ 解决:
- 确认已切换启用新输入系统(最常见原因):
Player → Active Input Handling = Input System Package - 脚本顶部忘记引入命名空间:必须加
using UnityEngine.InputSystem; - 运行的设备无鼠标(如手机),做空值判断即可避免报错。
❌ 问题2:鼠标移动增量delta 移动过快/过慢
✅ 解决:一定要乘以 Time.deltaTime,让鼠标移动速度和帧率无关,保证不同帧率下移动速度一致:
Vector2 mouseDelta = mouse.delta.ReadValue() * mouseSensitivity * Time.deltaTime;
❌ 问题3:鼠标滚轮滚动时效果不明显/太灵敏
✅ 解决:给滚轮值乘以缩放系数,并通过Mathf.Clamp限制范围,参考上面的综合示例。
❌ 问题4:Input Action配置后鼠标无响应
✅ 解决:
- 脚本中必须调用
.Enable()启用Action Map,否则配置的所有行为都不会生效 - 配置窗口中,Action的「类型」和「控制类型」配置错误(比如滚轮要选Vector2,左键要选Button)
- 保存配置后,重新拖拽配置文件到脚本字段。
❌ 问题5:鼠标位置position和预期不符
✅ 解决:记住鼠标位置是屏幕坐标系,原点在左下角,而UGUI的RectTransform是基于左上角的,如需转换为UI坐标,使用:
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, mousePos, camera, out Vector2 uiPos);
六、新旧输入系统 鼠标API 对比表(快速迁移必看)
如果你是从旧的Input系统迁移过来,这个对比表能让你无缝切换,瞬间对应上所有鼠标相关API,不用再查文档:
| 旧输入系统(Input) | 新输入系统(Input System) | 功能说明 |
|---|---|---|
Input.mousePosition |
Mouse.current.position.ReadValue() |
获取鼠标屏幕位置 |
Input.GetAxis("Mouse X") |
Mouse.current.delta.ReadValue().x |
鼠标X轴移动增量 |
Input.GetAxis("Mouse Y") |
Mouse.current.delta.ReadValue().y |
鼠标Y轴移动增量 |
Input.GetMouseButtonDown(0) |
Mouse.current.leftButton.wasPressedThisFrame |
鼠标左键按下瞬间 |
Input.GetMouseButton(1) |
Mouse.current.rightButton.isPressed |
鼠标右键持续按住 |
Input.GetMouseButtonUp(2) |
Mouse.current.middleButton.wasReleasedThisFrame |
鼠标中键松开瞬间 |
Input.mouseScrollDelta |
Mouse.current.scroll.ReadValue() |
鼠标滚轮滚动值 |
✅ 总结(两种鼠标方案怎么选?)
和键盘输入的选择逻辑完全一致,按项目需求选即可,无优劣之分,只有合适与否:
- 纯代码方案(
Mouse.current) → 90%场景首选:无配置、代码简洁、上手快、能实现所有鼠标功能,适合独立开发、小型项目、快速原型验证,学习成本极低,是个人开发的最优解。 - Input Action可视化配置 → 进阶首选:输入与业务逻辑解耦,支持多设备无缝切换(鼠标→手柄),修改按键无需改代码,适合中大型项目、团队协作,稍微学一点配置成本,后期维护收益巨大。
鼠标的核心输入逻辑其实就5个:位置、增量、按键、滚轮、侧键,掌握这5个核心API,就能搞定所有鼠标相关的开发需求啦!