diff --git a/getting_started/scripting/gdscript/gdscript_basics.rst b/getting_started/scripting/gdscript/gdscript_basics.rst index 1f6a5a699..d32c59824 100644 --- a/getting_started/scripting/gdscript/gdscript_basics.rst +++ b/getting_started/scripting/gdscript/gdscript_basics.rst @@ -1464,62 +1464,104 @@ freed. Signals ~~~~~~~ -It is often desired to send a notification that something happened in an -instance. GDScript supports creation of built-in Godot signals. -Declaring a signal in GDScript is easy using the `signal` keyword. +Signals are a way to send notification messages from an object that +other objects can listen to in a generic way. Create custom signals for +a class using the ``signal`` keyword. :: - # No arguments. - signal your_signal_name - # With arguments. - signal your_signal_name_with_args(a, b) + # Signal with no arguments + signal your_signal_name -These signals can be connected in the editor or from code like regular signals. -Take the instance of a class where the signal was -declared and connect it to the method of another instance: + # Signal with two arguments + signal your_signal_name_with_args(a, b) + +These signals may be connected to methods in the same manner as you connect +built-in signals of nodes such as :ref:`class_Button` or :ref:`class_RigidBody`. + +Here's an example that creates a custom signal in one script and connects +the custom signal to a method in a separate script, using the +:ref:`Object.connect() ` method: :: - func _callback_no_args(): - print("Got callback!") + # your_notifier.gd - func _callback_args(a,b): - print("Got callback with args! a: ", a, " and b: ", b) + signal data_found - func _at_some_func(): - instance.connect("your_signal_name", self, "_callback_no_args") - instance.connect("your_signal_name_with_args", self, "_callback_args") - -It is also possible to bind arguments to a signal that lacks them with -your custom values: + var your_data = 42 :: - func _at_some_func(): - instance.connect("your_signal_name", self, "_callback_args", [22, "hello"]) + # your_handler.gd -This is useful when a signal from many objects is connected to a -single callback and the sender must be identified: + func your_handler(): + print("Your handler was called!") :: - func _button_pressed(which): - print("Button was pressed: ", which.get_name()) + # your_game.gd - func _ready(): - for b in get_node("buttons").get_children(): - b.connect("pressed", self, "_button_pressed",[b]) + func _ready(): + var notifier = your_notifier.new() + var handler = your_handler.new() -Finally, emitting a custom signal is done by using the -Object.emit_signal method: + notifier.connect("data_found", handler, "your_handler") + +GDScript can bind arguments to connections between a signal and a method. +When the signal is emitted, calling the connected method, the bound argument is +given to the method. These bound arguments are specific to the connection +rather than the signal or the method, meaning that each connection has +unique bindings. + +Here is an example that creates a connection between a button's ``pressed`` signal and +a method, binding the button instance to the connection. The handler uses the +bound argument to print which button instance was pressed. + +:: + + func pressed_handler(which): + print("A button was pressed! Button's name was:", which.get_name()) + + func _ready(): + for button in get_node("buttons").get_children() + # Connect the button's 'pressed' signal to our 'pressed_handler' method + # Bind the button to the connection so we know which button was pressed + button.connect("pressed", self, "pressed_handler", [button]) + +Signals are generated by the :ref:`Object.emit_signal() ` +method which broadcasts the signal and arguments. + +Extending a previous example to use all the features of GDScript signals: :: - func _at_some_func(): - emit_signal("your_signal_name") - emit_signal("your_signal_name_with_args", 55, 128) - some_instance.emit_signal("some_signal") + # your_notifier.gd + + signal data_found(data) + + var your_data = 42 + + func _process(delta): + if delta == your_data: + emit_signal("data_found", data) + +:: + + # your_handler.gd + + func your_handler(data, obj): + print("Your handler was called from: ", obj.get_name(), with data: ", data) + +:: + + # your_game.gd + + func _ready(): + var notifier = your_notifier.new() + var handler = your_handler.new() + + notifier.connect("data_found", handler, "your_handler", [notifier]) Coroutines with yield ~~~~~~~~~~~~~~~~~~~~~