VirtualJoystick 在 Godot 4.7:终于有原生触摸屏摇杆
Source: Dev.to
Source: …
概览
直到最近,在 Godot 中如果想在手机上使用虚拟摇杆,你只能有两种选择:
- 安装插件
- 自行实现
这两种方式的效果相同:需要处理多点触控的边缘情况(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_flags、theme_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 类似,但摇杆会在超出原始边界框后继续跟随手指。松开时摇杆会弹回。
在编辑器中的使用
-
节点结构
- 将
VirtualJoystick设为 CanvasLayer 的子节点,以防它随世界摄像机滚动。
- 将
-
动作映射
- 将方向映射到 Input‑Actions(例如
move_left、move_right、move_up、move_down)。
- 将方向映射到 Input‑Actions(例如
代码示例
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_left、move_right、move_up和move_down填入 Action‑Properties。 - 节点会自动以 0.0 到 1.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阶段
- 预计在大约两个月后发布稳定版
-
给开发者的建议:
如果你正在开发移动游戏,提前进行跳转以在发布前测试摇杆是值得的。
小而具体。