Physics issue with my movement script

It will not let me into the game, i cant click into it.
is there a problem with it?

var Movement = pc.createScript('Movement');

Movement.attributes.add('camera', {
    type: 'entity',
    description: 'Optional, assign a camera entity, otherwise one is created'
});

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

Movement.attributes.add('lookSpeed', {
    type: 'number',
    default: 0.25,
    description: 'Adjusts the sensitivity of looking'
});

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

    var app = this.app;

    // Listen for mouse move events
    app.mouse.on("mousemove", this._onMouseMove, this);

    // when the mouse is clicked hide the cursor
    app.mouse.on("mousedown", function () {
        app.mouse.enablePointerLock();
    }, this);
};

// update code called every frame
Movement.prototype.update = function(dt) {
    // If a camera isn't assigned from the Editor, create one
    if (!this.camera) {
        this._createCamera();
    }

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

    // Get camera directions to determine movement directions
    var forward = this.camera.forward;
    var right = this.camera.right;


    // movement
    var x = 0;
    var z = 0;

    // Use W-A-S-D keys to move player
    // Check for key presses
    if (app.keyboard.isPressed(pc.KEY_A) || app.keyboard.isPressed(pc.KEY_Q)) {
        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;
    }

    // use direction from keypresses to apply a force to the character
    if (x !== 0 && z !== 0) {
        force.set(x, 0, z).normalize().scale(this.power);
        this.entity.rigidbody.applyForce(force);
    }

    // update camera angle from mouse events
    this.camera.setLocalEulerAngles(this.eulers.y, this.eulers.x, 0);
};

Movement.prototype._onMouseMove = function (e) {
    // If pointer is disabled
    // If the left mouse button is down update the camera from mouse movement
    if (pc.Mouse.isPointerLocked() || e.buttons[0]) {
        this.eulers.x -= this.lookSpeed * e.dx;
        this.eulers.y -= this.lookSpeed * e.dy;
    }
};

Movement.prototype._createCamera = function () {
    // If user hasn't assigned a camera, create a new one
    this.camera = new pc.Entity();
    this.camera.setName("First Person Camera");
    this.camera.addComponent("camera");
    this.entity.addChild(this.camera);
    this.camera.translateLocal(0, 0.5, 0);
};

@Thebosser_24 Do you have a new link for your game? I am not sure what you mean by it will not let you into the game. Or are you trying the tutorial? If so then once you get to the dashboard go ahead and fork the game and make it your own. You will be able to edit then.

here is the new link
i think there is a problem with pointerlock
https://playcanvas.com/editor/scene/1571468

Hi @Thebosser_24! The problem is the name of the script. Please keep in mind, renaming a script has some consequences. For now you have to remove the script from your player entity and add it again.

1 Like

i have deleted it of the player
i realized i named the camera wrong, now i gotta fix him falling over :laughing:
and nothing connects to the camrea via Child

@Thebosser_24 Hi… I really do like the fact that you are doing your best to learn as much as you can. I am wondering if it would be a better start for you to start with a solid base. It would be good to start with this First Person Tutorial:

First Person Movement | Learn PlayCanvas

You can open this in the editor and fork this project. It will automatically give you FPS and a good start. You can then remove some of the asset items in the scene and add all of your own.

2 Likes

I have a first person script ready with walking, running, jumping and crouching.

You just have to set it up properly.

here is the script.



FirstPersonMovementV2.attributes.add('camera', {
    type: 'entity',
    description: 'Optional, assign a camera entity, otherwise one is created'
});

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

FirstPersonMovementV2.attributes.add('powerRun', {
    type: 'number',
    default: 2500,
    description: 'Adjusts the speed of player running'
});

FirstPersonMovementV2.attributes.add('powerCrouching', {
    type: 'number',
    default: 2000,
    description: 'Adjusts the speed of player movement when crouching'
});

FirstPersonMovementV2.attributes.add('lookSpeed', {
    type: 'number',
    default: 0.25,
    description: 'Adjusts the sensitivity of looking'
});

FirstPersonMovementV2.attributes.add('cameraHeight', {
    type: 'number',
    default: 0.5,
    description: 'Adjusts the Y position of the camera'
});
FirstPersonMovementV2.attributes.add('cameraSmoothingUp', {
    type: 'number',
    default: 0.25,
    description: 'Camera smooth amount for crouching'
});
FirstPersonMovementV2.attributes.add('cameraSmoothingDown', {
    type: 'number',
    default: 0.15,
    description: 'Camera smooth amount for crouching'
});

FirstPersonMovementV2.attributes.add('playerHeight', {
    type: 'number',
    default: 2.0,
    description: 'Adjusts the Y position of the camera'
});

FirstPersonMovementV2.attributes.add('debug', {
    type: 'boolean',
    default: false,
    description: 'Debug player movement'
});


