I have a gltf model of my robot loaded in A-frame scene version 1.0.4. So far I can turn the robot about its x,y, z axes, but when I try to move it forward it still moves in its initial direction rather than the direction it's facing. I want to be able to control its movements with my keyboard without using any external libraries. I believe I have to use Quaternions, but I haven't figured out how to use them yet. Here is my A-frame code so far.
<a-scene id="myScene">
<a-entity environment="preset:forest;"></a-entity>
<a-entity gltf-model="#humanoid" id="robot" position="0 20 0" rotation="0 0 0"
scale="0.0001 0.0001 0.0001" static-body>
</a-entity>
</a-scene>
And here is my script
const robot = document.getElementById('robot');
const update = () => {
if (keys.forward) {
let {x,y,z} = robot.object3D.position;
let ry = robot.object3D.rotation.y;
z += Math.cos(ry * Math.PI/180)/12;
x += Math.sin(ry * Math.PI/180)/12;
robot.object3D.position.set(x, y, z);
}
else if (keys.backwards) {
let {x, y, z} = robot.object3D.position;
let ry = robot.object3D.rotation.y;
z -= Math.cos(ry * Math.PI/180)/10;
x -= Math.sin(ry * Math.PI/180)/10;
robot.object3D.position.set(x, y, z);
}
if (keys.turnLeft) {
let {x, y, z} = robot.getAttribute('rotation');
y += 0.25;
robot.setAttribute('rotation',{x,y,z});
}
else if (keys.turnRight) {
let {x, y, z} = robot.getAttribute('rotation');
y -= 0.25;
robot.setAttribute('rotation',{x,y,z});
}
}
let ry = robot.object3D.rotation.y; z += Math.cos(ry * Math.PI/180)/12;
Although a-frame
uses degrees for rotation, threejs
uses radians, so there is no need to convert them again:
const robot = document.querySelector("a-box")
document.body.addEventListener("keydown", (evt) => {
if (evt.key === 's') {
let {x,y,z} = robot.object3D.position;
let ry = robot.object3D.rotation.y;
z += Math.cos(ry)/12;
x += Math.sin(ry)/12;
robot.object3D.position.set(x, y, z);
} else if (evt.key === 'w') {
let {x, y, z} = robot.object3D.position;
let ry = robot.object3D.rotation.y;
console.log(ry)
z -= Math.cos(ry)/10;
x -= Math.sin(ry)/10;
robot.object3D.position.set(x, y, z);
}
if (evt.key === 'a') {
let {x, y, z} = robot.getAttribute('rotation');
y += 1;
robot.setAttribute('rotation',{x,y,z});
} else if (evt.key === 'd') {
let {x, y, z} = robot.getAttribute('rotation');
y -= 1;
robot.setAttribute('rotation',{x: x,y: y,z: z});
}
})
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 0 0" color="#4CC3D9">
<a-sphere radius="0.5" position="0 0 -1"></a-sphere>
</a-box>
<a-entity camera position="0 1.6 0"></a-entity>
</a-scene>
Same with getWorldDirection
:
const robot = document.querySelector("a-box")
const direction = new THREE.Vector3();
document.body.addEventListener("keydown", (evt) => {
if (evt.key === 's') {
// get robot direction
robot.object3D.getWorldDirection(direction);
// add a "speed" value
direction.multiplyScalar(0.1)
// add the new vector to the actual position
robot.object3D.position.add(direction)
} else if (evt.key === 'w') {
robot.object3D.getWorldDirection(direction);
direction.multiplyScalar(-0.1)
robot.object3D.position.add(direction)
}
if (evt.key === 'a') {
let {x, y, z} = robot.getAttribute('rotation');
y=y+1
robot.setAttribute('rotation',{x,y,z});
} else if (evt.key === 'd') {
let {x, y, z} = robot.getAttribute('rotation');
y=y-1
robot.setAttribute('rotation',{x: x,y: y,z: z});
}
})
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 0 0" color="#4CC3D9">
<a-sphere radius="0.5" position="0 0 -1"></a-sphere>
</a-box>
<a-entity camera position="0 1.6 0"></a-entity>
</a-scene>