How to get a node by mouse click?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By guawoo
:warning: Old Version Published before Godot 3 was released.

I searched all topics and had not found any tips about how to get a node by mouse click.I try to use KinematicBody2D and checked “pickable”.yes , it work,but not I want. I want to pick a node instance like Unity use ray-cast to get a object when mouse clicked.How to do in Godot?

Any type of nodes and all nodes under mouse point?

volzhs | 2016-05-05 06:55

yes,they can distinguish by tag or other way.

guawoo | 2016-05-05 08:01

what if scene tree is made like this?

- root
    - node (object)
        - sprite (for image view)
            - area2d (for some reason)
        - label (for name)

what do you want to pick if mouse point is in area2d?
what if mouse point is on area2d and label?

volzhs | 2016-05-05 09:09

- root
- node (object)
    - sprite (for image view)
        - area2d (for some reason)
    - label (for name)

I want to pick the node(object).
when mouse point on the node(object),then click, return the node(object). that I want.

sorry my bad English. If it hard to solve, I just use KinematicBody2D and check “pickable” to instead. It’s OK for me.

guawoo | 2016-05-05 09:26

:bust_in_silhouette: Reply From: PlanetKiller

extends Camera

member variables here, example:

var a=2

var b=“textvar”

var to = Vector3(0,0,0)
var from = Vector3(0,0,0)

func _fixed_process(delta):
var ds = PhysicsServer.space_get_direct_state(get_world().get_space())
if(Input.is_action_pressed(“left_click”)):
var col = ds.intersect_ray(from, to)
print(col.keys())
if(“collider” in col.keys()):
var obj = col[“collider”]
var colpos = col[“position”]/2
var blockpos = Vector3(ceil(colpos[0]), ceil(colpos[1]), 0)
obj.set_cell_item( int(colpos[0]), int(colpos[1]), 0, -1)
print(obj.get_cell_item( int(colpos[0]), int(colpos[1]), 0))
print(col[“position”])

func _input(event):
if (event.type == InputEvent.MOUSE_BUTTON and event.button_index == BUTTON_LEFT and event.pressed):
from = self.project_ray_origin(event.pos)
to = from + self.project_ray_normal(event.pos)*10000

func _ready():
# Called every time the node is added to the scene.
# Initialization here
set_process_input(true)
set_fixed_process(true)
pass


I use the above script to grab a block in a gridmap node. You should be able to modify it for any other node though using var obj = col[“collider”].
Mainly it projects a ray from the camera and uses that to select a node, but I’m unsure if I used a collision node as the parent, or if you need a physics setup.

I tried to use the code tag thingy, but it derped.

extends Camera

# member variables here, example:
# var a=2
# var b="textvar"

var to = Vector3(0,0,0)
var from = Vector3(0,0,0)

func _fixed_process(delta):
	var ds = PhysicsServer.space_get_direct_state(get_world().get_space())
	if(Input.is_action_pressed("left_click")):
		var col = ds.intersect_ray(from, to)
		
		print(col)
		print(col.keys())
		if("collider" in col.keys()):
			var obj = col["collider"]
			var colpos = col["position"]/2
			print(colpos)
			var blockpos = Vector3(ceil(colpos[0]), ceil(colpos[1]), 0)
			obj.set_cell_item( int(colpos[0]), int(colpos[1]), 0, -1)


func _input(event):
	if (event.type == InputEvent.MOUSE_BUTTON and event.button_index == BUTTON_LEFT and event.pressed):
		from = self.project_ray_origin(event.pos)
		to = from + self.project_ray_normal(event.pos)*10000
		
		

func _ready():
	# Called every time the node is added to the scene.
	# Initialization here
	set_process_input(true)
	set_fixed_process(true)
	pass

PlanetKiller | 2016-05-16 16:19

How to make it working in 2D? Do we really need a camera here?

qazwsx | 2016-08-16 09:53

Haven’t tried in 2D, but you might be able to get mouse point relative to the scene’s parent node. Try getting mouse position and deviding it by half the tile resolution.

PlanetKiller | 2016-08-24 15:19

:bust_in_silhouette: Reply From: luislodosm

This code searches for CollisionObject2D under the mouse pointer. It can also search for areas if specified in the parameters.

if Input.is_action_just_pressed("mouse_click"):
	var mousePos = get_global_mouse_position()
	var space = get_world_2d().direct_space_state
	var collision_objects = space.intersect_point(mousePos, 1)
	if collision_objects:
		print(collision_objects[0].collider.name)
	else:
		print("no hit")