Search code examples
godotgodot4

Godot signals from one instance trigger the handling func for all instances


I have a main scene and secondary scene. I want to create multiple instances of the secondary scene. The secondary scene will emit a signal with information which is specific to it. The main scene will detect the signal and act on the information.

The main scene is empty. The secondary scene is made of an icon and collision2D to allow detection of mouse clicks:

enter image description here

Secondary.gd:

class_name Secondary extends Area2D
@onready var sprite_2d = $Sprite2D

signal secondary_clicked(value)
var information

func _input(event):
    if event.is_action_pressed("mouse_left_click"):
        secondary_clicked.emit(information)

Main.gd:

class_name Main extends Node2D

# Called when the node enters the scene tree for the first time.
func _ready():
    var secondary_scene = preload("res://Secondary.tscn")
    var secondary_instance = secondary_scene.instantiate()
    add_child(secondary_instance)
    secondary_instance.information = "1st"
    secondary_instance.position = Vector2(510, 320)
    secondary_instance.secondary_clicked.connect(handle_signal)
    
    secondary_instance = secondary_scene.instantiate()
    add_child(secondary_instance)
    secondary_instance.information = "2nd"
    secondary_instance.position = Vector2(710, 320)
    secondary_instance.secondary_clicked.connect(handle_signal) 

func handle_signal(value):
    print("The value from the scene: " + value)

I'm expecting that mouse click will result in "The value from the scene: 1st" or "The value from the scene: 2nd" depending on which instance I clicked.

The actual result is that I get two prints, regardless of which one I clicked. This output was made by a single click:

enter image description here


Solution

  • The _input event is not limited to the current Node.

    So both instances get a call to their _input.

    At no point whether or not the click is over them is considered.

    Yes, you could figure out if the click is over them, however for this usecase I suggest you use _input_event instead.