How do you access the return value of the move_and_collide function?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dragon11705

I am using the move_and_collide 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?

:bust_in_silhouette: Reply From: jgodfrey

Looking at the move_and_collide docs here:

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

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


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

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'):

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 collision_info = [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_and_collide function) it returns null for collision_info and groups variables.

Dragon11705 | 2020-01-25 02:18

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'):

jgodfrey | 2020-01-25 02:26

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 move_and_slide/move_and_collide 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.

Dragon11705 | 2020-01-25 02:32