I\'m trying to make a component in A-frame that will move the player/camera in the direction the camera is facing. It should not move anywhere on the y plane, only in the x/
You could handle this in multiple ways.
Simple and available in most 3D engines:
The above steps within an a-frame component could look like this:
// inside an a-frame component
var player = document.querySelector("a-camera")
var direction = new THREE.Vector3();
window.addEventListener("keydown", (e) => {
if (e.code === "KeyR") {
// get the cameras world direction
this.el.sceneEl.camera.getWorldDirection( direction );
direction.multiplyScalar(0.1)
// faster than the below code - but getAttribute wont work
// player.object3D.position.add(direction)
var pos = player.getAttribute("position")
pos.x += direction.x
pos.y += direction.y // comment this to get 2D movement
pos.z += direction.z
player.setAttribute("position", pos);
}
})
each time "R" is pressed I do the mentioned steps and move forward. You can see how this works in this fiddle.
However you may want to do this a bit more "math-ish" way:
Mapping angles to 2D space is a job for the polar coordinate system !
We want to calculate x/y coordinates based on the camera rotation. The coordinate conversion looks like this:
x = r * cos(a)
y = r * sin(a)
where "r" is the step, the "a" is the angle.
var angle = player.getAttribute("rotation")
var x = 1 * Math.cos(angle.y * Math.PI / 180)
var y = 1 * Math.sin(angle.y * Math.PI / 180)
var pos = player.getAttribute("position")
pos.x -= y;
pos.z -= x;
player.setAttribute("position", pos);
It's quite simple - get the angle, calculate the shift, and set the new position.
Check it out here.
After all, this is a 3D space we're talking about.
The concept is the same - converting the camera angles into the x/y/z coordinates. The nifty trick here are the conversions from the spherical coordinate system.Three dimensions make it a bit more difficult, but the most confusing thing - the axis are different in the spherical system, than in the clipspace(used by a-frame):
Keeping that in mind the calculations should look like this:
// same component as 2D - just different calculations
var angle = player.getAttribute("rotation")
// the cameras 0 is actually 90' in the clipspace
let theta = (angle.x * Math.PI / 180) + Math.PI / 2
let fi = angle.y * Math.PI / 180
let r = 0.1
let z = Math.sin(theta) * Math.cos(fi) * r
let x = Math.sin(theta) * Math.sin(fi) * r
let y = Math.cos(theta) * r
var pos = player.getAttribute("position")
pos.x -= x;
pos.y -= y;
pos.z -= z;
player.setAttribute("position", pos);
Check it out in this fiddle.