Weird shadow issues (first person player with model)

Video of shadow issue (the shadow is of the gas mask)

see camera settings:


The issue doesn’t persist in the editor, so I’m 99.9% sure it’s due to the camera settings or maybe my code… If anyone could identify it please let me know.
see the full first person code below:

var FirstPersonMovement = pc.createScript('firstPersonMovement');

FirstPersonMovement.attributes.add('head', {
    type: 'entity',
    description: 'Assign the head_1 entity for rotation'
});

FirstPersonMovement.attributes.add('bodyParts', {
    type: 'entity',
    array: true,
    description: 'Assign the body parts that should follow the cameras Y rotation'
});

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

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

FirstPersonMovement.attributes.add('jumpPower', {
    type: 'number',
    default: 350,
    description: 'Adjusts the jump force'
});

FirstPersonMovement.attributes.add('sprintMultiplier', {
    type: 'number',
    default: 1.5,
    description: 'Multiplier for sprint speed'
});

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

    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 a 'collision' component");
    }

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

    // Lock rotation to prevent the player from falling over
    this.entity.rigidbody.fixedRotation = true;

    // Get animation component
    this.animComponent = this.entity.anim;
    if (!this.animComponent) {
        console.error("First Person Movement script needs an 'anim' component");
    }

    // Track movement and animation states
    this.isMoving = false;
    this.isRunning = false;
    this.isJumping = false;

    // Listen for collision events to determine when the player is grounded
    this.entity.collision.on("collisionstart", this.onCollisionStart, this);
    this.entity.collision.on("collisionend", this.onCollisionEnd, this);

    // Listen for jump input
    app.keyboard.on(pc.EVENT_KEYDOWN, this._onKeyDown, this);
};

// update code called every frame
FirstPersonMovement.prototype.update = function (dt) {
    var force = this.force;
    var app = this.app;

    // Movement variables
    var forward = this.head.forward;
    var right = this.head.right;
    var x = 0;
    var z = 0;

    // Use W-A-S-D keys to move player
    if (app.keyboard.isPressed(pc.KEY_D)) {
        x -= right.x;
        z -= right.z;
    }

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

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

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

    // Check for sprint (Shift key)
    var isSprinting = app.keyboard.isPressed(pc.KEY_SHIFT) && (x !== 0 || z !== 0);
    var speedMultiplier = isSprinting ? this.sprintMultiplier : 1;

    // Apply force if moving
    if (x !== 0 || z !== 0) {
        force.set(x, 0, z).normalize().scale(this.power * speedMultiplier);
        this.entity.rigidbody.applyForce(force);

        // Update walking and running states
        this._setWalkState(!isSprinting);
        this._setRunState(isSprinting);
    } else {
        // If not moving, reset walking and running states
        this._setWalkState(false);
        this._setRunState(false);
    }

    // Update body parts to face the Y rotation of the head
    this.bodyParts.forEach(function (part) {
        part.setLocalEulerAngles(0, this.eulers.x, 0);
    }, this);
};

// Handle mouse movement
FirstPersonMovement.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; // Fixed inverted movement
        this.eulers.y = pc.math.clamp(this.eulers.y, -70, 80); // Clamp vertical rotation
        this.head.setLocalEulerAngles(this.eulers.y, this.eulers.x, 0);
    }
};

// Handle jump input
FirstPersonMovement.prototype._onKeyDown = function (e) {
    if (e.key === pc.KEY_SPACE && this.canJump) {
        this.entity.rigidbody.applyImpulse(0, this.jumpPower, 0);
        this.canJump = false;

        // Set jump animation state
        this._setJumpState(true);
    }
};

// Detect collision with the ground to enable jumping
FirstPersonMovement.prototype.onCollisionStart = function (result) {
    if (result.other && result.other.rigidbody) {
        this.canJump = true;

        // Reset jump animation state upon landing
        this._setJumpState(false);
    }
};

// Detect when the player leaves the ground
FirstPersonMovement.prototype.onCollisionEnd = function (result) {
    if (result.other && result.other.rigidbody) {
        this.canJump = false;
    }
};

// Set walking animation
FirstPersonMovement.prototype._setWalkState = function (isWalking) {
    if (this.animComponent) {
        this.animComponent.setBoolean('isWalk', isWalking);
        this.isMoving = isWalking;
    }
};

// Set running animation
FirstPersonMovement.prototype._setRunState = function (isRunning) {
    if (this.animComponent) {
        this.animComponent.setBoolean('isRun', isRunning);
        this.isRunning = isRunning;
    }
};

// Set jumping animation
FirstPersonMovement.prototype._setJumpState = function (isJumping) {
    if (this.animComponent) {
        this.animComponent.setBoolean('isJump', isJumping);
        this.isJumping = isJumping;
    }
};

Have you disabled shadows for the model?

1 Like

Yeah since the model shadows do the same thing.