Why isn't a signal propogating?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By indy2005

I have Player1 with a Tween. The parent node is connected to the tween_completed signal via the UI.

I have Player2 which I need to react to the tween in Player1 completing.

I had thought I could simply connect Player2 to tween_completed on Player1, but this doens’t work. Instead I have to emit a separate signal from within Player1, in the on_tween_completed function, which I then capture. I would have thought on_tween_completed was a general signal which could be caught by any node in the scene that was interested.

i.e. This doesnt work:

Player1

extends Node2D

export var index:int = 0
onready var tween:Tween = $Tween
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
signal hide_players


# Called when the node enters the scene tree for the first time.
func _ready():
	if index == 1:
		tween.interpolate_property(self, "scale", null, Vector2(2.0,2.0), 4,Tween.TRANS_EXPO,Tween.EASE_IN)
		tween.start()
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass


func _on_Tween_tween_completed(object, key):
	self.visible = false

Player2

# Called when the node enters the scene tree for the first time.
func _ready():
	var player = get_node("/root/Game/Player1")
	
	player.connect("tween_completed", self, "_vanish")


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass
func _vanish():
	self.visible = false

But this arrangment does work, where I emit a fresh signal within Player1.

Player1

func _on_Tween_tween_completed(object, key):
	self.visible = false
	emit_signal("hide_players")

Player2

player.connect("hide_players", self, "_vanish")
:bust_in_silhouette: Reply From: klaas

Hi,
any object in the sceneTree can connect to any signal from any object in the sceneTree.

I think the problem is

var player = get_node("/root/Game/Player1") # <- this is the player, not the tween

player.connect("tween_completed", self, "_vanish") #the tween emits the signal, not the player

If my referencing was wrong, neither example would work, would it? In my working example, and non-working example, the node path is the same. The only thing different is the signal. I tried connecting to the /Tween instance directly, that didn’t work either.

This doesnt work.

func _ready():
	var player = get_node("/root/Game/Player1/Tween")
	
	player.connect("tween_completed", self, "_vanish")


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass
func _vanish(signal_index:int):
	if index == signal_index:
		self.visible = false

indy2005 | 2020-09-18 17:04

in your second example the playerr emits the signal, not the tween. therefor connecting to the player was correct.

In your newer code you connect the tween_completed with the vanish function. You expect one attribute. But tween_completed signal is specified like …

tween_completed ( Object object, NodePath key )

I dont know what index is but its most unlikely the other player object.

Therefor the condition fails and the player did not hide

klaas | 2020-09-18 17:26

index is just a way for me to selectively have some instances but not others respond to the signal while I learn…I will try your suggestions and let you know, thanks

indy2005 | 2020-09-18 17:29

Works now, thanks!

indy2005 | 2020-09-18 19:22