Is there any way to enable or disable cursor pointer for first person character?

Is there any way to enable or disable cursor pointer for first person character? I need to enable cursor pointer of this project. anyone please help me.

https://developer.playcanvas.com/en/tutorials/first-person-shooter-starter-kit/

Hello @meta_core,

You will have to comment out or delete this line of code inside firstPersonMovement script:

app.mouse.enablePointerLock();

image

3 Likes

Can you tell me please the specific part where locate in following code ?

editor link : PlayCanvas | HTML5 Game Engine

////////////////////////////////////////////////////////////////////////////////

//         First Person Controls That Drive a Character Controller            //

////////////////////////////////////////////////////////////////////////////////

var FirstPersonView = pc.createScript('firstPersonView');

FirstPersonView.attributes.add('camera', {

    title: 'Camera',

    description: 'The camera controlled by this first person view. It should be a child of the entity to which this script is assigned. If no camera is assigned, the script will create one for you.',

    type: 'entity'

});

FirstPersonView.prototype.initialize = function() {

    var app = this.app;

    // Check the user has set a camera entity for the FPS view

    if (!this.camera) {

        // If not look for a chile of the character controller called 'Camera'

        this.camera = this.entity.findByName('Camera');

        if (!this.camera) {

            // Still don't have a camera so just create one!

            this.camera = new pc.Entity('FPS Camera');

            this.camera.addComponent('camera');

        }

    }

    this.x = new pc.Vec3();

    this.z = new pc.Vec3();

    this.heading = new pc.Vec3();

    this.magnitude = new pc.Vec2();

    this.azimuth = 0;

    this.elevation = 0;

    // Calculate camera azimuth/elevation

    var temp = this.camera.forward.clone();

    temp.y = 0;

    temp.normalize();

    this.azimuth = Math.atan2(-temp.x, -temp.z) * (180 / Math.PI);

    var rot = new pc.Mat4().setFromAxisAngle(pc.Vec3.UP, -this.azimuth);

    rot.transformVector(this.camera.forward, temp);

    this.elevation = Math.atan(temp.y, temp.z) * (180 / Math.PI);

    this.forward = 0;

    this.strafe = 0;

    this.jump = false;

    this.cnt = 0;

    app.on('firstperson:forward', function (value) {

        this.forward = value;

    }, this);

    app.on('firstperson:strafe', function (value) {

        this.strafe = value;

    }, this);

    app.on('firstperson:look', function (azimuthDelta, elevationDelta) {

        this.azimuth += azimuthDelta;

        this.elevation += elevationDelta;

        this.elevation = pc.math.clamp(this.elevation, -90, 90);

    }, this);

    app.on('firstperson:jump', function () {

        this.jump = true;

    }, this);

};

FirstPersonView.prototype.postUpdate = function(dt) {

    // Update the camera's orientation

    this.camera.setEulerAngles(this.elevation, this.azimuth, 0);

    // Calculate the camera's heading in the XZ plane

    this.z.copy(this.camera.forward);

    this.z.y = 0;

    this.z.normalize();

    this.x.copy(this.camera.right);

    this.x.y = 0;

    this.x.normalize();

    this.heading.set(0, 0, 0);

    // Move forwards/backwards

    if (this.forward !== 0) {

        this.z.scale(this.forward);

        this.heading.add(this.z);

    }

    // Strafe left/right

    if (this.strafe !== 0) {

        this.x.scale(this.strafe);

        this.heading.add(this.x);

    }

    if (this.heading.length() > 0.0001) {

        this.magnitude.set(this.forward, this.strafe);

        this.heading.normalize().scale(this.magnitude.length());

    }

    if (this.jump) {

        this.entity.script.characterController.jump();

        this.jump = false;

    }

    this.entity.script.characterController.move(this.heading);

    var pos = this.camera.getPosition();

    this.app.fire('cameramove', pos);

};

////////////////////////////////////////////////////////////////////////////////

//  FPS Keyboard Controls (Movement Only - Work Alongside Mouse Look Script)  //

////////////////////////////////////////////////////////////////////////////////

var KeyboardInput = pc.createScript('keyboardInput');

