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("Button down!")

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() з неявним 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!")

Хоча всі варіанти дають однаковий результат (сигнал button BaseButton.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])

Примітка: У булевому контексті сигнал буде обчислюватися як false, якщо він нульовий (див. is_null()). В іншому випадку сигнал завжди обчислюватиметься як true.

Примітка

Існують значні відмінності при використанні цього API із С#. Більше інформації: ref:doc_c_sharp_differences.

Посібники

Конструктори

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)

Constructs a 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, "було натиснуто")

Примітка: Якщо об'єкт callable звільниться, з'єднання буде втрачено.


void disconnect(callable: Callable) 🔗

Відключення цього сигналу з вказаного Callable. Якщо підключення не існує, генерує помилку. Використовуйте method_connected, щоб переконатися, що підключення існує.


void emit(...) vararg const 🔗

Зніміть цей сигнал. Всі Callable, підключені до цього сигналу, будуть запущені. Цей метод підтримує змінну кількість аргументів, тому параметри можуть бути передані як окремий список коми.


Array get_connections() const 🔗

Повернутися до Array підключень до цього сигналу. Кожен з'єднання представлений як Dictionary, який містить три записи:

  • signal - посилання на цей сигнал;

  • Callable - посилання на підключений Callable;

  • flags - це поєднання об'єкту [enum. Роз'єм.


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 не має об’єкта, а назва сигналу порожня. Еквівалент singal == Singal().


Описи операторів

bool operator !=(right: Signal) 🔗

Повертає true, якщо сигнали не діляться тим самим об'єктом і назвою.


bool operator ==(right: Signal) 🔗

Повертає true, якщо обидва сигнали діляться тим самим об'єктом і назвою.