Navigating with Three.JS FPS controls by moving left and right

Currently, I am working on a demo to check player controls for a FPS game. The camera rotation is controlled by the mouse, and the player can move using W-A-S-D keys. However, I am facing an issue with implementing movement left and right relative to the direction of the camera.

I am utilizing THREE.JS along with PhysiJS (Physics engine) in my project.

Below is a snippet of the code I am currently using...

    // Direction the camera is pointing
    var cameraLookVector = this.controls.getDirection(this.vDirection);         
                
    // Player Movement
    this.v = new THREE.Vector3(0,0,0);
    if(keyboard.pressed("W")) { // Move forward
        this.v.x -= cameraLookVector.x * (Player.SPEED * delta * this.q); // Working perfectly
        this.v.z -= cameraLookVector.z * (Player.SPEED * delta * this.q);
    }
    if(keyboard.pressed("A")) { // Move left
        // Currently setting position based on world coordinates instead of camera direction
        this.v.x -= Player.SPEED * delta * this.q;
        /* Tried alternatives without success
        this.v.x -= Math.cos(cameraLookVector * (Math.PI/180)) * (Player * delta * this.q);
        this.v.z -= Math.sin(cameraLookVector * (Math.PI/180)) * (Player * delta * this.q);
        */
    }
    if(keyboard.pressed("S")) { // Move backward
        this.v.x -= cameraLookVector.x * (Player.SPEED * delta * this.q); // Works fine
        this.v.z -= cameraLookVector.z * (Player.SPEED * delta * this.q);
    }
    if(keyboard.pressed("D")) { // Move right
        // Currently setting position based on world coordinates instead of camera direction
        this.v.x += Player.SPEED * delta * this.q;
    }
    
    this.bodyMesh.setLinearVelocity(this.v);

The current implementation of left and right controls updates the player's position in relation to the world, not the camera direction. This results in the player moving in different directions based on camera rotation. I aim to update the player's left and right movement relative to the camera direction so that they always appear to be strafing left or right from the player's perspective.

Any assistance provided would be greatly appreciated!

Answer №1

An alternative method for calculating a vector in either the left or right direction with less computational intensity involves using the cross-product of the cameraLookVector and a fixed "up" direction. This approach assumes that the cameraLookVector is never parallel to this "up" direction.

In the scenario depicted, we can designate the b vector as the camera's viewing direction, a as a constant upward vector, and a x b as a non-normalized vector pointing towards the desired leftward strafe direction.

const vectorUp = new THREE.Vector3(0, 1, 0);

// Calculate leftward vector
const coefficient = Player.SPEED * delta * this.q;

this.v.copy(new THREE.Vector3().crossVectors(vectorUp, cameraLookVector).normalize().multiplyScalar(coefficient));

Answer №2

To achieve this, you can generate a fresh Vector3 and adjust it according to the rotation of the camera, assuming that you are able to access it programmatically.

let factor = Player.SPEED * delta * this.q;

// Calculate right vector
this.v.copy(new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion).multiplyScalar(factor));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Switch Object to WebElement or SearchContext in JavaScript

Looking for the best way to convert an Object to WebElement or SearchContext using JavaScript? In Java, casting as `(WebElement)` or `(SearchContext)` works fine. However, attempting the same in JavaScript with `as Webelement` or `as SearchContext` result ...

Having trouble finding module: Unable to locate 'fs' - yet another hurdle with NextJS

