Linear velocity inconsistency on CollisionListener

Hello everybody.

I want to check when my player(a Sphere shape and CharacterControl) lands during a fall. So I created a CollisionListener to check when the player collides with something and since the onGround() method only works if the player is jumping I decided to use the linear velocity to know if the player is falling.

My code looks like this:

physicsSpace.addCollisionListener(event -> {
            PhysicsCollisionObject a = event.getObjectA();
            PhysicsCollisionObject b = event.getObjectB();
            PhysicsCollisionObject playerObject = player.getPlayerControl().getCharacter();

            Vector3f lv = new Vector3f();
            player.getPlayerControl().getCharacter().getLinearVelocity(lv);

            boolean isPlayer = playerObject.equals(a) || playerObject.equals(b);
            boolean negativeY = lv.getY() < -10;

            if (isPlayer && negativeY) {
                Sounds.LAND.play();
            }
        });

The problem is that sometimes when I get the velocity on a fall collision the Y is zero, I suppose this is because I’m getting the velocity when the player already landed.

This happens when the fall distance is: 1(this one is not a problem) 3 4 6 10 units

I tried different things like:

  • Increase the CollisionShapeMargin
  • Modify the physic step and fall velocity

But those only mitigate a little the problem and have some drawbacks.

I also thought in using raycast in the update loop or add a additional CollisionShape at the bottom of the character or just use the update loop to store the last linear velocity.

What do you suggest?

Thanks!

PD: I’m using Minie 7.8.1

1 Like

On my current project, I use a GhostControl with Box shape below the player spatial (what happening when hitting an object from the side while falling?) and handle the whole thing in the players update loop. When the Box doesn’t collide and the vertical velocity is bigger than a value (GhostControl uses only AABB), it switches to the fall state; when it is in the fall state, the box collides and the velocity is 0, it switches to the landing state.

But I have no idea, if it is a good way. ^^"

3 Likes

Thanks for the response @Nakano, I like your approach, I will try to implement it :+1:

1 Like

onGround() is intended to work even when the player hasn’t jumped.

I made changes in Minie version 5.0 that might be related to the issue you’re seeing. How is onGround() failing? Is it returning false when the character is on the ground? Or is it returning true when the character is airborne?

The biggest issue with CharacterControl is that crucial parts are hard-coded in C++ and are difficult to modify without breaking things. Perhaps you should consider switching to BetterCharacterControl or writing your own custom control based on BetterCharacterControl.

1 Like

Hello @sgold, onGround() returns true when the character is airborne, works fine when the character jumps, but when, for example, it walks off a platform only returns true.

This also affected my jump logic since I only wanted it to be able to jump when is on ground but if it walks off a platform it can jump midair. But then I though:

Hmmm, that’s a nice feature to have.

So I let it be. :rofl:

Anyway, thanks for the suggestion, I will try BetterCharacterControl.

If you need help reproducing the issue just tell me.

2 Likes

when, for example, it walks off a platform only returns true.

Thanks. That’s what I was afraid of.
I’ll write a test for this situation and try to fix the bug.

2 Likes

I’ve developed a simple fix for the false positives in onGround(). I expect the fix will be in the next release of Minie.

3 Likes