VirtualJoystick 在 Godot 4.7:终于有原生触摸屏摇杆

发布: (2026年5月2日 GMT+8 01:41)
7 分钟阅读
原文: Dev.to

Source: Dev.to

Source:

概览

直到最近,在 Godot 中如果想在手机上使用虚拟摇杆,你只能有两种选择:

  1. 安装插件
  2. 自行实现

这两种方式的效果相同:需要处理多点触控的边缘情况(Edge‑Cases)、手动的分辨率缩放(Resolution‑Scaling),最终得到一个约 200 行的类,每次引擎更新后都必须重新测试。

随着 Godot 4.7 beta 1(2026 年 4 月 24 日)发布,这一切都结束了。全新的 VirtualJoystick‑节点 已经成为引擎的一部分,提供三种模式,并且能够干净地集成到 Action‑Mapping‑系统 中。

为什么 TouchScreenButton 不足

Godot 已经有节点 TouchScreenButton 用于移动端控制。问题:

  • 它继承自 Node2D → 不能使用 Anchors
  • 因此无法相对于屏幕边缘定位。

审稿人 Calinou 在 Pull‑Request 中简短地写道:

“TouchScreenButton inherits from Node2D, which means it can’t make use of anchors.”

对于一个需要在所有显示尺寸上都能正常显示的元素来说,这是一个致命问题。

原始提案:
“When creating a mobile game, you often need a virtual joystick so the player can move around. However, this is nontrivial to implement correctly.”

结果:每个移动端的 Godot 项目要么依赖于资产库,要么自行编写摇杆类,而在许多情况下这些实现会错误处理边缘情况(多点触控跟踪、分辨率缩放、离开摇杆时的行为)。

VirtualJoystick – 原生解决方案

  • 继承自 Control → 锚点、size_flagstheme_override以及所有 Control 节点能够的功能都可用。
  • 程序化渲染(非位图)→ 在1080 p、4 K 平板等设备上保持锐利。
  • 主题属性 可调整外观(背景、按钮、颜色)。

信号(可在编辑器中绑定)

Signal描述
tapped松开时,摇杆未被移动
released手指离开屏幕
flicked摇杆从死区移动出来
flick_canceled已启动的快速滑动被取消并回弹

提示: tapped 信号使得摇杆可以作为动作按钮使用,当玩家仅短暂点击时。

三种模式

模式摇杆位置超出边界的移动常见使用场景
JOYSTICK_FIXED未改变(放置位置不变)经典 UI,固定 UI 的动作游戏
JOYSTICK_DYNAMIC触摸时弹出Joypad 游戏的移动端移植(更舒适)
JOYSTICK_FOLLOWING触摸时弹出,手指超出边界框后仍跟随双摇杆射击游戏,大屏幕

模式简要说明

  • JOYSTICK_FIXED – 摇杆保持在原位。当玩家未直接点击时,不会有任何反应。
  • JOYSTICK_DYNAMIC – 当玩家点击控件的激活区域时,按钮会弹到触摸位置。摇杆本身不再移动。
  • JOYSTICK_FOLLOWING – 与 DYNAMIC 类似,但摇杆会在超出原始边界框后继续跟随手指。松开时摇杆会弹回。

在编辑器中的使用

  1. 节点结构

    • VirtualJoystick 设为 CanvasLayer 的子节点,以防它随世界摄像机滚动。
  2. 动作映射

    • 将方向映射到 Input‑Actions(例如 move_leftmove_rightmove_upmove_down)。

代码示例

extends CharacterBody2D

@export var move_speed: float = 200.0

func _physics_process(_delta: float) -> void:
    var input_dir := Input.get_vector(
        "move_left",
        "move_right",
        "move_up",
        "move_down"
    )
    velocity = input_dir * move_speed
    move_and_slide()
  • VirtualJoystick 检查器中,将 move_leftmove_rightmove_upmove_down 填入 Action‑Properties
  • 节点会自动以 0.01.0 之间的强度触发这些动作。
  • 你的游戏代码无需了解摇杆的细节——平台无关,同样适用于手柄或键盘。

有意省略的内容

功能原因
Deadzone‑Konfiguration im Knoten死区属于 Input‑Action(Project Settings → Input Map)。双重配置容易出错。
Clamp‑Zone(摇杆被“卡住”的区域)在原始提案中是可选的,但在最终版本中被移除。

这些决定是 设计决策,而不是缺陷。如果你需要它们,可以继承该节点并自行添加——在标准工作流中并不需要这样做。

为什么这很重要

  • 许多开发者已经拥有自己的 VirtualJoystick.gd 类,或使用资产库中的插件(根据边缘情况覆盖,代码量在 100 – 300 行之间)。
  • 资产库目前列出了大约 ~20 个竞争的摇杆插件。

原生节点消除了

  • 需要选择和维护插件的必要性。
  • 插件在引擎更新后可能不再工作 的风险。

该节点由引擎团队维护,下一次更新时不会消失。

结论

如果你的游戏面向触摸屏,VirtualJoystick 是推荐的解决方案。它节省时间,减少错误,并且具备未来保障。

2024 年,德国移动游戏实现了 30 亿 € 的创纪录收入——这强烈表明触摸优化仍然至关重要。

市场概览与德国移动游戏发展

  • 收入增长:
    “欧元,较2019年增长63%。” 智能手机多年来一直是国内使用最广的游戏平台。

  • 许多独立工作室的开发策略:
    混合模式——先发布桌面版,随后移植到移动端。在这个移动移植步骤中,触摸屏操作迄今为一天的手工制作

  • 版本 4.7的当前状态:

    • 处于Beta阶段
    • 预计在大约两个月后发布稳定版
  • 给开发者的建议:
    如果你正在开发移动游戏,提前进行跳转以在发布前测试摇杆是值得的。
    小而具体。

0 浏览
Back to Blog

相关文章

阅读更多 »

Pygame Snake,第4部分

介绍 在第1、2、3部分中,我们组装了除实际游戏逻辑之外的所有内容。现在我们将添加 snake 机制。将单个 dot 替换为 snake li...