Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Signal

Встроенный тип, представляющий сигнал Object.

Описание

Signal — это встроенный тип Variant, который представляет сигнал экземпляра Object. Как и все типы Variant, он может храниться в переменных и передаваться в функции. Сигналы позволяют всем подключенным Callable (и соответственно, их соответствующим объектам) прослушивать и реагировать на события, не ссылаясь напрямую друг на друга. Это сохраняет код гибким и простым в управлении. Вы можете проверить, имеет ли Object заданное имя сигнала, используя Object.has_signal().

В 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("Hit with weapon %s for %d damage." % [weapon_type, damage])

``Object.connect()`` или ``Signal.connect()``?

Как видно выше, рекомендуемый метод для подключения сигналов — не Object.connect(). В блоке кода ниже показаны четыре варианта подключения сигналов с использованием либо этого устаревшего метода, либо рекомендуемого connect(), а также с использованием либо неявного Callable, либо определенного вручную.

func _ready():
    var button = Button.new()
    # Вариант 1: Object.connect() с неявным вызовом для определенной функции.
    button.connect("button_down", _on_button_down)
    # Вариант 2: Object.connect() с созданным Callable, использующим целевое имя объекта и метода.
    button.connect("button_down", Callable(self, "_on_button_down"))
    # Вариант 3: Signal.connect() с неявным вызовом для определенной функции.
    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("Кнопка нажата!")

Хотя все варианты имеют одинаковый результат (BaseButton.button_down button будет подключен к _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("Hit by %s (level %d) with weapon %s for %d damage." % [hit_by, level, weapon_type, damage])

Примечание: В логическом контексте сигнал будет оцениваться как false, если он равен null (см. is_null()). В противном случае сигнал всегда будет оцениваться как true.

Примечание

Существуют заметные различия при использовании данного API с C#. Подробнее см. API различия C# и 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 Signal(object: Object, signal: StringName)

Создает объект Signal, ссылающийся на сигнал с именем signal в указанном object.


Описания метода

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

Соединяет этот сигнал с указанным callable. Дополнительно можно указать flags для настройки поведения соединения (см. константы ConnectFlags). Вы можете передать дополнительные аргументы в связанный callable, используя Callable.bind().

Сигнал может быть соединён с одним и тем же 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, " was pressed")

Примечание: Если объект callable освобождён, соединение будет потеряно.


void disconnect(callable: Callable) 🔗

Отключает этот сигнал от указанного Callable. Если соединение не существует, генерирует ошибку. Используйте is_connected(), чтобы убедиться, что соединение существует.


void emit(...) vararg const 🔗

Выдает этот сигнал. Все Callable, подключенные к этому сигналу, будут активированы. Этот метод поддерживает переменное количество аргументов, поэтому параметры можно передавать в виде списка, разделенного запятыми.


Array get_connections() const 🔗

Возвращает Array соединений для этого сигнала. Каждое соединение представлено как Dictionary, который содержит три записи:

  • signal — ссылка на этот сигнал;

  • callable — ссылка на подключенный Callable;

  • flags — комбинация ConnectFlags.


StringName get_name() const 🔗

Возвращает имя этого сигнала.


Object get_object() const 🔗

Возвращает объект, испускающий этот сигнал.


int get_object_id() const 🔗

Возвращает идентификатор объекта, испускающего этот сигнал (см. Object.get_instance_id()).


bool has_connections() const 🔗

Возвращает true, если к этому сигналу подключен какой-либо Callable.


bool is_connected(callable: Callable) const 🔗

Возвращает true, если указанный Callable подключен к этому сигналу.


bool is_null() const 🔗

Возвращает true, если этот Signal не имеет объекта и имя сигнала пустое. Эквивалентно signal == Signal().


Описания оператора

bool operator !=(right: Signal) 🔗

Возвращает true, если сигналы не имеют одного и того же объекта и имени.


bool operator ==(right: Signal) 🔗

Возвращает true, если оба сигнала имеют один и тот же объект и имя.