在 Unity 中,对鼠标的控制主要涉及鼠标可见性、锁定状态、位置控制以及模拟鼠标输入(如点击、滚轮)等。以下是具体实现方法,涵盖核心场景:

1.控制鼠标的可见性与锁定状态

Unity 内置的Cursor类提供了控制鼠标基本状态的 API,无需额外系统调用,适用于大多数场景。

1.1控制鼠标可见性

通过Cursor.visible属性控制鼠标是否在屏幕上显示:

// 隐藏鼠标
Cursor.visible = false;

// 显示鼠标
Cursor.visible = true;

1.2控制鼠标锁定状态

通过Cursor.lockState属性控制鼠标是否锁定到屏幕中心(常用于第一人称视角游戏,避免鼠标移出窗口):

CursorLockMode的可选值:

  • None:鼠标自由移动,可移出窗口;

  • Locked:鼠标锁定在屏幕中心,移动时仅产生输入事件(如Input.GetAxis("Mouse X")),不会实际移动位置;

  • Confined:鼠标限制在窗口内,可移动但无法移出。

using UnityEngine;

public class MouseControl : MonoBehaviour
{
    void Update()
    {
        // 按ESC键切换锁定状态
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            // 切换锁定状态:锁定 ↔ 解锁
            Cursor.lockState = Cursor.lockState == CursorLockMode.Locked 
                ? CursorLockMode.None : CursorLockMode.Locked;
            
            // 锁定时隐藏鼠标,解锁时显示
            Cursor.visible = Cursor.lockState != CursorLockMode.Locked;
        }
    }
}

2.控制鼠标位置

Unity 的Input.mousePosition是只读属性,无法直接设置鼠标位置。若需主动移动鼠标到指定屏幕坐标,需调用操作系统级 API(如 Windows 的User32.dll),通过平台调用(P/Invoke)实现。

注意

  • 此方法依赖 Windows 系统的User32.dll,仅在 Windows 平台有效;

  • Mac/Linux 需使用对应平台的系统 API(如 Mac 的CGWarpMouseCursorPosition);

  • 屏幕坐标以左上角为原点,与 Unity 的Screen类坐标体系一致。

Windows平台控制鼠标位置示例:

using UnityEngine;
using System.Runtime.InteropServices; // 用于DllImport

public class MousePositionControl : MonoBehaviour
{
    // 导入Windows系统的鼠标位置设置函数
    [DllImport("User32.dll")]
    private static extern bool SetCursorPos(int x, int y);

    // 将鼠标移动到屏幕指定位置(屏幕坐标:原点在左上角,x向右递增,y向下递增)
    public void MoveMouseTo(int screenX, int screenY)
    {
        // 限制坐标在屏幕范围内(可选)
        screenX = Mathf.Clamp(screenX, 0, Screen.width);
        screenY = Mathf.Clamp(screenY, 0, Screen.height);
        
        SetCursorPos(screenX, screenY);
    }

    // 示例:移动到屏幕中心
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            int centerX = Screen.width / 2;
            int centerY = Screen.height / 2;
            MoveMouseTo(centerX, centerY);
        }
    }
}

3.模拟鼠标输入

若需模拟鼠标点击、滚轮滚动等操作(如自动化测试、脚本触发交互),同样需调用系统级 API(如 Windows 的mouse_event)。

在 Windows 平台模拟鼠标左键点击示例:

using UnityEngine;
using System.Runtime.InteropServices;

public class SimulateMouseInput : MonoBehaviour
{
    // 导入Windows鼠标事件函数
    [DllImport("User32.dll")]
    private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);

    // 鼠标事件常量(Windows定义)
    private const uint MOUSEEVENTF_LEFTDOWN = 0x02; // 左键按下
    private const uint MOUSEEVENTF_LEFTUP = 0x04;   // 左键抬起
    private const uint MOUSEEVENTF_RIGHTDOWN = 0x08; // 右键按下
    private const uint MOUSEEVENTF_RIGHTUP = 0x10;  // 右键抬起
    private const uint MOUSEEVENTF_WHEEL = 0x0800;  // 滚轮事件

    // 模拟一次左键点击
    public void SimulateLeftClick()
    {
        // 按下左键
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        // 抬起左键(间隔一小段时间更真实)
        Invoke(nameof(LeftClickUp), 0.1f);
    }

    private void LeftClickUp()
    {
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    }

    // 模拟滚轮滚动(delta为正数向上滚,负数向下滚)
    public void SimulateMouseWheel(int delta)
    {
        mouse_event(MOUSEEVENTF_WHEEL, 0, 0, (uint)delta, 0);
    }

    // 测试:按T键模拟左键点击,按R键模拟滚轮上滚
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.T))
        {
            SimulateLeftClick();
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            SimulateMouseWheel(120); // 通常120为一个单位滚动量
        }
    }
}

4.注意事项

        平台兼容性:系统级 API(如User32.dll)是平台特定的,需针对 Windows/Mac/Linux 编写不同实现(可通过#if UNITY_STANDALONE_WIN等条件编译区分)。

        权限问题:部分环境(如全屏应用、沙箱模式)可能限制程序对鼠标的控制,需确保程序有足够权限。

        移动平台:移动设备(手机 / 平板)无物理鼠标,上述方法仅适用于 PC 端;移动平台需通过触摸 API(如Input.touches)处理交互。

        性能与延迟:频繁调用系统 API 可能导致性能问题,建议控制调用频率(如通过InvokeRepeating或限制Update中的执行次数)。

Logo

这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!

更多推荐