KeyboardInput.prototype.initialize = function() {

    var app = this.app;

    var updateMovement = function (keyCode, value) {

        switch (keyCode) {

            case 38: // Up arrow

            case 87: // W

                app.fire('firstperson:forward', value);

                break;

            case 40: // Down arrow

            case 83: // S

                app.fire('firstperson:forward', -value);

                break;

            case 37: // Left arrow

            case 65: // A

                app.fire('firstperson:strafe', -value);

                break;

            case 39: // Right arrow

            case 68: // D

                app.fire('firstperson:strafe', value);

                break;

        }

    };

    var keyDown = function (e) {

        if (!e.repeat) {

            updateMovement(e.keyCode, 1);

            if (e.keyCode === 32) { // Space

                app.fire('firstperson:jump');

            }

        }

    };

    var keyUp = function (e) {

        updateMovement(e.keyCode, 0);

    };

    // Manage DOM event listeners

    var addEventListeners = function () {

        window.addEventListener('keydown', keyDown, true);

        window.addEventListener('keyup', keyUp, true);

    };

    var removeEventListeners = function () {

        window.addEventListener('keydown', keyDown, true);

        window.addEventListener('keyup', keyUp, true);

    };

    this.on('enable', addEventListeners);

    this.on('disable', removeEventListeners);

   

    addEventListeners();

};

////////////////////////////////////////////////////////////////////////////////

//                         FPS Mouse Look Controls                            //

////////////////////////////////////////////////////////////////////////////////

var MouseInput = pc.createScript('mouseInput');

MouseInput.prototype.initialize = function() {

    var app = this.app;

    var canvas = app.graphicsDevice.canvas;

    var mouseDown = function (e) {

        if (document.pointerLockElement !== canvas && canvas.requestPointerLock) {

            canvas.requestPointerLock();

        }

    };

    var mouseMove = function (e) {

        if (document.pointerLockElement === canvas) {

            var movementX = event.movementX || event.webkitMovementX || event.mozMovementX || 0;

            var movementY = event.movementY || event.webkitMovementY || event.mozMovementY || 0;

            app.fire('firstperson:look', -movementX / 5, -movementY / 5);

        }

    };

    // Manage DOM event listeners

    var addEventListeners = function () {

        window.addEventListener('mousedown', mouseDown, false);

        window.addEventListener('mousemove', mouseMove, false);

    };

    var removeEventListeners = function () {

        window.removeEventListener('mousedown', mouseDown, false);

        window.removeEventListener('mousemove', mouseMove, false);

    };

    this.on('enable', addEventListeners);

    this.on('disable', removeEventListeners);

   

    addEventListeners();

};

// Utility function for both touch and gamepad handling of deadzones

// Takes a 2-axis joystick position in the range -1 to 1 and applies

// an upper and lower radial deadzone, remapping values in the legal

// range from 0 to 1.

function applyRadialDeadZone(pos, remappedPos, deadZoneLow, deadZoneHigh) {

    var magnitude = pos.length();

 

    if (magnitude > deadZoneLow) {

        var legalRange = 1 - deadZoneHigh - deadZoneLow;

        var normalizedMag = Math.min(1, (magnitude - deadZoneLow) / legalRange);

        var scale = normalizedMag / magnitude;

        remappedPos.copy(pos).scale(scale);

    } else {

        remappedPos.set(0, 0);

    }

}

////////////////////////////////////////////////////////////////////////////////

//                 Dual Virtual Stick FPS Touch Controls                      //

////////////////////////////////////////////////////////////////////////////////

var TouchInput = pc.createScript('touchInput');

TouchInput.attributes.add('deadZone', {

    title: 'Dead Zone',

    description: 'Radial thickness of inner dead zone of the virtual joysticks. This dead zone ensures the virtual joysticks report a value of 0 even if a touch deviates a small amount from the initial touch.',

    type: 'number',

    min: 0,

    max: 0.4,

    default: 0.3

});

TouchInput.attributes.add('turnSpeed', {

    title: 'Turn Speed',

    description: 'Maximum turn speed in degrees per second',

    type: 'number',

    default: 150

});

TouchInput.attributes.add('radius', {

    title: 'Radius',

    description: 'The radius of the virtual joystick in CSS pixels.',

    type: 'number',

    default: 50

});

TouchInput.attributes.add('doubleTapInterval', {

    title: 'Double Tap Interval',

    description: 'The time in milliseconds between two taps of the right virtual joystick for a double tap to register. A double tap will trigger a jump.',

    type: 'number',

    default: 300

});

