[SOLVED] Realistic player movement

So, I was making a first person movement script, but I have come to a problem. So, I need it to completely stop moving when the key is not pressed. For example when the W key is pressed you move forward, if not then you stop moving, like in normal FPS games. Here is my script if anyone can help me.

var PlayerMovement = pc.createScript('playerMovement');

PlayerMovement.attributes.add('camera', {
    type: 'entity',
    description: 'Optional. Assign a camera entity.'
});

PlayerMovement.attributes.add('power', {
    type: 'number',
    default: 2500,
    description: 'Adjust the speed of the player movement.'
});

PlayerMovement.attributes.add('lookSpeed', {
    type: 'number',
    default: 0.25,
    description: 'Adjusts the camera sensitivity.'
})

// initialize code called once per entity
PlayerMovement.prototype.initialize = function() {
    this.force = new pc.Vec3();
    this.eulers = new pc.Vec3();

    var app = this.app

    app.mouse.on("mousemove", this._onMouseMove, this);

    app.mouse.on("mousedown", function() {
        app.mouse.enablePointerLock();
    }, this)

    if (!this.entity.collision) {
        console.error("Collision componet not found in entity 'Player'")
    }

    if (!this.entity.rigidbody || this.entity.rigidbody.type !== pc.BODYTYPE_DYNAMIC) {
        console.error("Either Rigidbody componet is not found, or the Rigidbody is not correctly configured! It needs to be set to 'Dynamic'")
    }
};

// update code called every frame
PlayerMovement.prototype.update = function(dt) {
    if (!this.camera) {
        this._createCamera();
    }

    var force = this.force;
    var app = this.app;

    var forward = this.camera.forward;
    var right = this.camera.right;
    var up = this.camera.up;

    var x = 0;
    var z = 0;
    var y = 0;

    if (app.keyboard.isPressed(pc.KEY_A)) {
        x -= right.x
        z -= right.z
    }

    if (app.keyboard.isPressed(pc.KEY_D)) {
        x += right.x;
        z += right.z;
    }

    if (app.keyboard.isPressed(pc.KEY_W)) {
        x += forward.x;
        z += forward.z;
    }

    if (app.keyboard.isPressed(pc.KEY_S)) {
        x -= forward.x;
        z -= forward.z;
    }

    if (app.keyboard.isPressed(pc.KEY_SPACE)) {
        var pos = this.entity.getPosition();
        if (pos.y < 2) {
            y += up.y
        }
    }

    if (x !== 0 || z !== 0 || y !== 0) {
        force.set(x, y, z).normalize().scale(this.power);
        this.entity.rigidbody.applyForce(force)
    }

    this.camera.setLocalEulerAngles(this.eulers.y, this.eulers.x, 0);
};

PlayerMovement.prototype._onMouseMove = function (e) {
    if (pc.Mouse.isPointerLocked() || e.buttons[0]) {
        this.eulers.x -= this.lookSpeed * e.dx;
        this.eulers.y -= this.lookSpeed * e.dy;
    }
}

PlayerMovement.prototype._createCamera = function () {
    this.camera = new pc.Entity();
    this.camera.setName("FPC");
    this.entity.addChild(this.camera)
    this.camera.translateLocal(0, 0.5, 0)
}

As far I can see the script is already working like that.

Sorry, must have explained it wrong. Right now, it feels like you are walking on ice. I don’t want it to act like that.

You can try to set the friction of the rigidbody component to 1.

I̶t̶ s̶t̶i̶l̶l̶ d̶o̶e̶s̶n̶’t̶ s̶t̶o̶p̶ a̶s̶ f̶a̶s̶t̶ a̶s̶ I̶’d̶ l̶i̶k̶e̶ i̶t̶ t̶o̶o̶. I̶t̶ d̶o̶e̶s̶ s̶t̶o̶p̶ f̶a̶s̶t̶e̶r̶ t̶h̶o̶u̶g̶h̶
Never mind, I just set the linear damping to 0.99

1 Like

Have a look at our new FPS template for some inspiration! PlayCanvas 3D HTML5 Game Engine