Trying to access a JSON file located one directory above the NextJS application directory can be tricky. In a standard JavaScript setup, you might use the following code: var fs = require('fs'); var data = JSON.parse(fs.readFileSync(directory_pat ...

The Rails text area fails to load through JavaScript when a line break is detected

My comment form has a feature that displays the content of the text area using js. It functions properly unless a new line is entered in the text area, in which case it does not show up right away. However, after refreshing the page, the comment appears wi ...

The Toggle Functionality necessitates a double-click action

I'm currently working on implementing a menu that appears when scrolling. The menu consists of two <li> elements and has toggle functionality. Everything is functioning properly, except for the fact that the toggle requires two taps to activate ...

Looping through required fields in jQuery based on a CSS class

Is there a way to loop through required fields marked with <input class="required">? Currently, only the first input in the loop is being evaluated. How can I traverse the DOM using a loop to check all input boxes? Thank you for your help. While I ...

Can we use ToggleClass to animate elements using jQuery?

I have a section on my website where I want to implement an expand feature. I am currently using jQuery's toggleClass function to achieve this effect. jQuery('.menux').click(function() { jQuery(this).toggleClass('is-active&a ...

Tips on Selecting a Typed Value

When clicking on 'no_results_text' and it's not available in the list, I want to show the searched value from the alert. I have included an onclick method for 'no_results_text', so that the typed value is displayed in the alert. h ...

Cannot load JSON file from Visual Studio 2013

I am currently working on building a drag-able network diagram using d3.js, and I've come across an unusual issue. Whenever I try to run the page from Visual Studios 2013, I encounter the following error: "Unhandled exception at line 25, column 13 in ...

Shifting axios requests outside of the React Component

Do you think this approach in React could be considered an anti-pattern? How would you suggest improving it? In my project, I utilize an EventItem Component along with a separate helper file named EventHelper.js to manage all axios calls related to the co ...

The functionality of Bootstrap popover is not functioning properly

I'm trying to activate a popover when users hover their mouse over a div. Can I use a popover with a div, or am I missing something in my code? Here's what I have: <div class="grid-item content-text" data-toogle ="popover" data-content="Lorem ...

Creating a many-to-many relationship in Sequelize using a join table to insert data

I recently set up two models in sequelize with a many-to-many relationship. While Sequelize successfully created the join table, I am facing difficulties when trying to insert data into it. Despite going through the documentation section on associations ...

When you encounter an open response and need to resend it, simply click the "Send Again

After the discontinuation of Firebug, I find myself in need of two crucial functionalities that I used frequently. To replace these features, I am wondering if there are similar options available within the default Firefox Web Console. Previously, when ma ...

Populate an HTML table using a JavaScript array containing objects

Greetings, fellow coders! I am new to the coding world and this community, and despite my efforts in searching for a solution, I couldn't find exactly what I was looking for. So, here is my question: I have an array structured as follows: const arr ...

JavaScript TypeError - missing method issue

When I try to call this code, I am encountering a TypeError: player = new Player({name:''}); Player = MeteorModel.extend({ schema:{ name:{type:String,}, value:{} }, belongsTo:{ meteorCollection:'', methodName ...

What is the best way to activate multiple events within an overlapping area containing multiple divs at the same

How can I trigger events on same level divs that overlap in different areas? When there are multiple divs overlapping, only one of them gets triggered. Is there a way to trigger events on all overlapped same level divs? Here is an example code snippet: ...

updating the HTML DOM elements using JavaScript is not yielding any response

One way that I am trying to change the background of a div is by using a function. Below is an example of the html code I am working with: $scope.Background = 'img/seg5en.png'; document.getElementById("Bstyle").style.background = "url("+$scope.B ...

The checksum verification encountered an error during the installation process of the npm package weexpack

I am encountering an issue while trying to install weexpack. It seems that the sha1 checksum verification is failing. npm install -g weexpack npm ERR! code EINTEGRITY npm ERR! sha1-33w+1aJ3w/nUtdgZsFMR0QogCuY= integrity checksum failed when using sha1: w ...

Disable automatic browser scroll reset on inline onclick event

Currently, I am utilizing prototype to create an ajax request through an inline onclick on a link. The function is designed to display an element on the page and everything functions properly. However, there is an issue where the browser scroll bar reset ...

The EJS is throwing an error because it cannot define the property "round" on an undefined object

I'm currently delving into the realm of Node.js, using the "Secrets of Ninja" book as my guide. I've come across an EJS program in the book that I copied verbatim to run, but I encountered an error despite not making any modifications to the code ...

Building on the Vuejs3 and Vuex4 framework, create a conditional rendering feature that triggers upon

I have a unique setup where custom objects are used to hold child objects full of data. The child objects start with null values for all properties, allowing them to be filled with data from remote sources when referenced. This results in a lazy-loading sy ...