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?
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
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.
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.
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.