Menu

Godot Signals in GDScript: signal, connect() and emit()

Signals let a node announce that something happened without knowing who listens. Declare a signal, connect it to a function or a lambda, emit it with arguments, disconnect it, and use the engine's built-in signals.

This page includes runnable editors. Edit, run, and see output instantly.

A signal is a message a node sends when something happens: a button was pressed, the player died, a coin was collected. Other code connects to the signal and runs when it fires. The sender does not need to know who is listening:

Health: 10 -> 6
Health: 6 -> 0
Game over

Three steps:

  1. Declare the signal with signal, listing its arguments.
  2. Connect a function to it with signal_name.connect(function).
  3. Emit it with signal_name.emit(arguments). Every connected function runs, in the order they were connected.

Why Signals Matter

Signals keep nodes independent. A Player emits died, and the HUD, the music and the level each connect to it. None of them needs a reference to the others, and the Player scene works on its own. The Godot rule of thumb is "call down, signal up": a parent calls methods on its children, and a child sends signals to whoever is above it.

Built-in Signals

Every node type comes with signals. A few you will use early:

NodeSignalWhen
Buttonpressedthe button is clicked
Area2Dbody_entered(body)a physics body enters the area
Timertimeoutthe time is up
AnimationPlayeranimation_finished(name)an animation ends
any Nodetree_exitingthe node is about to leave the tree

Connect them in code the same way:

func _ready():
	$StartButton.pressed.connect(_on_start_pressed)
	$Hitbox.body_entered.connect(_on_hitbox_body_entered)

func _on_hitbox_body_entered(body: Node2D) -> void:
	if body.is_in_group("player"):
		body.take_damage(1)

Or connect them in the editor: select the node, open the Node dock, double click the signal and pick the script. Godot writes an empty handler such as _on_start_button_pressed() for you.

Connecting a Lambda

For a short reaction, connect a lambda instead of writing a method:

+5 coins
+1 coins
Total: 6

One-Shot Connections, Disconnecting and Checks

first time only
level started
level started
true
0

CONNECT_ONE_SHOT disconnects after the first emit. Connecting the same function twice is an error, so connect once, usually in _ready():

ERROR: Signal 'level_started' is already connected to given callable 'Node(main.gd)::_on_level_started' in that object.

Passing Extra Data with bind()

A signal's arguments are fixed by the emitter. To add your own, bind() them to the handler. This tells several buttons apart with one function:

func _ready():
	$Shop/BuySword.pressed.connect(_on_buy_pressed.bind("sword"))
	$Shop/BuyShield.pressed.connect(_on_buy_pressed.bind("shield"))

func _on_buy_pressed(item: String) -> void:
	print("Buying ", item)

Waiting for a Signal

await pauses a function until a signal fires, which reads like a script of events:

func open_chest() -> void:
	$AnimationPlayer.play("open")
	await $AnimationPlayer.animation_finished
	spawn_loot()

See await for coroutines and timers.

Godot 3 vs Godot 4

Godot 3Godot 4
connect("died", self, "_on_died")died.connect(_on_died)
emit_signal("died")died.emit() (the old form still works)
disconnect("died", self, "_on_died")died.disconnect(_on_died)
yield(self, "died")await died

Frequently Asked Questions

How do I connect a signal in Godot 4?

Call connect() on the signal with the function to run: $Button.pressed.connect(_on_button_pressed). Pass the method name without parentheses. You can also connect in the editor's Node dock, which writes the handler function for you.

How do I create a custom signal in GDScript?

Declare it at the top of the script: signal died or, with arguments, signal health_changed(old_value: int, new_value: int). Fire it with died.emit() or health_changed.emit(10, 4).

What replaced emit_signal and the string connect in Godot 4?

Godot 4 treats a signal as a value: died.emit() and died.connect(_on_died). The old emit_signal("died") still works, but the Godot 3 form connect("died", self, "_on_died") does not.

What does "Signal is already connected to given callable" mean?

You connected the same function to the same signal twice, often because connect() runs in a function that is called more than once. Connect once in _ready(), or check first with is_connected().

Coddy programming languages illustration

Learn to code with Coddy

Get started