I’m developing a simple game. When the player ends a level, it emits a signal that runs through a SignalBus.gd global autoloaded script. Other signals through the script are working well, just this one script (intermission.gd) refuses to connect to any signal. I am making the connections from within the code itself. Here is the code for SignalBus.gd and intermission.gd
Intermission.gd
extends Node2D
var counter := 0
var arrayCounter := 0
var length := 0
var toDisplay = {}
var score = "None"
const SCORE_START = "Score: "
const DEATHS_START = "Deaths: "
var deaths = "None"
func _ready() -> void:
#NOT WORKING
SignalBus.displayScore.connect(_on_display_score)
#_on_display_score(2, 2)
var deathString = DEATHS_START + str(deaths)
var scoreString = SCORE_START + score
toDisplay = [
{
"value": deathString,
"object": null
},
{
"value": scoreString,
"object": null
}
]
length = len(toDisplay[0]["value"])
for dict in toDisplay:
#add labels for everthing we need to display
var child = Label.new()
dict["object"] = child
$VBoxContainer.add_child(child)
$DisplayTimer.start()
#IS WORKING BUT NOT WHEN SIGNAL IS EMITTED
func _on_display_score(scoreIn: int, deathsIn: int):
print('here')
score = str(scoreIn)
deaths = str(deathsIn)
#makes the score and deaths show up nicely
func _on_display_timer_timeout() -> void:
counter += 1
if arrayCounter >= len(toDisplay):
return
if counter == length+1:
length = len(toDisplay[arrayCounter]["value"])
arrayCounter += 1
counter = 0
return
else:
var dict = toDisplay[arrayCounter]
dict["object"].text = dict["value"].substr(0, counter)
$DisplayTimer.start()
SignalBus.gd
extends Node
enum scoreTypes {
COIN = 1,
ENEMY = 1,
}
@warning_ignore_start("unused_signal")
signal dashStarted()
signal dashEnded()
signal dashesUpdated(dashCount: int)
signal dashPickedUp()
signal died()
signal isClimbing()
signal stoppedClimbing()
signal healthUpdated(currentHealth: int)
signal damage(value: int)
signal scoreChange(scoreChange: int)
signal levelEnd()
signal displayScore(score: int, deaths: int)
signal testSignal()
@warning_ignore_restore("unused_signal")
Are you by any chance queue_free() the node before it has a chance to print anything?
Can we see your emit code? Are you sure it is getting to that line?
Yes, I’m certain that the signal is being called, I’ve tested it with other signals. The player emits the signal, but the intermission.gd file refuses to connect to any signal
player.gd (i’ve omitted large parts cuz its a very large script
I haven’t used Godot 4, but there are two potential issues I see. One is that you use print("here") in multiple places. Try using something like print("here1") and print("here2"). The other thing is that signal levelEnd() has no arguments, but you pass an argument when you call SignalBus.levelEnd.emit(currentLevel).
Edit: try replacing signal levelEnd() with signal levelEnd(value: int) in SignalBus.gd.
Is Intermission.gd also an autoload? If so, it must come after SignalBus.gd in order to call SignalBus.displayScore.connect(_on_display_score) in _ready().
Try adding print_debug("here3") and print_debug("here4") before and after SignalBus.displayScore.connect(_on_display_score) in intermission’s _ready() function to see if it even gets there. And also, do you get any errors when you run the project?
Ok, there are a few possibilities left. First, make sure that score and deaths in player.gd are of type int. You could also try calling it with some explicit values, for instance:
Next, if that doesn’t work, try putting the same SignalBus.displayScore.emit(1, 2) in intermission right after you connect the signal. If that doesn’t work, then print the return value of the connect method:
var return_value = SignalBus.displayScore.connect(_on_display_score)
print(return_value)
So, either it has not been instantiated yet, or it has been removed. You may try to create a button that will call the levelEnd signal when you click it, to see if it works then.
I’m guessing its the former, because the intermission screen stays indefinitely until the player chooses to change it. So how would I go around ensuring that the signal is only sent after the screen has been instantiated?
I made both the changes, but it still has the same issue.
I think I’m gonna try another way, namely make the SignalBus store both variables and make intermission access them directly. Thank you for your help though