控制器、手柄和摇杆

SDL游戏控制器数据库 。 控制器支持Windows、macOS、Linux、Android、iOS和HTML5。 HOTAS 等更专业的设备测试较少,可能并不总是按照预期工作。如果你有机会使用这些设备,不要犹豫 在GitHub 上报告错误。 在本指南中,您将学会:

  • 如何编写你的输入逻辑以支持键盘和控制器输入.
  • 控制器的行为如何与键盘/鼠标输入不同.
  • 解决Godot中控制器的问题

    支持通用导出

    输入动作 ,然后引用指定的按键和控制器输入,而不是在你的脚本中硬编码按键或控制器按钮。 使用 InputEvent 页面上有详细解释。 注解 与键盘输入不同,支持鼠标和控制器输入的动作将需要不同的代码路径,例如在第一人称游戏中四处查看,因为这些必须被分开处理。

    我应该使用哪个输入单例方法?

    有3种方式可以以模拟感知的方式获得输入:
  • Input.get_vector() : GDScript C#
    1. # `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.# This handles deadzone in a correct way for most use cases.# The resulting deadzone will have a circular shape as it generally should.var velocity = Input.get_vector("move_left", "move_right", "move_forward", "move_back")# The line below is similar to `get_vector()`, except that it handles# the deadzone in a less optimal way. The resulting deadzone will have# a square-ish shape when it should ideally have a circular shape.var velocity = Vector2(Input.get_action_strength("move_right") - Input.get_action_strength("move_left"), Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")).clamped(1)
    1. // `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.// This handles deadzone in a correct way for most use cases.// The resulting deadzone will have a circular shape as it generally should.Vector2 velocity = Input.GetVector("move_left", "move_right", "move_forward", "move_back");// The line below is similar to `get_vector()`, except that it handles// the deadzone in a less optimal way. The resulting deadzone will have// a square-ish shape when it should ideally have a circular shape.Vector2 velocity = new Vector2(Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"), Input.GetActionStrength("move_back") - Input.GetActionStrength("move_forward")).Clamped(1);
  • Input.get_axis() : GDScript C#
    1. # `walk` will be a floating-point number between `-1.0` and `1.0`.var walk = Input.get_axis("move_left", "move_right")# The line above is a shorter form of:var walk = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    1. // `walk` will be a floating-point number between `-1.0` and `1.0`.float walk = Input.GetAxis("move_left", "move_right");// The line above is a shorter form of:float walk = Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left");
  • Input.get_action_strength() : GDScript C#
    1. # `strength` will be a floating-point number between `0.0` and `1.0`.var strength = Input.get_action_strength("accelerate")
    1. // `strength` will be a floating-point number between `0.0` and `1.0`.float strength = Input.GetActionStrength("accelerate");
    Input.is_action_pressed() : GDScript
    1. # `jumping` will be a boolean with a value of `true` or `false`.var jumping = Input.is_action_pressed("jump")
    C#
    1. // `jumping` will be a boolean with a value of `true` or `false`.bool jumping = Input.IsActionPressed("jump");
    Input.get_vector()Input.get_axis() 不可用。只有 Input.get_action_strength()Input.is_action_pressed() 在Godot 3.3中可用。

    键盘/鼠标和控制器输入之间的差异

    如果您习惯于处理键盘和鼠标输入,可能会对控制器处理特定情况的方式感到惊讶。

    盲区

    模拟输入的轴。模拟输入的好处是它们为动作提供了额外的灵活性。不像数字输入只能提供 0.01.0 的强度,模拟输入可以提供 0.01.0 之间的任何强度。缺点是没有死区系统,由于控制器的物理结构,模拟轴的强度永远不会等于 0.0。相反,它将徘徊在一个低值,如 0.062。这种现象被称为漂移,在旧的或有问题的控制器上会更加明显。 0.0。因为我们不希望我们的车在这种情况下自动转向,我们定义了一个“死区”值 0.2,它将忽略所有强度低于 0.2 的输入。一个理想的死区值是足够高的,可以忽略操纵杆漂移引起的输入,但又足够低,不会忽略玩家的实际输入。 0.2 ,但你可以在项目设置的输入映射选项卡中根据每个动作增加或减少它。对于 Input.get_vector() ,可以指定死区,否则它将从向量中的所有动作计算出平均死区值。

    “回声”事件

    不会产生固定间隔的重复输入事件(也被称为“回声”事件)。这是因为操作系统首先不会为控制器输入发送“回声”事件。 InputEvent 对象,并使用 Input.parse_input_event() 定期解析它们。这可以在 Timer 节点的帮助下完成。

    故障排除

    参见 控制器支持的已知问题列表。

    Godot 无法识别我的控制器。

    Gamepad Tester 网站来确认你的控制器被识别。

    我的控制器的按钮或轴映射不正确。

    SDL 游戏控制器数据库的错误的映射。你可以在链接的存储库中打开一个拉取请求,为下一个 Godot 版本提供一个更新的映射。 官方Joypads演示 中的映射向导。一旦你有了控制器可工作的映射,你可以在运行Godot之前通过定义 SDL_GAMECONTROLLERCONFIG 环境变量来测试它: Linux/macOS Windows (cmd) Windows (powershell)
    1. export SDL_GAMECONTROLLERCONFIG="your:mapping:here"./path/to/godot.x86_64
    1. set SDL_GAMECONTROLLERCONFIG=your:mapping:herepath\to\godot.exe
    1. $env:SDL_GAMECONTROLLERCONFIG="your:mapping:here"path\to\godot.exe
    Input.add_joy_mapping() 尽早在脚本的 _ready() 函数中添加它们。

    我的控制器在特定的平台上工作,但在另一个平台上却不能。

    macOS

    控制器目前只支持基于x86的Mac电脑。这意味着控制器不能在采用ARM处理器的Mac上工作,如苹果M1。

    Linux

    不支持 udev,除非在 SCons 命令行中传递 udev=yes。这使得控制器的热插拔支持在自编译的可执行文件中不可用。

    HTML5

    与 “本地” 平台相比,HTML5 控制器的支持通常不太可靠。各个浏览器对控制器的支持质量往往相差甚远。因此,如果玩家无法使用他们的控制器,你可能不得不指示他们使用不同的浏览器。 控制器的支持得到了很大的改善 。