Signal does not disconnect

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

I’m trying to make a script in an enemy class to shoot at the player. I’m trying to use signals but the engine is throwing an error:

0:00:08:0202 - Signal 'player_entered' is already connected to given method 'on_player_entered' in that object.
----------
Type:Error
Description: Signal 'player_entered' is already connected to given method 'on_player_entered' in that object.
Time: 0:00:08:0202
C Error: Condition ' s->slot_map.has(target) ' is true. returned: ERR_INVALID_PARAMETER
C Source: core/object.cpp:1413
C Function: connect

When the player enter in an Area2D around the enemy, it triggers the following code:

func _on_sensor_body_entered(body):
	var n = body
	$time_shoot.start()
	emit_signal("player_entered" , n)
	attack(body)

The signal will be connected by the $time_shoot:

func _on_time_shoot_timeout():
	print("I'm here")
	self.connect("player_entered" , self , "on_player_entered")
	print(str(self.is_connected("player_entered" , self , "on_player_entered")) + " Connected")

func on_player_entered(body):
	print("I'm here man")
	attack(body)
	self.disconnect("player_entered" , self , "on_player_entered")
	print(str(self.is_connected("player_entered" , self , "on_player_entered")) + " Disconnected")

Then the attack function runs and the body_exited signal should stop the timer

func attack(body):
	var shoot = pre_shoot.instance()
	var angle = $sight.look_at(body.global_position)
	shoot.global_position = $sight.global_position
	shoot.global_rotation = global_rotation
	shoot.dir = Vector2(cos(global_rotation) , sin(global_rotation)).normalized()
	get_parent().add_child(shoot)

func _on_sensor_body_exited(body):
	$time_shoot.stop()
	pass

But by the Output it seems that the connect() is not connecting to on_player_entered function. Due to the error, I’m trying to disconnect the function, but no lcuk. What I’m missing?

:bust_in_silhouette: Reply From: Warlaan

You seem to misunderstand what signals are doing.
Signals are basically method calls, the only difference is that you don’t need to know the function to be called at the time you are writing the calling code.

So for example when someone wrote the button node they added a pressed signal because they knew that when the button is pressed you will want to call something, but since they didn’t know your project they couldn’t say which function it would be.

Connecting signals is kind of filling in the blanks. So when you connect the player entered signal you are saying "from now on when emit_signal(“player entered”) is called I want it to call this function.

So the first mistake you are making is that you are calling emit_signal right away in _on_sensor_body_entered, but the signal isn’t connected until the time runs out.

Before I can give you any tipps how to fix the code you’ll have to describe what it is supposed to do, because you are emitting the signal right away, but you aren’t connecting it until the timer runs out. Do you want to attack right away or after a delay?

In any case I don’t think that you need signals here. You know the player entered method, so there’s no need for abstracting the call with a signal.

The last part of your comment was the solution. Another person suggested me to just use a variable to store the body that on_body_entered gets and then use it in my attack function. It worked.

Regarding the use of signals: yes, I really got confused with the use. If I’m understanding this correctly, the connect() should be on the _ready() on the script that will connect to the signal, right? Seems more suitable for other classes than the one that is emitting
the signal.

malkav182 | 2019-04-04 21:25