// initialize code called once per entity
FirstPersonMovementV2.prototype.initialize = function() {
    
    
    // player child entities
    this.playerCollisionUpper = this.entity.findByName('player-collision-upper');
    this.playerCollisionLower = this.entity.findByName('player-collision-lower');
    this.playerModel = this.entity.findByName('player-model');
    
    // physics
    this.force = new pc.Vec3();
    this.eulers = new pc.Vec3();
    this.velocity = new pc.Vec3();
    this.crouchRaycastStart = new pc.Vec3();
    this.crouchRaycastEnd = new pc.Vec3();
    this.crouchRaycastLastAngle = 0;
    this.playerHeightCrouching = this.playerCollisionLower.collision.height;
    
    // player data
    this.playerSpawnPosition = this.entity.getPosition().clone();
    this.playerHeightCurrent = this.playerHeight;
    
    // states
    this.playerMoving = false;
    this.playerCrouching = false;
    this.playerJumping = false;
    this.playerRunning = false;

    // (optional) enable ccd, prevents rigidbody clipping through at high speeds
    const body = this.entity.rigidbody.body;
    body.setCcdMotionThreshold(1);
    body.setCcdSweptSphereRadius(0.1);
    body.setContactProcessingThreshold(0.1); 

    // camera
    this.cameraHeightCurrent = this.playerHeight * this.cameraHeight;
    
    // reparent camera if not a child of this entity
    if (this.entity.children.indexOf(this.camera) < 0) {
        this.camera.reparent( this.entity );
    }
    
    // debug
    this.debugThirdPerson = false; // toggle with 'X' key
    this.debugCamLocalPosition = new pc.Vec3();
    
    // events
    var app = this.app;
    
    // Listen for mouse move events
    app.mouse.on("mousemove", this._onMouseMove, this);

    // when the mouse is clicked hide the cursor
    app.mouse.on("mousedown", function () {
        app.mouse.enablePointerLock();
    }, this);

    // Check for required components
    if (!this.entity.collision) {
        console.error("First Person Movement script needs to have a 'collision' component");
    }

    if (!this.entity.rigidbody || this.entity.rigidbody.type !== pc.BODYTYPE_DYNAMIC) {
        console.error("First Person Movement script needs to have a DYNAMIC 'rigidbody' component");
    }
};





// update code called every frame
FirstPersonMovementV2.prototype.update = function(dt) {
    // If a camera isn't assigned from the Editor, create one
    if (!this.camera) {
        this._createCamera();
    }

    const force = this.force;
    const app = this.app;

    // Get camera directions to determine movement directions
    const forward = this.camera.forward;
    const right = this.camera.right;

    // movement
    let x = 0;
    let z = 0;

  
  
  
  


   






    // attributes
    let playerHeight = this.playerHeight;
    let power = this.power;
    let powerRun = this.power*3;

    // Movement mechanic: input
    // Use W-A-S-D keys to move player
    // Check for key presses
    
    
    
    
    if (app.keyboard.isPressed(pc.KEY_A) || app.keyboard.isPressed(pc.KEY_Q)) {
        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_SHIFT) && app.keyboard.isPressed(pc.KEY_W)) {
        
        x += forward.x;
        z += forward.z;

        power = powerRun;

        playerRunning = true;

       
  
    }
    else( 
        
        

     (playerRunning = false)

    );
   





    // Crouching mechanic: input
    if (app.keyboard.isPressed(pc.KEY_C)) {
        this.playerCrouching = true;
    }
    else if (this.playerCrouching) {
        // verify that there is room to stand up
        this.playerCrouching = this.raycastCrouch();   
    }
    
    // Crouching mechanic: apply
    if (this.playerCrouching) {
        playerHeight = this.playerHeightCrouching;
        power = this.powerCrouching;
    }
    this._updateCrouchMechanic( playerHeight, dt );
    
    // Movement mechanic: use direction from keypresses to apply a force to the character
    this.playerMoving = x !== 0 && z !== 0;
    if (this.playerMoving) {
        force.set(x, 0, z).normalize().scale(power);
        this.entity.rigidbody.applyForce(force);

       
    }

    // Running mechanic: run like mad
    this.playerRunning = x !== 0 && z !== 0;
    if (this.playerRunning) {
        force.set(x, 0, z).normalize().scale(powerRun);
        this.entity.rigidbody.applyForce(force);

       
    }
      

    // respawn when falling off map
    if (this.entity.getPosition().y < -60) {
        this.entity.rigidbody.teleport(0, -45, 0);
        this.entity.rigidbody.linearVelocity = this.velocity.set(0, 0, 0);
        this.entity.rigidbody.angularVelocity = new pc.Vec3(0, 0, 0);
    }

    // update camera
    this._updateCamera();
    
};
 

//
// Utilities
//

