Use raycast for jumping detection

Right now, my code to detect if the player can jump is based on this.entity.collision.on('collisionstart', function()) {.... The problem is that if the player touches the walls, it counts as if he is on the ground. This creates another problem that when I push the player down, it should feel like the player falls naturally. Namely, the value of the downwards force gets reset.

I’ve heard about raycasts, but I don’t know how to implement it yet on PlayCanvas.

Here is my code with the collision based detection so far (my collision bean has a height of 2.5):

var Jump = pc.createScript('jump');

Jump.attributes.add('doesLevelAllowJump', {
    type: 'boolean',
    default: true,
    description: "Allows the player to jump."
});

Jump.prototype.initialize = function(){
    this.angularFactor = new pc.Vec3();

    this.canJump = false;
    this.entity.collision.on('collisionstart',function(){
        this.gravity = 0;
        this.canJump = true;
    },this);

    this.entity.collision.off('collisionend',function(){
    this.canJump = false;
    },this);

    this.gravity = 0;
};

Jump.prototype.update = function(dt) {
    //Der gravity wird ständig zurückgesetzt, während der Spieler den Boden berührt
    if(this.canJump) {this.gravity = 0;}

    if(!this.canJump)
    {
        //Druck nach unten
        this.gravity += dt;
        this.entity.rigidbody.applyForce(0, this.gravity * -3000, 0);
    }
    if(this.doesLevelAllowJump){
        if(this.app.keyboard.wasPressed(pc.KEY_SPACE) == true && this.canJump == true){
            this.entity.rigidbody.applyImpulse(0, 1250, 0);
            this.canJump = false;
        }
    }
};

Hi @SayHiToMePls!

A raycast is simple to create. You need a start position and an end position for this. The easiest way is to add an empty entity below your player, that will be the end position. The player itself can be the start position.

    var from = this.entity.getPosition();
    var to = this.entity.findByName('endEntity').getPosition();
    var result = this.app.systems.rigidbody.raycastFirst(from, to);

    if (result) {
       // player  is grounded
    }    

You have to prevent that the raycast can hit the collision component of the player itself.

1 Like

So “result” is to detect if the raycast between both entities touches anything inbetween?

Can’t I do a raycast without an extra object? Maybe start from player, then go 1.25 or a bit more down and then checking if the raycast hits anything except for the player.

Yes.

Yes you can, but I don’t know the exact way out of my head.