godot how to know if a click is inside a sprite :

Viewed 492

I have a p12 Sprite that have a KinematicBody2D and the KinematicBody2D have a Collision polygon2d.

I'am trying to check if a mouse clik is inside p12 :

var inside : bool = p12.get_node("KinematicBody2D").has_point(to_local(pos))

or

var inside : bool = p12.get_node("KinematicBody2D").get_node("Collision polygon2d").has_point(to_local(pos))

Are not working.

Any idea how to check if the click is inside my sprite ?

here is my code :

func wich_piece(mouse_pos : Vector2 ):
    for piece in pieces:
        var inside : bool = ((piece as Sprite).get_node("KinematicBody2D") as KinematicBody).has_point(to_local(mouse_pos))
        if inside:
            return piece
    return null 

Regards

2 Answers

If I understand correctly you want to detect a mouse click inside a sprite?

I'm assuming your sprite is inside a KinematicBody2D Like this:

enter image description here

Connect The signal input_event() in KinematicBody2D to any script and check if the mouse is clicked inside it:

enter image description here

func _on_KinematicBody2D_input_event(viewport, event, shape_idx):
    if(event.is_pressed()):
        print("pressed!")

Now every time I click I get a signal like this:

enter image description here

I have a p12 Sprite that have a KinematicBody2D and the KinematicBody2D have a Collision polygon2d.

This is an odd setup, it means that if you move the KinematicBody2D the Sprite does not. Are you sure you don't want to have KinematicBody2D with Sprite as child?


If you want to find out if a position is inside a sprite, you would do something like this:

var inside:bool = p12.get_rect().has_point(p12.to_local(pos))

Pay attention that I'm calling to_local on the Sprite. If you are using local coordinates, it is important what they are local to. I'm, of course, assuming pos was in global coordinates to begin with.


However, if the goal is to find if a position is inside a PhysicsBody2D(such as KinematicBody2D), we do something different.

We can do this:

func collides(body:PhysicsBody2D, pos:Vector2) -> bool:
    var results := get_world_2d().direct_space_state.intersect_point(pos)
    for result in results:
        if result.collider == body:
            return true
    
    return false

As you can imagine that would be a waste of effort if we are going over an array like you do. Since intersect_point is already telling us the PhysicsBody2D, you would approach this differently. Something like this:

func wich_piece(pos:Vector2):
    var bodies := []
    var results := get_world_2d().direct_space_state.intersect_point(pos)
    for result in results:
        bodies.append(result.collider)

    for piece in pieces:
        var body := ((piece as Sprite).get_node("KinematicBody2D") as KinematicBody)
        if bodies.has(body):
            return piece

    return null

But if all you actually want is to find out when the user clicks a KinematicBody2D. Set input_pickable to true. The you will get "mouse_entered", "mouse_exited" and "input_event" signals. Plus calls to _input_event.

Related