TouchInput.prototype.initialize = function() {

    var app = this.app;

    var graphicsDevice = app.graphicsDevice;

    var canvas = graphicsDevice.canvas;

    this.remappedPos = new pc.Vec2();

   

    this.leftStick = {

        identifier: -1,

        center: new pc.Vec2(),

        pos: new pc.Vec2()

    };

    this.rightStick = {

        identifier: -1,

        center: new pc.Vec2(),

        pos: new pc.Vec2()

    };

   

    this.lastRightTap = 0;

    var touchStart = function (e) {

        e.preventDefault();

        var xFactor = graphicsDevice.width / canvas.clientWidth;

        var yFactor = graphicsDevice.height / canvas.clientHeight;

        var touches = e.changedTouches;

        for (var i = 0; i < touches.length; i++) {

            var touch = touches[i];

           

            if (touch.pageX <= canvas.clientWidth / 2 && this.leftStick.identifier === -1) {

                // If the user touches the left half of the screen, create a left virtual joystick...

                this.leftStick.identifier = touch.identifier;

                this.leftStick.center.set(touch.pageX, touch.pageY);

                this.leftStick.pos.set(0, 0);

                app.fire('leftjoystick:enable', touch.pageX * xFactor, touch.pageY * yFactor);

            } else if (touch.pageX > canvas.clientWidth / 2 && this.rightStick.identifier === -1) {

                // ...otherwise create a right virtual joystick

                this.rightStick.identifier = touch.identifier;

                this.rightStick.center.set(touch.pageX, touch.pageY);

                this.rightStick.pos.set(0, 0);

                app.fire('rightjoystick:enable', touch.pageX * xFactor, touch.pageY * yFactor);

               

                // See how long since the last tap of the right virtual joystick to detect a double tap (jump)

                var now = Date.now();

                if (now - this.lastRightTap < this.doubleTapInterval) {

                    app.fire('firstperson:jump');

                }

                this.lastRightTap = now;

            }

        }

    }.bind(this);

    var touchMove = function (e) {

        e.preventDefault();

        var xFactor = graphicsDevice.width / canvas.clientWidth;

        var yFactor = graphicsDevice.height / canvas.clientHeight;

       

        var touches = e.changedTouches;

        for (var i = 0; i < touches.length; i++) {

            var touch = touches[i];

            // Update the current positions of the two virtual joysticks

            if (touch.identifier === this.leftStick.identifier) {

                this.leftStick.pos.set(touch.pageX, touch.pageY);

                this.leftStick.pos.sub(this.leftStick.center);

                this.leftStick.pos.scale(1 / this.radius);

                app.fire('leftjoystick:move', touch.pageX * xFactor, touch.pageY * yFactor);

            } else if (touch.identifier === this.rightStick.identifier) {

                this.rightStick.pos.set(touch.pageX, touch.pageY);

                this.rightStick.pos.sub(this.rightStick.center);

                this.rightStick.pos.scale(1 / this.radius);

                app.fire('rightjoystick:move', touch.pageX * xFactor, touch.pageY * yFactor);

            }

        }

    }.bind(this);

    var touchEnd = function (e) {

        e.preventDefault();

        var touches = e.changedTouches;

        for (var i = 0; i < touches.length; i++) {

            var touch = touches[i];

            // If this touch is one of the sticks, get rid of it...

            if (touch.identifier === this.leftStick.identifier) {

                this.leftStick.identifier = -1;

                app.fire('firstperson:forward', 0);

                app.fire('firstperson:strafe', 0);

                app.fire('leftjoystick:disable');

            } else if (touch.identifier === this.rightStick.identifier) {

                this.rightStick.identifier = -1;

                app.fire('rightjoystick:disable');

            }

        }

    }.bind(this);

    // Manage DOM event listeners

    var addEventListeners = function () {

        canvas.addEventListener('touchstart', touchStart, false);

        canvas.addEventListener('touchmove', touchMove, false);

        canvas.addEventListener('touchend', touchEnd, false);

    };

    var removeEventListeners = function () {

        canvas.removeEventListener('touchstart', touchStart, false);

        canvas.removeEventListener('touchmove', touchMove, false);

        canvas.removeEventListener('touchend', touchEnd, false);

    };

    this.on('enable', addEventListeners);

    this.on('disable', removeEventListeners);

   

    addEventListeners();

};

