+1 vote

I created a Player scene and attached a script to it. To my understanding, I thought that like OOP, if I add multiple instances of the same player scene to my main scene, each of them will operate like a unique instance and will have its own script instance so that every signal sent to this script will be sent to X instances of player scenes I have.

That's not the case... I emit a signal from my main scene script and it received on the player script once, for all instances of player in the scene.

Maybe I misunderstood and this is not possible to begin with but if it does, how? and if not, what would you suggest to be a solution to such a case?

in Engine by (13 points)
reshown by

I emit a signal from my main scene script and it received on the player script once, for all instances of player in the scene.

I don't understand how that's different from

every signal sent to this script will be sent to X instances of player scenes I have.

If all your players are connected to the same signal, when that signal emits, all players will receive it.

Do you mean only ONE of your players receive it?

All my players receive it so doing something that should affect only one of them is impossible.
I ended up sending multiple signals with the player object as a param to check if player.name == self.name and do the action only for it.
Is this the way to go?

You can choose which is connected and which isn't. If you want some players to never receive the signal, just disconnect it from these instances. Or don't make the connection in the first place, depends how you connected the signal.

I want all the players to receive the signal but handle it uniquely for each of them. Do I have to emit the signal X times or is there an option to emit it once and somehow handle it per Player?

Sorry I still don't understand what you really want. Signals are connected to whichever you want, and when you emit it once, it gets sent to whoever is connected to it at the time. The emitter can send arguments as well. There is also a way to specify extra arguments at connection time, which expand the emit-time arguments.

I ended up sending multiple signals with the player object as a param to check if player.name == self.name

I don't understand the point of this either. If you want to send a message to a particular player, just call a function on that player, don't use signals. Or connect the signal only to that player.

Thanks for taking the time to answer although I wasn't clear enough. @Zylann

Maybe some code will help.
Main scene script:

func stop():
    emit_signal("touch")

Player script:

func _on_Main_touch():
# Do whatever

In this way, _on_Main_touch() will be called once per player which is great but I don't have any way I know of to do handle it differently per player instance. For example: Player1 should go right, Player2 should go left and Player3 should go up.

So I moved to:
Main scene script:

func stop():
    for player in get_tree().get_nodes_in_group("players"):
            emit_signal("touch", player)

Player script:

func _on_Main_touch(location, player):
      if (player.get_name() == self.get_name()):
      #Do something else per player

This way works for my logic but _on_Main_touch is called way more than needed (4 times per player as there are 4 players in that node group).

Are any of the above is the right way to go? Any better ways?

for player in get_tree().get_nodes_in_group("players"):
        emit_signal("touch", player)

Considering what you want to do, this is obviously not the right solution. Keep it with a single emit_signal.

So all your players will receive the signal touch. Great. Now you want each of them to do something different: based on what?
You gave an example where Player1 should go right, Player2 should go left and Player3 should go up. So the solution to that would litterally be:

func _on_Main_touch():
    if name == "Player1":
        # Go right
    elif name == "Player2":
        # Go left
    elif name == "Player3":
        # Go up

If it's more complex than that, maybe you need different scripts with a common base script, or you could connect to a different function, or specify connect-time arguments (with the signal "bindings").

Thanks! I misunderstood signals it seems, now I get it and it works.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.