Why are all instanced scenes responding to a mouse click done on a single one?

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

The instanced scene tree is:

The KinematicBody is scripted with:

func _input(event):
	if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
		print(self.name, ", ", get_parent().name)

I make two instances of the above scene in another scene like this:

extends Spatial

export (PackedScene) var Body

func _ready():
	var body1 = Body.instance()
	body1.translate(Vector3(-10, 0, 0))
	var body2 = Body.instance()
	body2.translate(Vector3(10, 0, 0))

But if I click one body, I get:

KinematicBody, @Spatial@2
KinematicBody, Spatial

So, the event fires up on all instances, instead of just the one that I clicked. Note that I want to understand WHY it happens, not interested in alternative walk arounds. Though I may post here my final solution later. Thanks!

deleted duplicate answer

Bernard Cloutier | 2020-10-05 15:03

:bust_in_silhouette: Reply From: Bernard Cloutier
func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
        print(self.name, ", ", get_parent().name)

This will function will be invoked on every script instance that contains it. When you click somewhere, the engine gets out its list of nodes defining an _input method and invokes each one. Nothing in this function is specific to which node you are clicking on.

What you want is to connect to your kinematic body’s input_event signal so that you can handle input events specific to your body:

func _on_KinematicBody_input_event(camera, event, click_position, click_normal, shape_idx):
	if event is InputEventMouseButton and (event as InputEventMouseButton).pressed:
		print(self.name) # I check for pressed, else this will also print when the button is released

Thanks, I seem to think abut the instances the same way as in general OOP, and viewed the _input() function as encapsulated object method. But it seems that it is some kind of class method after all. Unfortunately, the _on_Kinematic signal does not fire in my game, not sure why. (Any idea how to debug it, why a signal does not fire?) On small study projects what you sugested works perfectly, but not in my game. I will try to pick objects using ray casting instead.

grok | 2020-10-05 16:04

Have you connected the input_event signal to _on_KinematicBody_input_event?

The _input function is indeed a typical OOP virtual method. Or do you want your entities to only react to mouse clicks if they happen on them? How would you implement click-to-move (like in an rts) then? You’d have to go about it in a roundabout way.

I’ll admit the docs don’t make the intended use of the input_event signal very clear though: https://docs.godotengine.org/en/stable/classes/class_collisionobject.html#signals

Bernard Cloutier | 2020-10-05 16:14

As I say, it works on simple test projects, but it doesn’t in my game. Maybe because I collect a lot of input in other scenes, who knows. I don’t want to implement click to move, just to select (pick) kinematic bodies that are instanced from a single scene.

I tried raycast but I got stuck at printing the clicked object name (though I seem to get it’s ID correctly). Can you help? how to obtain instanced scene name via ray casting? - Archive - Godot Forum

grok | 2020-10-05 17:18