Need Help With Signals 2

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
image

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.

image
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.