TouchInput.prototype.update = function(dt) {

    var app = this.app;

   

    // Moving

    if (this.leftStick.identifier !== -1) {

        // Apply a lower radial dead zone. We don't need an upper zone like with a real joypad

        applyRadialDeadZone(this.leftStick.pos, this.remappedPos, this.deadZone, 0);

        var strafe = this.remappedPos.x;

        if (this.lastStrafe !== strafe) {

            app.fire('firstperson:strafe', strafe);

            this.lastStrafe = strafe;

        }

        var forward = -this.remappedPos.y;

        if (this.lastForward !== forward) {

            app.fire('firstperson:forward', forward);

            this.lastForward = forward;

        }

    }

    // Looking

    if (this.rightStick.identifier !== -1) {

        // Apply a lower radial dead zone. We don't need an upper zone like with a real joypad

        applyRadialDeadZone(this.rightStick.pos, this.remappedPos, this.deadZone, 0);

        var lookLeftRight = -this.remappedPos.x * this.turnSpeed * dt;

        var lookUpDown = -this.remappedPos.y * this.turnSpeed * dt;

        app.fire('firstperson:look', lookLeftRight, lookUpDown);

    }

};

////////////////////////////////////////////////////////////////////////////////

//                 Dual Analog Stick FPS Gamepad Controls                     //

////////////////////////////////////////////////////////////////////////////////

var GamePadInput = pc.createScript('gamePadInput');

GamePadInput.attributes.add('deadZoneLow', {

    title: 'Low Dead Zone',

    description: 'Radial thickness of inner dead zone of pad\'s joysticks. This dead zone ensures that all pads report a value of 0 for each joystick axis when untouched.',

    type: 'number',

    min: 0,

    max: 0.4,

    default: 0.1

});

GamePadInput.attributes.add('deadZoneHigh', {

    title: 'High Dead Zone',

    description: 'Radial thickness of outer dead zone of pad\'s joysticks. This dead zone ensures that all pads can reach the -1 and 1 limits of each joystick axis.',

    type: 'number',

    min: 0,

    max: 0.4,

    default: 0.1

});

GamePadInput.attributes.add('turnSpeed', {

    title: 'Turn Speed',

    description: 'Maximum turn speed in degrees per second',

    type: 'number',

    default: 90

});

GamePadInput.prototype.initialize = function() {

    var app = this.app;

    this.lastStrafe = 0;

    this.lastForward = 0;

    this.lastJump = false;

    this.remappedPos = new pc.Vec2();

   

    this.leftStick = {

        center: new pc.Vec2(),

        pos: new pc.Vec2()

    };

    this.rightStick = {

        center: new pc.Vec2(),

        pos: new pc.Vec2()

    };

    // Manage DOM event listeners

    var addEventListeners = function () {

        window.addEventListener("gamepadconnected", function(e) {});

        window.addEventListener("gamepaddisconnected", function(e) {});

    };

    var removeEventListeners = function () {

        window.removeEventListener("gamepadconnected", function(e) {});

        window.removeEventListener("gamepaddisconnected", function(e) {});

    };

    this.on('enable', addEventListeners);

    this.on('disable', removeEventListeners);

   

    addEventListeners();

};

GamePadInput.prototype.update = function(dt) {

    var app = this.app;

    var gamepads = navigator.getGamepads ? navigator.getGamepads() : [];

    for (var i = 0; i < gamepads.length; i++) {

        var gamepad = gamepads[i];

        // Only proceed if we have at least 2 sticks

        if (gamepad && gamepad.mapping === 'standard' && gamepad.axes.length >= 4) {

            // Moving (left stick)

            this.leftStick.pos.set(gamepad.axes[0], gamepad.axes[1]);

            applyRadialDeadZone(this.leftStick.pos, this.remappedPos, this.deadZoneLow, this.deadZoneHigh);

            var strafe = this.remappedPos.x;

            if (this.lastStrafe !== strafe) {

                app.fire('firstperson:strafe', strafe);

                this.lastStrafe = strafe;

            }

            var forward = -this.remappedPos.y;

            if (this.lastForward !== forward) {

                app.fire('firstperson:forward', forward);

                this.lastForward = forward;

            }

            // Looking (right stick)

            this.rightStick.pos.set(gamepad.axes[2], gamepad.axes[3]);

            applyRadialDeadZone(this.rightStick.pos, this.remappedPos, this.deadZoneLow, this.deadZoneHigh);

            var lookLeftRight = -this.remappedPos.x * this.turnSpeed * dt;

            var lookUpDown = -this.remappedPos.y * this.turnSpeed * dt;

            app.fire('firstperson:look', lookLeftRight, lookUpDown);

            // Jumping (bottom button of right cluster)

            if (gamepad.buttons[0].pressed && !this.lastJump) {

                app.fire('firstperson:jump');

            }

            this.lastJump = gamepad.buttons[0].pressed;

        }

    }

};

Hi @meta_core! Line 295 of the code above and line 180 of the actual script is related.

1 Like