信号是 Godot 内置的委派机制,允许一个游戏对象对另一个游戏对象的变化做出反应,而无需相互引用 使用信号可以限制耦合,并保持代码的灵活性

  • GDScript:类(节点)使用 PascalCase(大驼峰命名法),变量和函数使用 snake_case(蛇形命名法),常量使用 ALL_CAPS(全大写)(请参阅 GDScript 编写风格指南)。

1、场景设置

先新建一个场景

image.png

在场景面板中,选择 2D 场景,作为根节点

image.png

然后将 sprite_2d.tscn 文件拖动到 Node2D 上

image.png

再添加一个 Node2D 节点的子节点,Button 节点

image.png

创建完进行拖拽调整大小,再添加文本

image.png

2、在编辑器中连接信号

需要将按钮的“pressed”信号连接到 Sprite2D,通过调用一个新函数来控制其运动状态 选中按钮节点,在检查器旁边的节点 Tab 下找到可用的信号,里面有 pressed() 信号

image.png

选中后点击“连接”,这里会要选一个接收信号的方法,这里用默认,连接到 Sprite2D 节点上

image.png

点击“连接”,自动跳转到对应节点的脚本

image.png

点击左侧绿色箭头,可以看到函数的详情,包括信号接受者,信号来源等信息

image.png

Node 的另一个方法 is_processing() ,如果空闲处理处于活动状态,则返回 true。我们可以使用 not 关键字来反转该值。 另外,将 _process 改为自动运行

extends Sprite2D

var speed = 400
var angular_speed = PI

func _process(delta: float):
	
	rotation += angular_speed * delta
	var velocity = Vector2.UP.rotated(rotation) * speed
	position += velocity * delta


func _on_button_pressed() -> void:
	set_process(not is_processing())

screen006.gif

3、用代码连接信号

Godot 有一个 Timer 节点,用于实现技能冷却时间、武器重装等 为 Sprite2D 添加一个子节点

image.png

image.png

然后前往检查器,启用 Autostart

image.png

返回脚本,在 Node._ready() 内置函数中调用,节点完全实例化时,引擎自动调用该函数 为了获取对于当前节点的引用,使用 Node.get_node(),注意使用节点名

func _ready():
	var timer = get_node("Timer")

这里用到 Timer 节点的 timeout 信号,将这个信号关联函数

image.png

func _ready():
	var timer = get_node("Timer")
	timer.timeout.connect(_on_timer_timeout)

接下来,定义对应的函数 _on_timer_timeout()

func _on_timer_timeout():
	visible = not visible

此时对应的事件就是可见性变化

screen007.gif

4、完整脚本

extends Sprite2D

var speed = 400
var angular_speed = PI


func _ready():
	var timer = get_node("Timer")
	timer.timeout.connect(_on_timer_timeout)


func _process(delta):
	rotation += angular_speed * delta
	var velocity = Vector2.UP.rotated(rotation) * speed
	position += velocity * delta


func _on_button_pressed():
	set_process(not is_processing())


func _on_timer_timeout():
	visible = not visible

5、自定义信号

可以在脚本中定义自定义信号 生命值达到 0 时,定义一个”died”或“health_depleted”的信号

extends Node2D

signal health_depleted

var health = 10

信号一般表示过去的事件,通常使用过去时态命名

自定义信号和内置信号的工作方式相同,会显示在信号标签页中,也可以像其他信号一样进行连接

image.png

要通过代码发出信号,需要调用信号的 emit() 方法

func take_damage(amount):
	health -= amount
	if health <= 0:
		health_depleted.emit()

信号还可以选择声明一个或多个参数

extends Sprite2D

signal health_depleted(old_value, new_value)   # 指定参数

var health = 10

此时,调用时就需要多传入参数

func take_damage(amount):
	var old_health = health
	health -= amount
	health_changed.emit(old_health, health)