Problems with 3D collision detection/notification depending on collision shape

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

Hey there,

A few colleagues and I have been trying to acquaint ourselves with Godot, in order to use it for future game Projects. While trying out some basic examples we run into a weird problem:

the Setup

We wanted to have 2 sets of rigidbodies: the player(s) on the one hand and projectiles (in this case rockets) on the other hand. Right now we just wanted the rockets to despawn upon impact. For this example it’s not really necessary to make either of nodes Rigidbodies (Areas or KinematicBodies would work fine I suppose) but since is a testcase for a common setup this is what we chose to do.

Originally we used the Notification system with something similar to this code:

public void _on_Player_body_entered (Godot.Object col){
    GD.Print("Collision with: " + col);
    Node n = (Node) col; 

After running into the problems (see below) we tried a few other implementations that should really do the same thing, judging from the documentation.

public override void _PhysicsProcess(float delta){
          foreach (PhysicsBody bod in this.GetCollidingBodies()) bod.QueueFree();

As can be seen we used C# as scripting language and the Godot 3.1 beta.

the Problem

When all collision shapes are boxe shapes this works without any flaw we could notice. When changing them to spheres/capsules/cylinders every now and then (ca. 5-20% of the collisions) a collision would occur, but the code would not run and the projectiles would just bouce off of the player and float away into space.

These 2 short videos demonstrate the problem: - with box colliders - with Sphere colliders

the Question
Why does this problem occur? Is there a way to make sure notifications occur (other than using box colliders for everything)? Is this possibly a beta-only problem?

Thanks a bunch for any help people can provide. We’d really like to work with an Open Source engine such as Godot, but weren’t able to find any satisfying solution for this problem so far.

One basic thing about collision shapes (maybe unrelated): Never scale them. Leave the Scale at 1:1 and edit the extents of the shape.

If you want a collision but not a collision then you might be better off using an area as a child for the Rockets. That way there will be no bounce. Another way would be to use a Kinetic Body + move_and_collide

Another aspect might be to also add an _entered check for the rocket. Perhaps the collision event is only triggered on either side.

Another method to check for collisions are the PhysicsDirectBodyState.get_contact* methods callable in the RigidBodies _integrate_forces() handler.

Finally, when things get too fast (not here) it might be an idea to work with raycasts. (Good for fast moving bullets)

wombatstampede | 2019-01-23 14:14

Thanks for the answer.

I was aware of Godots “never scale colliders” paradigm, so that’s not the source of the problem. We also tried to track collisions on both sides (in this case: on the rockets as well as on the player) but this didn’t reduce the number of error cases to a satisfying number.

It’s also clear that for this specific case other setups (e.g. using an area or kinematicBody) would probably work. The reason why I’m asking the question here is that generally avoiding colliding rigidbodies if you want to track collisions in code seem an aweful restriction for a 3D engine. I wasn’t able to find any documentation on similar cases. If this is a known issue that is being worked on or the result of me/us not following conventions we were not aware of, that is fair enough. But not finding any answer is a tad frustrating.

radow | 2019-01-23 19:04

You have two “colliding” problems here:
On one side there’s a physics engine which “automatically” reacts to collision when a RigidBody collides. On the other side, there’s the collision notification which is probably slightly delayed (shortly after the “bounce”).

In this case I’d also see it as an error that you sometimes don’t get any collision event at all. You should open a ticket on github ( GitHub - godotengine/godot: Godot Engine – Multi-platform 2D and 3D game engine ) … and you should add a simplified test case to that ticket.

But as collision notifications may be slightly delayed/deferred you may be better off handling collisions differently (as long as you want to keep the collision like it is). I see that you already tried checking inside _physicsprocess() although I didn’t find any infos about your results in that case. Personally I’d put the collision check into integrate_forces() of the “rock”:

 func _integrate_forces(state):
    if state.get_contact_count()>0:
        <do something>

(You have to set the contacts_reported value to a non-zero value, see: Physics introduction — Godot Engine (latest) documentation in English )

wombatstampede | 2019-01-24 07:52

Thanks for the reply.

I’ll try checking for collisions in _integrate_forces as you suggested.

Checking in _physicsprocess() had the same result as using the notification system.
The contacts_reported value had already been set to some integer value >0, since this is also necessary for the notification system as far as I understood the documentation.

radow | 2019-01-24 10:20