FirstPersonMovementV2.prototype._updateCrouchMechanic = function (heightTarget, dt) {

    // on height change
    let height = this.playerHeightCurrent;
    if (height !== heightTarget) {
        
        this.playerHeightCurrent = heightTarget;
        
        // (optional) instantly scale player model
        //this.playerModel.setLocalScale(1, heightTarget * 0.5, 1);
        
        // (optional) instantly offset player model. usefull for a crouching skeletal animations.
        //this.playerModel.setLocalPosition(0, (this.playerHeight - heightTarget) * 0.5, 0);
        
        // disable the upper collision body when crouching
        const upperCollisionEnabled = this.playerCollisionUpper.collision.enabled;
        if (this.playerCrouching) {
            if (upperCollisionEnabled) {
                this.playerCollisionUpper.collision.enabled = false; 
                this.playerCollisionUpper.enabled = false;
            }
        }
        else {
            if (!upperCollisionEnabled) {
                this.playerCollisionUpper.collision.enabled = true; 
                this.playerCollisionUpper.enabled = true;
            }
        }
    }
    
    // smoothing //
    
    // setup smoothing speed based on going up or down
    const smoothing = this.playerCrouching ? this.cameraSmoothingDown : this.cameraSmoothingUp;
    const t = Math.min(dt / smoothing, 1.0);
    
    /// update camera height smooth
    let cameraHeightTarget = heightTarget * this.cameraHeight * 0.5; // - this.playerHeight * 0.5;
    this.cameraHeightCurrent = pc.math.lerp(this.cameraHeightCurrent, cameraHeightTarget, t);
    
    /// (optional) update player model smooth, not ideal for skeletal animations.
    // scale
    let playerModelScaleY = this.playerModel.getLocalScale().y;
    playerModelScaleY = pc.math.lerp( playerModelScaleY, heightTarget * 0.5, t);
    this.playerModel.setLocalScale(1, playerModelScaleY, 1);
    // pos
    let playerModelPosY = this.playerModel.getLocalPosition().y;
    const scaleDelta = - playerModelScaleY;
    this.playerModel.setLocalPosition(0, -scaleDelta, 0);
    
};

// Raycast above player when in Crouching State
FirstPersonMovementV2.prototype.raycastCrouch = function() {
    
    const height = this.playerHeightCurrent;
    const radius = this.playerCollisionLower.collision.radius;
    const positionStart = this.playerCollisionLower.getPosition();
    const positionEntity = this.entity.getPosition();
    const padding = -0.15;  // add a little buffer to radius to cast from inside
    const precision = 9;    // amount of raycasters to cast
    
    // raycaster is colliding with rigidbody
    let colliding = false;
    
    // nifty optimization (starts angle at last hit angle)
    let angleOffset = this.crouchRaycastLastAngle;
    
    // make a circle of raycasters to cast above player
    for (let i = 0; i < precision; i ++) {
        
        // setup raycaster positions
        this.crouchRaycastStart.copy(positionStart);
        this.crouchRaycastEnd.copy(positionEntity);
        this.crouchRaycastEnd.y += this.playerHeight;
        
        // offset raycaster positions in a circle, index 0 reserved for center raycast
        let phi = 0;
        if (i !== 0) {
            const len = precision - 1;
            const slice = ((i - 1) / len);
            const pizza = 360 * pc.math.DEG_TO_RAD;
            phi = (pizza * slice) + angleOffset;
            const x = Math.cos( phi ) * (radius + padding);
            const z = Math.sin( phi ) * (radius + padding);
            this.crouchRaycastStart.x += x;
            this.crouchRaycastStart.z += z;
            this.crouchRaycastEnd.x += x;
            this.crouchRaycastEnd.z += z;
        }
        
        // raycast from center to to player height
        const result = this.app.systems.rigidbody.raycastFirst(this.crouchRaycastStart, this.crouchRaycastEnd);

        // is raycaster colliding with a rigidbody?
        colliding = result && result.entity.rigidbody;

        // debug: render line
        if (this.debugThirdPerson && this.debug) {
            this.app.renderLine(this.crouchRaycastStart, this.crouchRaycastEnd, colliding ? pc.Color.RED : pc.Color.GREEN);
        }
        
        // exit loop when collision success
        if (colliding) {
            this.crouchRaycastLastAngle = phi;
            break;   
        }
    }

    return colliding;
};

FirstPersonMovementV2.prototype._createCamera = function () {
    // If user hasn't assigned a camera, create a new one
    this.camera = new pc.Entity();
    this.camera.setName("First Person Camera");
    this.camera.addComponent("camera");
    this.entity.addChild(this.camera);
    this.camera.translateLocal(0, this.cameraHeight, 0);
};

FirstPersonMovementV2.prototype._updateCamera = function () {
    
    // update camera angle from mouse events
    this.camera.setLocalEulerAngles(this.eulers.y, this.eulers.x, 0);
    
    // update position
    this.camera.setLocalPosition(0, this.cameraHeightCurrent, 0);
    
    // debug: third person camera
    this.debugThirdPersonCamera();
};

//
// Input
//

FirstPersonMovementV2.prototype._onMouseMove = function (e) {
    // If pointer is disabled
    // If the left mouse button is down update the camera from mouse movement
    if (pc.Mouse.isPointerLocked() || e.buttons[0]) {
        this.eulers.x -= this.lookSpeed * e.dx;
        this.eulers.y -= this.lookSpeed * e.dy;
    }
};





type or paste code here

here is how to set it up.

https://playcanvas.com/editor/scene/1192176

Have a nice day!
=)

1 Like

Man, Thank you!