关于 godot-gdscript
面向 Godot 4.7 开发者的 GDScript 2.0 编写与排错指南,适用于新写脚本或迁移旧项目。重点介绍静态类型、节点生命周期、信号及 3.x 到 4.x 的语法变化。
主要功能
- 01使用静态类型声明变量与函数
- 02按用途使用节点生命周期回调
- 03通过 @onready 获取节点引用
- 04用 @export 暴露可编辑参数
- 05使用信号与 await 处理事件
适用场景
- 01编写或修复 .gd 脚本
- 02将 Godot 3.x 脚本迁移至 4.x
- 03排查信号连接和类型错误
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill godot-gdscript安装后在 Claude Code 中输入/godot-gdscript确认已加载。
附带文件references/annotations-and-typing.md
详细介绍
Godot GDScript(4.x)
编写正确的静态类型 GDScript,并按照引擎预期的方式使用节点生命周期和信号 系统。目标版本为 Godot 4.7(GDScript 2.0)。
适用场景
- 编写或修复
.gd文件:声明变量、函数和类,使用@export/@onready、连接信号,或等待协程/信号。 - 将 Godot 3.x 脚本移植到 4.x,且脚本不再能解析时。
**不适用场景:**场景/节点结构和实例化问题 →
godot-nodes-scenes;信号架构/解耦模式 →
godot-signals-groups;改用 C# 而不是 GDScript → godot-csharp。
核心工作流
- 尽可能为所有内容指定类型。 GDScript 2.0 支持静态类型
(
var hp: int = 10、func add(a: int, b: int) -> int:)。类型可在解析时捕获错误, 并提升 VM 的运行速度。使用:=推断类型。 - **按用途使用生命周期回调:**节点及其子节点进入场景树时调用一次
_ready(); 每个渲染帧调用_process(delta);在固定的物理帧上调用_physics_process(delta)(用于移动/物理逻辑)。 - 使用
@onready获取节点引用,不要在_init()中获取——节点进入场景树前, 子节点尚不存在。 - 使用
@export暴露可调参数,以便设计师在检查器中编辑。 - 在适合的情况下,用信号 +
await响应事件,而不是轮询。 - **运行项目并查看错误。**调试器面板会打印带行号的类型错误; 优先修复第一个错误(后续错误通常是连带产生的)。
模式
1. 包含生命周期、@export 和 @onready 的类型化脚本
extends Node2D
class_name Spinner # registers a global type usable in other scripts
@export var speed: float = 90.0 # editable in the Inspector (degrees/sec)
@export_range(0, 10, 0.5) var wobble := 2.0
@onready var sprite: Sprite2D = $Sprite2D # resolved when the node enters the tree
func _ready() -> void:
# Runs once, after children are ready. Safe to touch $Sprite2D here.
sprite.modulate = Color.AQUA
func _process(delta: float) -> void:
# delta is seconds since last frame; multiply rates by it for FPS independence.
rotation_degrees += speed * delta
2. 信号:声明、发出、连接(4.x Callable 语法)
extends Node
signal health_changed(current: int, maximum: int) # typed signal params
var health := 100
func take_damage(amount: int) -> void:
health = max(health - amount, 0)
health_changed.emit(health, 100) # 4.x: emit as a method on the signal
func _ready() -> void:
# 4.x: connect with a Callable, not a string method name.
health_changed.connect(_on_health_changed)
func _on_health_changed(current: int, maximum: int) -> void:
print("HP: %d/%d" % [current, maximum])
3. await——暂停执行,直到计时器或信号触发(替代 3.x 的 yield)
func flash_then_continue() -> void:
modulate = Color.RED
await get_tree().create_timer(0.2).timeout # resume after 0.2s
modulate = Color.WHITE
# await any signal: var result = await some_node.some_signal
4. Lambda、类型化数组和安全访问
var enemies: Array[Node] = [] # typed array
func cull_dead() -> void:
enemies = enemies.filter(func(e): return e.is_inside_tree())
func get_first_name(d: Dictionary) -> String:
return d.get("name", "unknown") # default avoids missing-key errors
易踩问题
- 3.x → 4.x 的信号 API 有所变化。
emit_signal("x")仍可使用,但建议改用x.emit(...);connect("x", self, "_on_x")已移除——请改用带 Callable 的x.connect(_on_x)。yield(obj, "sig")现在应写为await obj.sig。 export var现在写作@export var(注解)。onready→@onready、tool→@tool,以及remote/masterRPC 关键字也应改为@rpc(...)注解。- 在
_init()中使用@onready和$NodePath会失败——节点尚未进入场景树。 请在_ready()中初始化节点引用,或使用@onready。 - 整数除法会截断。
5 / 2 == 2。请使用5.0 / 2,或转换为float。 - **
_process与_physics_process。**在_physics_process(delta)中调用move_and_slide()并编写物理逻辑;在_process中使用会导致运动与帧率相关。 class_name在整个项目中必须唯一,并且要在其他脚本中使用该类型名称或将其作为检查器类型时必须声明。
参考资料
- 如需完整的注解列表、高级类型用法和风格约定,请阅读
references/annotations-and-typing.md。
相关技能
godot-nodes-scenes— 场景树、实例化和自动加载。godot-signals-groups— 使用信号和组实现事件驱动架构。godot-resources— 使用自定义Resource类型实现数据驱动设计。godot-csharp— 使用 C#/.NET 实现相同的引擎概念。
评论
支持 Markdown