[SOLVED] Is there any way to get the collisions of an entity on demand? (Good way to to detect ground collision for jumping)

I’m trying to implement jumping.

The first method I tried was to allow the player to jump whenever it comes in contact with the ground by setting a variable canJump to true, and then when the player jumps, set it to false.

TouchInput.prototype.onCollisionStart = function(event) {
    for (i = 0; i < event.contacts.length; i++)
        if (event.contacts[i].normal.y == 1)
            this.canJump = true;
};

But the problem with this is, if the player is touching the ground and then falls off the ground the player can still jump because nothing sets canJump to false. I tried to use the “collisionend” event, but the event only returns the collision that ended, not the remaining collisions. So I couldn’t use that to check if the player is still touching the ground.

The second method I tried was to fire a ray cast from the player to a point below the player but the problem with this method is that if more than half of the player’s body is outside the platform then the player can’t jump.

So I thought the best way would be to check if the player is touching the ground by checking if the player is colliding with any other entities. But I couldn’t find a way to get the collisions of an entity on demand. Is there a way to do that?

Or is there a better way to implement jumping?

Right, so there is probably no universal approach and the jump mechanic is usually tailored to the game. From what I read in your description, your issue with the raycast was that it doesn’t report the collision, when the player is standing on the edge. You can mitigate it by using a convex sweep test of the physics engine, instead of raycast. If your character has a cyllinder collision shape, you can cast a sphere shape downwards to test for ground touch.

I made a convex cast extension to make it easier to do convex shapes collision tests:

Edit:
There is also a way for the collider to continuously track the collision with a rigidbody. I made an example a while back, but it hasn’t been battle tested, so might have bugs/issues:
https://playcanvas.com/project/718607/overview/oncollisionstay

1 Like

Thanks a lot. I’ll give it a try.

Although I’ll still try to find a simpler method.

1 Like

So I’ve decided to do it using my first method where I set canJump to true whenever I touch the ground.

I decided to handle this by just checking the player’s velocity on the Y axis whenever I click jump. If it’s less than 0, then that means the player is falling, so don’t let the player jump. This seems like a simple way to fix it and so far I haven’t found any downside to this method.

There’s a chance to do a double jump with this method at the very top of the jump where velocity may be 0.

I don’t know about the surface but you can also add a check of Y position with the ground if its plane. Like if player position is some particular range where the ground lies then it can also solve the problem.

I’m not just checking the player’s Y velocity.
I’m using a variable canJump and setting it to true whenever the player touches the ground.

On my collisionstart event I set it to true.

And then when the player jumps:

if (now - this.lastRightTap < this.doubleTapInterval && this.canJump == true && this.player.rigidbody.linearVelocity.y >= 0) {
    this.player.rigidbody.applyImpulse(this.jumpImpulse);
    this.canJump = false;
}

I don’t want a hard-coded value of Y. Because the map will include a lot of vertical spaces.

Update: I have switched from checking ground collision to raycasting, as sometimes after jumping up and while falling down, if my character was sliding against a wall it wouldn’t touch the ground(possibly due to friction?) and the collision event wasnt fired and I wasn’t able to jump. In order to jump again, I had to move my character away from the wall and then it would be able to jump again.