Signal

代表 Object 中某个信号的内置类型。

描述

Signal 即信号,是一种内置的 Variant 类型,代表某个 Object 实例上的某个信号。与所有 Variant 一样,信号可以存储在变量中也可以传递给函数。所有连接到该信号的 Callable(以及扩展出的相应对象)都可以监听事件并对事件进行响应,无需相互直接引用。这样代码就更加灵活,便于管理。你可以使用 Object.has_signal() 来检查某个 Object 对象是否有特定名称的信号。

在 GDScript 中,信号可以使用 signal 关键字声明。在 C# 中,你可以对委托使用 [Signal] 特性。

signal attacked

# 还可以额外声明参数。
# 发出信号时必须传入这些参数。
signal item_dropped(item_name, amount)

连接信号是 Godot 中最常见的操作之一,API 为此提供了许多选项,详见下文。下面的代码展示的是推荐的做法。

func _ready():
    var button = Button.new()
    # 这里的 `button_down` 是 Signal Variant 类型。因此调用的是 Signal.connect() 方法而不是 Object.connect() 方法。
    # 对该 API 的概述见下面的讨论。
    button.button_down.connect(_on_button_down)

    # 假设存在 `Player` 类,定义了 `hit` 信号。
    var player = Player.new()
    # 我们再次使用 Signal.connect(),还使用了 Callable.bind() 方法,
    # 返回的是绑定了参数的新 Callable。
    player.hit.connect(_on_player_hit.bind("sword", 100))

func _on_button_down():
    print("按下了按钮!")

func _on_player_hit(weapon_type, damage):
    print("使用武器 %s 造成了 %d 点伤害。" % [weapon_type, damage])

``Object.connect()`` 还是 ``Signal.connect()``?

如上所示,并不推荐使用 Object.connect() 来连接信号。下面的代码中展示了连接信号的四种方法,包括这种传统的方法、推荐的 connect() 方法、使用隐式 Callable、以及手动定义。

func _ready():
    var button = Button.new()
    # 方法 1:Object.connect() 与方法的隐式 Callable。
    button.connect("button_down", _on_button_down)
    # 方法 2:Object.connect() 与使用目标对象和方法名构造的 Callable。
    button.connect("button_down", Callable(self, "_on_button_down"))
    # 方法 3:Signal.connect() 与方法的隐式 Callable。
    button.button_down.connect(_on_button_down)
    # 方法 4:Signal.connect() 与使用目标对象和方法名构造的 Callable。
    button.button_down.connect(Callable(self, "_on_button_down"))

func _on_button_down():
    print("Button down!")

所有方法的效果都是一样的(buttonBaseButton.button_down 信号连接到 _on_button_down),方法 3 的校验最为完善:如果 button_down Signal_on_button_down Callable 未定义就会输出编译错误。而方法 2 仅依赖字符串名称,只能在运行时校验名称:如果 "button_down" 不是信号或者 "_on_button_down" 不是 self 对象的方法,就会在运行时生成错误。使用方法 1、2、4 的主要原因是确实需要使用字符串(例如根据从配置文件读取的字符串通过程序来连接信号)。否则建议使用方法 3(而且速度最快)。

参数的绑定和传递:

绑定参数的语法需要使用 Callable.bind(),返回的是当前 Callable 绑定参数后的副本。

调用 emit()Object.emit_signal() 时也可以传递信号的参数。下面的例子展示的是信号参数和绑定参数之间的关系。

func _ready():
    # 假设存在 `Player` 类,定义了 `hit` 信号。
    var player = Player.new()
    # 使用 Callable.bind()。
    player.hit.connect(_on_player_hit.bind("sword", 100))

    # 发出信号时添加的参数先传递。
    player.hit.emit("Dark lord", 5)

# 发出信号时传入了 (`hit_by`, `level`) 两个参数,
# 连接信号时绑定了 (`weapon_type`, `damage`) 两个参数。
func _on_player_hit(hit_by, level, weapon_type, damage):
    print("受到来自 %s%d 级)的攻击,使用武器 %s 造成了 %d 点伤害。" % [hit_by, level, weapon_type, damage])

备注

通过 C# 使用该 API 时会有显著不同,详见 C# API 与 GDScript 的差异

教程

构造函数

Signal

Signal()

Signal

Signal(from: Signal)

Signal

Signal(object: Object, signal: StringName)

方法

int

connect(callable: Callable, flags: int = 0)

void

disconnect(callable: Callable)

void

emit(...) vararg const

Array

get_connections() const

StringName

get_name() const

Object

get_object() const

int

get_object_id() const

bool

has_connections() const

bool

is_connected(callable: Callable) const

bool

is_null() const

运算符

bool

operator !=(right: Signal)

bool

operator ==(right: Signal)


构造函数说明

Signal Signal() 🔗

构造空的 Signal,没有绑定对象和信号名称。


Signal Signal(from: Signal)

构造给定 Signal 的副本。


Signal Signal(object: Object, signal: StringName)

新建 Signal 对象,引用 object 对象中名为 signal 的信号。


方法说明

int connect(callable: Callable, flags: int = 0) 🔗

将信号连接到可调用体 callable。还可以添加 flags 对连接的行为进行配置(见 ConnectFlags 常量)。可以使用 Callable.bind() 为连接的 callable 提供额外的参数。

一个信号只能和同一个 Callable 连接一次。如果信号已连接,则会返回 @GlobalScope.ERR_INVALID_PARAMETER 并生成错误,除非信号是用 Object.CONNECT_REFERENCE_COUNTED 连接的。要防止这个问题,请先使用 is_connected() 检查已有连接。

for button in $Buttons.get_children():
    button.pressed.connect(_on_pressed.bind(button))

func _on_pressed(button):
    print(button.name, " 被按了一下")

注意:如果 callable 的对象被释放,连接会丢失。


void disconnect(callable: Callable) 🔗

将该信号与给定的 Callable 断开连接。如果该连接不存在,则会生成错误。请使用 is_connected() 来确保连接存在。


void emit(...) vararg const 🔗

发出该信号。与该信号相连的所有 Callable 都将被触发。此方法支持可变数量的参数,所以参数可以用逗号分隔列表的形式传递。


Array get_connections() const 🔗

返回该信号的连接 Array。连接用 Dictionary 表示,包含三个条目:

  • signal 是对此信号的引用。

  • callable 是对连接的 Callable 的引用。

  • flagsConnectFlags 的组合。


StringName get_name() const 🔗

返回该信号的名称。


Object get_object() const 🔗

返回发出该信号的对象。


int get_object_id() const 🔗

返回发出该信号的对象的 ID(见 Object.get_instance_id())。


bool has_connections() const 🔗

如果存在连接到该信号的 Callable,则返回 true


bool is_connected(callable: Callable) const 🔗

如果指定的 Callable 已连接到此信号,则返回 true


bool is_null() const 🔗

如果该 Signal 不存在对象且信号名为空,则返回 true。等价于 signal == Signal()


运算符说明

bool operator !=(right: Signal) 🔗

如果信号的对象或名称不同,则返回 true


bool operator ==(right: Signal) 🔗

如果信号的对象和名称相同,则返回 true