一、核心前提:鼠标的核心全局实例对象

和键盘的 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名称(严格大小写,直接复制)

  1. 鼠标左键 → leftButton
  2. 鼠标右键 → rightButton
  3. 鼠标中键(滚轮按下) → 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,打开配置窗口,按以下步骤配置,所有鼠标输入都在这里配置完成

  1. 左侧点击+ → 新建 Action Map,命名为MouseControl(代表鼠标的所有输入行为)
  2. 选中MouseControl,右侧点击+,根据需求创建Action(输入行为),并设置对应的「类型」和「绑定」,鼠标必配的5个Action如下(复制即可)
    • ✔️ MousePosition(鼠标位置):类型选「Value」,控制类型选「Vector2」→ 点击+绑定 → 选择MousePosition
    • ✔️ MouseDelta(鼠标增量):类型选「Value」,控制类型选「Vector2」→ 绑定 → MouseDelta
    • ✔️ MouseScroll(鼠标滚轮):类型选「Value」,控制类型选「Vector2」→ 绑定 → MouseScroll
    • ✔️ MouseLeftClick(鼠标左键):类型选「Button」→ 绑定 → MouseLeft Button
    • ✔️ MouseRightClick(鼠标右键):类型选「Button」→ 绑定 → MouseRight Button
  3. 配置完成后,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,鼠标输入无响应

✅ 解决:

  1. 确认已切换启用新输入系统(最常见原因):Player → Active Input Handling = Input System Package
  2. 脚本顶部忘记引入命名空间:必须加 using UnityEngine.InputSystem;
  3. 运行的设备无鼠标(如手机),做空值判断即可避免报错。

❌ 问题2:鼠标移动增量delta 移动过快/过慢

✅ 解决:一定要乘以 Time.deltaTime,让鼠标移动速度和帧率无关,保证不同帧率下移动速度一致:

Vector2 mouseDelta = mouse.delta.ReadValue() * mouseSensitivity * Time.deltaTime;

❌ 问题3:鼠标滚轮滚动时效果不明显/太灵敏

✅ 解决:给滚轮值乘以缩放系数,并通过Mathf.Clamp限制范围,参考上面的综合示例。

❌ 问题4:Input Action配置后鼠标无响应

✅ 解决:

  1. 脚本中必须调用 .Enable() 启用Action Map,否则配置的所有行为都不会生效
  2. 配置窗口中,Action的「类型」和「控制类型」配置错误(比如滚轮要选Vector2,左键要选Button)
  3. 保存配置后,重新拖拽配置文件到脚本字段。

❌ 问题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() 鼠标滚轮滚动值

✅ 总结(两种鼠标方案怎么选?)

和键盘输入的选择逻辑完全一致,按项目需求选即可,无优劣之分,只有合适与否

  1. 纯代码方案(Mouse.current90%场景首选:无配置、代码简洁、上手快、能实现所有鼠标功能,适合独立开发、小型项目、快速原型验证,学习成本极低,是个人开发的最优解。
  2. Input Action可视化配置进阶首选:输入与业务逻辑解耦,支持多设备无缝切换(鼠标→手柄),修改按键无需改代码,适合中大型项目、团队协作,稍微学一点配置成本,后期维护收益巨大。

鼠标的核心输入逻辑其实就5个:位置、增量、按键、滚轮、侧键,掌握这5个核心API,就能搞定所有鼠标相关的开发需求啦!