• Godot Help
  • Need some help understanding signals in Godot 4.1

Hello, I'm a very new user and on day 2 of learning Game Dev, please bear with me, could someone assist me with connecting some signals from a UI Scene to my Player?

This is my Level Up Screen code with a button_pressed signal.

extends Control

signal increase_speed

@onready var player = get_node("/root/Game/Player")
@onready var lus = get_node("/root/Game/UILayer/LevelUpScreen")

func _on_levelup_button_pressed():
	player.emit_signal("increase_speed", 50)
	lus.visible = false

Now I read the page on Godot 4 docs about connecting signals through code, but I genuinely don't understand it and I've been slowly killing my braincells for the past 2 hours on this and various other issues, how is y'all night going?

What I got in /Root/Game/Player

func _ready():
	var level_up_screen = get_node("/root/Game/UILayer/LevelUpScreen")
	level_up_screen.increase_speed.connect(_on_increase_speed)

func _on_increase_speed(value):
	speed += value

I will come back to this tomorrow with a fresh mindset, but would genuinely appreciate any help that you can provide.

    Marttern You've almost got it right. A signal is sent from the node that has it to any code connected to it. It is Godot's direct implementation of the observer pattern in computer programming. The node sending the signal doesn't need to know anything about or have a reference to where the signal is being received. It just sends the signal. It's up to other classes to connect to that signal so that when it's sent, they receive it. It's the opposite direction from how functions normally work.

    Normally, since your button has a reference to player, you could just write player._on_increase_speed(50) and it would do that. With signals, instead you call increase_speed.emit(50). You don't need a reference to player, because your player already is connected to and ready to receive the increase_speed signal.

    HOWEVER...

    Not every situation is the correct situation for signals. A good general rule is that your player character should never need to know about or talk to the UI. In this situation, it's probably better for the player to not have any level_up_screen variable at all, and instead for your level up button to directly call that function on your player. You don't want your player character code to depend on UI code, because you wind up with a mess that way.

      An example of a good place to use a signal: Say your character has a health value, and in the UI there is a health bar. Because we don't want the player to need to know about that health bar, instead we have the player emit a signal health_changed(old_val, value) and the health bar will connect to that signal and update appropriately when the player gains or loses health.

      award Sorry for my late response and thank you for the help. I managed to solve it, it really was so, so close. Appreciate the helpful link as well! 🙂