在 Godot 中锁定鼠标光标的方法

Table of Contents

在 Godot 中,有几种方法可以锁定鼠标光标,使其不超出游戏窗口。以下是使用 C# 的实现方法:

1. 使用 Input.set_mouse_mode() 方法

这是最常用的方法,Godot 提供了几种鼠标模式:

using Godot;

public class MouseLock : Node
{
    public override void _Ready()
    {
        // 锁定鼠标到窗口中心并隐藏
        Input.SetMouseMode(Input.MouseMode.Captured);
        
        // 其他可用模式:
        // Input.MouseMode.Visible - 正常可见模式(默认)
        // Input.MouseMode.Hidden - 隐藏但可以自由移动
        // Input.MouseMode.Captured - 锁定并隐藏(最适合FPS游戏)
        // Input.MouseMode.Confined - 限制在窗口内但可见
    }

    public override void _Input(InputEvent @event)
    {
        if (@event is InputEventKey keyEvent && keyEvent.Pressed)
        {
            if (keyEvent.Scancode == (int)KeyList.Escape)
            {
                // 按ESC键释放鼠标
                Input.SetMouseMode(Input.MouseMode.Visible);
            }
        }
    }
}

2. 使用 Confined 模式(仅限在窗口内移动)

using Godot;

public class MouseConfine : Node
{
    public override void _Ready()
    {
        // 限制鼠标在窗口内但保持可见
        Input.SetMouseMode(Input.MouseMode.Confined);
    }
}

3. 手动限制鼠标位置(不推荐)

如果需要更精细的控制,可以手动限制鼠标位置:

using Godot;

public class ManualMouseLock : Node
{
    private Viewport _viewport;

    public override void _Ready()
    {
        _viewport = GetViewport();
    }

    public override void _Process(float delta)
    {
        // 获取当前鼠标位置
        Vector2 mousePos = _viewport.GetMousePosition();
        
        // 获取视口大小
        Vector2 viewportSize = _viewport.Size;
        
        // 检查并修正鼠标位置
        if (mousePos.x <= 0)
            _viewport.WarpMouse(new Vector2(0, mousePos.y));
        else if (mousePos.x >= viewportSize.x)
            _viewport.WarpMouse(new Vector2(viewportSize.x, mousePos.y));
            
        if (mousePos.y <= 0)
            _viewport.WarpMouse(new Vector2(mousePos.x, 0));
        else if (mousePos.y >= viewportSize.y)
            _viewport.WarpMouse(new Vector2(mousePos.x, viewportSize.y));
    }
}

4. 结合使用的完整示例

using Godot;

public class MouseController : Node
{
    private bool _isMouseCaptured = false;

    public override void _Ready()
    {
        // 初始为捕获模式
        CaptureMouse();
    }

    public override void _Input(InputEvent @event)
    {
        if (@event is InputEventKey keyEvent && keyEvent.Pressed)
        {
            if (keyEvent.Scancode == (int)KeyList.Escape)
            {
                if (_isMouseCaptured)
                    ReleaseMouse();
                else
                    CaptureMouse();
            }
        }
    }

    private void CaptureMouse()
    {
        Input.SetMouseMode(Input.MouseMode.Captured);
        _isMouseCaptured = true;
    }

    private void ReleaseMouse()
    {
        Input.SetMouseMode(Input.MouseMode.Visible);
        _isMouseCaptured = false;
    }
}

注意事项

  1. Godot 4.0+ 的变化

    • 在 Godot 4.0 中,方法名改为 Input.MouseModeEnumInput.SetMouseMode()
    • Scancode 改为 Keycode
  2. 全屏模式

    • 在全屏模式下,鼠标会自动被限制在窗口内
  3. 多显示器环境

    • Confined 模式在多显示器环境下可能表现不同
  4. UI 交互

    • 当鼠标被捕获时,UI 元素可能无法正常交互,需要设计相应的处理逻辑

选择哪种方法取决于你的具体需求:

  • 第一人称游戏:使用 Captured 模式
  • RTS 或策略游戏:使用 Confined 模式
  • 需要精确控制:使用手动限制方法
kumakoko avatar
kumakoko
pure coder
comments powered by Disqus