Dante
Dante

Reputation: 13

How do I check if two KinematicBody2D's are overlapping in Godot?

I've just gotten into coding, and I'm trying to make a simple duck shooter game in Godot 3.0. I have a crosshair(Kinematicbody2D) and ducks flying across the screen(also KinematicBody2D). Is there a way that I can detect if the duck and crosshair are overlapping? Like an if statement?
In case anyone's curious, this is the code I've got so far (This is the duck script and the comments are what I need to add in on that line).

 func _physics_process(delta: float) -> void:
    position.x += 4
    if (position.x > 1600):
        Score -= 1
        position.x = rand_range(-250, -1000)
    
    if Input.is_action_just_pressed("shoot"):
        #check if overlapping with crosshair
            Score += 1
            #bird explodes in feathers
            position.x = rand_range(-250, -1000)
        else:
            Score -= 0.25

Upvotes: 1

Views: 1207

Answers (1)

Theraot
Theraot

Reputation: 40220

I don't think it makes sense to make the crosshair into a physics body. Does it collide/push/bounce off obstacles? Much less a KinematicBody2D. Do you need move_and_slide or can you get away with writing the position? So here are some alternatives to go about it, before I answer the question as posted.


Input Pickable

If you want to find out if the pointer interacts with a physics body, you can enable input_pickable, and you will get an "input_event" signal whenever it happens.


Mimic input Pickable

Otherwise you can get the position of the pointing device in an _input event and query what physics objects are there. Something like this:

if (
        event is InputEventScreenDrag
        or event is InputEventScreenTouch
        or event is InputEventMouse
    ):
        var viewport := get_viewport()
        var position:Vector2 = viewport.get_canvas_transform().affine_inverse().xform(event.position)
        var objects := get_world_2d().direct_space_state.intersect_point(position)
        for object in objects:
            print(object.collider)

And see if the one you want is there.


Area2D

Another option is to make the crosshair into an Area2D, then you can ask the Area2D for its overlapping_bodies, and see if the one you want is there. Or call overlaps_body passing your physics body as parameter and it returns true or false if it is overlapping the Area2D or not, respectively.


KinematicBody2D collisions

And to answer the question on the title, if you have two kinematic bodies, if you moved them with move_and_* methods (which is how it is intended). You can a lists of what they collided with like this:

for i in get_slide_count():
    var collision = get_slide_collision(i)
    print("Collided with: ", collision.collider.name)

Otherwise, you can do this:

var parameters := Physics2DShapeQueryParameters.new()
parameters.transform = global_transform
parameters.set_shape($CollisionShape2D.shape)
var results = get_world_2d().direct_space_state.intersect_shape(parameters)
for result in results:
    print(result.collider)

Upvotes: 1

Related Questions