Question
Hi, I’m having issues implementing signals, I have an example script below:
main.gd (Global name Main)
signal reset_animation
func _ready() → void:
-player_killed()
func player_killed():
-reset_animation.emit()
-print(‘good’)
moving_platform.gd
The moving_platforms is a group of platforms that all have this script attached to it, so the procedure of adding them to the group doesn’t have any issues.
I’m running this script on a part in the game right now, ‘good’ is printing but I can’t get it to print ‘hi’. Am I missing a step?
The autoload is ready before the moving platform is ready.
How would you suggest to fix this,? Sorry and thanks.
calling player_killed()
on ready seems pretty wild. You would wait a frame for everything else to load and get connected to main’s signal before emitting
# main.gd
func _ready() -> void:
await get_tree().process_frame # wait one frame
player_killed()
You can paste scripts with three ticks. I did the above like so:
```gd
# main.gd
func _ready() -> void:
await get_tree().process_frame # wait one frame
player_killed()
```
Hello,
Sorry I wasn’t clear about the issue. My code doesn’t run the function at the start immediately. I didn’t want to show the too much of the code cause I didn’t want to confuse you.
main.gd (Global name Main)
extends Node
signal reset_animation
@onready var player = $Player
@onready var lantern_group = get_tree().get_nodes_in_group("lantern")
@onready var killzone_group = get_tree().get_nodes_in_group("killzone")
func _ready() -> void:
for killzone in killzone_group:
killzone.connect("player_killed", player_killed)
func _process(_delta: float) -> void:
if Input.is_action_pressed("reset"):
player_killed()
func player_killed():
if player:
for lantern in lantern_group:
if lantern.ACTIVE:
player.global_position = lantern.global_position
break
reset_animation.emit()
print('good')
moving_platforms.gd
extends AnimatableBody2D
func _ready() -> void:
add_to_group("moving_platforms")
if Main:
Main.connect("reset_animation", _on_reset_animation)
func _on_reset_animation():
print('hi')
$AnimationPlayer.play("move")
When I use the reset
action, it will only print good
. This indicates that the signal was emitted, but not received by moving_platforms.gd
. From some more debugging, I figured out the connection in moving_platforms.gd
couldn’t be established, but I didn’t know how to fix it (I tried adding if Main
to see if it would work, but it didn’t. Are you able to find this issue? Thank you so much for your time.
Did it have a different error before if Main:
? This would only hide a null value error, not fix it.
You could try switching to the 4.x way to connect signals
Main.reset_animation.connect(_on_reset_animation)
Your main.gd may still have ordered issues by trying to get_nodes_in_group
before anything else is ready.
This is the only error I get in the Debugger. I also tried the 4.x way of connecting signals and it still doesn’t work.
Should I try delaying the moving_platforms.gd
’s _ready()
function until the Main finishes its set up?
No that error is the issue.
Did you declare the Main.gd script as global or the Main.tscn scene as global? If you did the script then it will not create any of it’s children, thus $Player
will not exist.
Setting main.tscn as global instead of main.gd seems to have fixed the issue for now, but the script is doing everything twice now. It prints good
twice and hi
2 * the number of platforms I have
times. Do you know why it might be doing this?
Did you make this Main scene a Global and the main scene for your project?
Godot always adds Globals as a new node to what ever scene is running. If you run or instantiate the Main.tscn while it’s a global then you will have two main scenes under /root
1 Like
Yes, main.tscn is the main scene of my project and also a global scene.