Jump Is Acting Weird

I’ve been trying to make some decent physics using ammo. So far, the movement stays consistent across me and my friend’s computer. I’ve been trying to add in jump. Basically, it’s just adding to the ysp variable, with some additional maths to account for slopes. Problem is, the jump acts weird. When you press W to jump, the player just teleports up right away, and then falls back down. I’ve been trying many ways, but it doesn’t work with ysp around. It only works when you apply Impulse normally, but I don’t want that, as it ruins the movement code written before it. If I try to use Impulse when I still use ysp, it has the same result.

Code:

var PlayerController = pc.createScript('playerController');

//Variables
var acc = 10;
var frc = 10;
var dec = 25;
var jmp = 1200;
var grounded = false;
var max_speed = 60;
var gsp = 0;
var xsp = 0;
var ysp = 0;
var MainForce;
var goingRight = true;
var angle = 0;
var grv = 20;
var air = 6;
var checkGround = false;
var slope = 12.5;

PlayerController.prototype.initialize = function() {
    MainForce = new pc.Vec3();
    this.app.keyboard.on(pc.EVENT_KEYDOWN, this.onKeyDown, this);
    this.app.keyboard.on(pc.EVENT_KEYUP, this.onKeyUp, this);
    this.entity.collision.on('collisionstart', this.onCollisionStart, this);
    this.entity.collision.on('collisionend', this.onCollisionEnd, this);
    this.entity.collision.on('contact', this.onContact, this);
};

PlayerController.prototype.update = function(dt) {
    /*if (this.app.keyboard.isPressed(pc.KEY_A)) {
        if (jump === false) {
            this.entity.rigidbody.applyForce(-speed * dt / 2, 0, 0);
        }
        if (jump === true) {
            this.entity.rigidbody.applyForce(-speed * dt, 0, 0);  
        }
    }
    if (this.app.keyboard.isPressed(pc.KEY_D)) {
        if (jump === false) {
            this.entity.rigidbody.applyForce(speed * dt / 2, 0, 0);
        }
        if (jump === true) {
            this.entity.rigidbody.applyForce(speed * dt, 0, 0);  
        }
    }
    if (this.app.keyboard.wasPressed(pc.KEY_W) && this.entity.rigidbody.linearVelocity.y === 0) {
            this.entity.rigidbody.applyImpulse(0, jump_force, 0); 
        jump = false;
    }
    if (this.entity.rigidbody.linearVelocity.x > max_speed) {
        this.entity.rigidbody.linearVelocity(max_speed, this.entity.rigidbody.linearVelocity.y, this.entity.rigidbody.linearVelocity.z);
    }*/
    
    //Functions
    this.MainPhysics(dt);
    this.onGrounded();
};

PlayerController.prototype.MainPhysics = function(dt) {
    this.entity.rigidbody.linearVelocity = MainForce.set(xsp * dt, ysp * dt, 0);
    
    //Basic Movement
    if (this.app.keyboard.isPressed(pc.KEY_D)) {
        gsp += acc;
        goingRight = true;
    }
    if (this.app.keyboard.isPressed(pc.KEY_A)) {
        gsp -= acc;
        goingRight = false;
    }
    if (!this.app.keyboard.isPressed(pc.KEY_D) && !this.app.keyboard.isPressed(pc.KEY_A)) {
        goingRight = null;
    }
    
    //Deceleration / Friction
    if (gsp > 0 && goingRight === false) {
        gsp -= dec;
    }
    if (gsp < 0 && goingRight === true) {
        gsp += dec;
    }
    if ((gsp > 0 || gsp < 0) && goingRight === null) {
        if (gsp > 0) {
            gsp -= frc;
        }
        if (gsp < 0) {
            gsp += frc;
        }
        if (gsp < frc && gsp > -frc) {
            gsp = 0;    
        }
    }
    
    //Jumping
    if (this.app.keyboard.wasPressed(pc.KEY_W) && grounded === true) {
        ysp += jmp * Math.cos(angle * pc.math.DEG_TO_RAD);
        grounded = false;
    }
        
    //Movement Type
    if (grounded === true) {
        //Main
        xsp = gsp * Math.cos(angle * pc.math.DEG_TO_RAD);
        ysp = gsp * Math.sin(angle * pc.math.DEG_TO_RAD);
        
        //Slope Factor
        gsp -= slope * Math.sin(angle * pc.math.DEG_TO_RAD);
    }
    if (grounded === false) {
        gsp = xsp;
        //Gravity
        ysp -= grv;
        if (ysp < -400) { ysp = -400; }
        
        //Air Movement
        if (this.app.keyboard.isPressed(pc.KEY_RIGHT)) {
            xsp += air;
            goingRight = true;
        }
        if (this.app.keyboard.isPressed(pc.KEY_LEFT)) {
            xsp -= air;
            goingRight = false;
        }
        
        //Air Drag
        if (ysp > 0 && ysp < 4) {
            if (Math.abs(xsp) >= 1.25) { xsp = xsp * 0.96875; }    
        }
    }
};

PlayerController.prototype.onGrounded = function() {
    //Ground Check
    if (checkGround === true) {
        grounded = true;
    }
    if (checkGround === false) {
        grounded = false;
    }
};

PlayerController.prototype.onCollisionEnd = function(other) {
    //Ground Check
    if (other.tags.has('ground')) {
        checkGround = false;
    }     
};

PlayerController.prototype.onContact = function(result) {
    //Second Ground Check
    if (result.other.tags.has('ground')) {
        checkGround = true;
        angle = result.other.getEulerAngles().z;
    } 
};

Link To Editor: https://playcanvas.com/editor/scene/944932

Hey! You can use apply force too to implement a feature of jump. You can use the following code to implement it. Just replace the following W pressed condition with the following code and it will work.

//Jumping
    if (this.app.keyboard.wasPressed(pc.KEY_W) && grounded === true) {
        var forwardVector=new pc.Vec3(0,0,0);
        var appliedForce=new pc.Vec3(0,0,0);
        // ysp += jmp * Math.cos(angle * pc.math.DEG_TO_RAD);
        this.tempY = 0;
        forwardVector = this.entity.up;
        this.tempY += forwardVector.y;
        
        appliedForce.set(0, this.tempY, 0).normalize().scale(2000);
        this.entity.rigidbody.applyForce(appliedForce);
        grounded = false;
    }
1 Like

You can also check the first player example on the engine repo, it implements jumping:

https://playcanvas.github.io/#camera/first-person.html

I’ll try it later. I think there’s a chance it might not work, and I’m pretty sure I know the reason why.

I tried that in your project and it worked :confused:

Hmm, ok. I’ll try it now.

The player does jump. But the problem is still the same. The player just sort of teleports up and drops down rather than going up naturally.

I guess then you have to apply impulse on it and change the movement code accordingly because i am afraid there is no other way you can apply force up naturally.

I have figured out what the problem was. The jump works much better now.

1 Like

Great, can you post your solution so that others can learn from it please?

1 Like