Advance according to a vector system

Hello, I’m working on game design. I’m trying to create a 2D vector system for movement (if it’s tilted), but it’s not working as I’d like. The forums haven’t addressed this question yet.

Here is the code for my 3D, considering that yellow represents the front of the figure.

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import * as THREE from 'three';

    export function loadervoit(scene) {
        const geometry = new THREE.BoxGeometry( 1, 2, 1 ); 
        const material = new THREE.MeshBasicMaterial( {color: 0x0068FF } ); 
        const cubeA = new THREE.Mesh( geometry, material ); 

        const geometryB = new THREE.BoxGeometry( 1, 1, 1 ); 
        const materialB = new THREE.MeshBasicMaterial( {color: 0xF7FF00 } ); 
        const cubeB = new THREE.Mesh( geometryB, materialB ); 
        cubeB.position.y = 1

        const groupvoit = new THREE.Group();
        groupvoit.add( cubeA );
        groupvoit.add( cubeB );
        
        scene.add( groupvoit );
        return groupvoit
    }

Here is the code to test the vector system.

const groupvoit = loadervoit(scene);


const speed = 0.01;

// Fonction pour mettre à jour la position de groupvoit en fonction de sa rotation
function updatePosition() {
    // Calculer la direction basée sur la rotation actuelle de groupvoit
    const direction = new THREE.Vector2(
        Math.sin(groupvoit.rotation.x),
        Math.cos(groupvoit.rotation.x)
    );

    // Crée un nouveau vecteur basé sur la direction et la vitesse
    const displacement = direction.clone().multiplyScalar(speed);

    // Met à jour la position de groupvoit en utilisant le vecteur de déplacement
    groupvoit.position.y += displacement.x;
    groupvoit.position.z += displacement.y;

    // Redessine ou rafraîchit la scène si nécessaire
    renderer.render(scene, camera);
}

Here is the code to test the movement system and then link the vector system to the button.


// debut vérif si touche est préssé
var keysPressed = {};
var alerte = false;

document.addEventListener("keydown", function (event) {
    keysPressed[event.key] = true;

    if (event.key === "z") {
        if (alerte === false) {
            alert(groupvoit.rotation.x);
            var result = groupvoit.rotation.x / 90;
            confirm(result);
            alerte = true;
        }
    } else if (event.key === "a") {
        alerte = false;
    } else if (event.key === "e") {
        groupvoit.rotation.x = 1.57;
    } else if (event.key === "ArrowUp") {
        groupvoit.position.y += 0.1;
    } else if (event.key === "ArrowDown") {
        groupvoit.position.y -= 0.1;
    } else if (event.key === "ArrowLeft") {
        if (groupvoit.rotation.x >= 6.29) {
            groupvoit.rotation.x = 0;
        }
        groupvoit.rotation.x += 0.1;
    } else if (event.key === "ArrowRight") {
        if (groupvoit.rotation.x <= 0) {
            groupvoit.rotation.x = 6.29;
        }
        groupvoit.rotation.x -= 0.1;
    } else if (event.key === " ") {
        console.log(groupvoit.position.x," ; ", groupvoit.position.y);
        console.log(groupvoit.rotation.x);
    }
    // Si la touche "Shift" gauche est enfoncée
    else if (event.key === "Shift") {
        window.location.href = "test/test.html";
    }
});


document.addEventListener("keyup", function (event) {
    // Réinitialisez l'état de la touche lorsque la touche est relâchée
    keysPressed[event.key] = false;
});
// fin vérif si touche est préssé

Knowing that I use Tween for the animations in Three.js.
The language used for the comments is French because I am French.
thanks for help

Can you explain what you’re trying to do and the intended result?

I’m trying to create a 2D vector system for movement (if it’s tilted), but it’s not working as I’d like

This makes no sense, you need to include more information (what do you mean by a 2d vector system? what is tilted? what is it doing now, and what do you want it to do instead)?

This makes the object move to the left and if I rotate it, its direction changes.
For the 2D vector system, it is a system that allows calculating the rotation x to then move the object along the z and y axes, making it move according to the object’s inclination.

thanks

You can transform a direction by the object.quaternion to get it in local space…
(This only works if the object is a child of scene, not if its a child of other nodes, but its quick and dirty)

let speed = .1;
myMoveVec3.set(0,0,speed ) //We want to move the object on its local Z axis..
myMoveVec3.applyQuaternion( thePlayer.quaternion );
thePlayer.position.add(myMoveVec)

( and you can chain this all like:
thePlayer.position.add(myMoveVec3.set(0,0,speed ).applyQuaternion(thePlayer.quaternion)
)

Or instead via its matrixWorld:
(This is more general and probably also reasonably fast, and should work even with nested objects, although it performs a vector normalize internally, but not a huge deal.)

myMoveVec3.set(0,0,speed ) //We want to move the object on its local Z axis..
myMoveVec3.transformDirection( thePlayer.matrixWorld );
thePlayer.position.add(myMoveVec)
1 Like

thanks for the help, but I didn’t understand the explanation and the programs given don’t work

If you can post your code in a codepen it will be easier to get help.

If manthrax’s solution doesn’t work, it’s most likely because your object isn’t a child of the scene, but is nested inside other objects which have their own rotations.

What his solution does is take the direction vector which is in the player’s local space, and then transform it with the player’s quaternion to get that direction in world space.

Imagine you are the player, put your hand in front of you. It’s now at coordinates (0,0,1) in your local space, and (0,0,1) in the world space. Now turn on yourself: your hand is still at (0,0,1) in your local space, but it’s at (1,0,0) in world space.
If you use (0,0,1) as your direction vector, you’ll always move the same direction regardless of your rotation (let’s say that’s like going north).
In order to go in the direction you’re facing (east), you need to transform that direction vector by applying your rotation to it.
You could write myMoveVec3.applyEuler( thePlayer.rotation ); to make it easier to understand. BUT THIS WILL ONLY WORK IF YOUR PLAYER IS A DIRECT CHILD OF THE SCENE (or if it’s nested inside of objects whose rotation is ( 0,0,0 ).

Worth reading more about local vs world space, it’s vital to understand this if you want to write graphics code. Luckily in THREE.js you can easily convert a vector from world to local space and vice versa with Object3D.worldToLocal, Object3D.localToWorld, and you also have Object3D.getWorldPosition, Obejct3D.getWorldDirection, Obejct3D.getWorldQuaternion etc

thanks for the help here is the github link without the modules.
sorry I’m not a mathematician

Hello I found the vector movement system “lerpVectors()” thanks to a code that I found on the internet the only problem I cannot get the ball to be aimed on the car for example a “lookAt()” I give you the link to the site

if anyone, how can a grouped mesh (not child and parent) be aimed at the direction of an object?

https://sbcode.net/threejs/vector3-lerp/