This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+2 votes

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?

in Engine by (27 points)

Any type of nodes and all nodes under mouse point?

yes,they can distinguish by tag or other way.

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?

- 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.

2 Answers

–1 vote

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 fixedprocess(delta):
var ds = PhysicsServer.spacegetdirectstate(getworld().getspace())
if(Input.is
actionpressed("leftclick")):
var col = ds.intersectray(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
cellitem( 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.buttonindex == BUTTONLEFT and event.pressed):
from = self.projectrayorigin(event.pos)
to = from + self.projectraynormal(event.pos)*10000

func ready():
# Called every time the node is added to the scene.
# Initialization here
set
processinput(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.

by (62 points)

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

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

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.

+2 votes

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")

https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html

by (332 points)
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 Frequently asked questions and 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 [email protected] with your username.