+1 vote

I am using the moveandcollide function to detect collisions between 2 kinematic2d bodies (I am checking if the colliding object is in a specific group), but don't know how to use, access, or check the group of the return value of the function. It is supposed to return a KinematicCollisionObject or something, but I have no clue how to access it or use it in an if statement. Anyone know how to?

in Engine by (31 points)

1 Answer

+2 votes

Looking at the move_and_collide docs here:

https://docs.godotengine.org/en/3.1/classes/class_kinematicbody2d.html#class-kinematicbody2d-method-move-and-collide

move_and_collide returns a KinematicCollision2D object. So, looking at that object here:

https://docs.godotengine.org/en/3.1/classes/class_kinematiccollision2d.html#class-kinematiccollision2d

You can see all of the properties and methods associated with it. The interesting property in this case is:

collider

That's documented as the colliding body. You can use that to access the underlying group(s). So, something like this:

var collision_info = move_and_collide(...)
var groups = collision_info.collider.get_groups()
print(groups)
by (19,238 points)

What I am doing is trying to get it to do something when an enemy(a kinematic body2d in a group called 'Enemy') collides with the player (a kinematicbody2d).
The problem is that when I use an if statement to check if the collider is in a group, the collision seems to return null and also it freaks out since my tilemap doesn't have a collider on it.

func _process(delta):
var collision_info = move_and_collide(Vector2(0,0))
if collision_info.collider.is_in_group('Enemy'):
    print('Dead')

Once I start it and try to move, It stops and the debugger gives me this error:
Invalid get index 'collider' (on base: 'null instance').
It also says that collisioninfo = [null]
Let me know if you need anymore information to help me solve the issue please.
P.S. Every child node including the collision shape of the enemy is in the group "Enemy".
P.P.S When I try using the code you gave me (with a vector2(0,0) as the argument for the move
andcollide function) it returns null for collisioninfo and groups variables.

I'm not in front of Godot ATM to test anything, but guessing, you might need to validate a few things once you get the collision_info object back, before attempting to use it...

Perhaps this:

var collision_info = move_and_collide(Vector2(0,0))
if collision_info is KinematicCollision and collision_info.collider is Node:
    if collision_info.collider.is_in_group('Enemy'):
        print('Dead')

Thank you so much it seems to be working mostly now. The only issue is that for some reason it only detects the collision when the player is moving and is colliding with the enemy, and does nothing when the enemy collides with the player unless the player is moving. I will look into that if you have an idea feel free to share it though.
Edit: Never mind I think I found a way I am trying it out now. It should work if I detect collisions from both the player and enemy nodes at the same time since the enemy is always moving. Apparently moveandslide/moveandcollide only work when the kinematicbody2d is moving which I guess makes sense. Again think you for your help I really appreciate it.
Edit: I tried it out and it works almost perfectly now. All I had to do was use the code you have in your current last comment in both kinematicbodies (and change it for the enemy to look for the player group) and wire them together using custom signals and it works near perfectly.

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.