A-frame move forward in camera direction

后端 未结 1 1159
小蘑菇
小蘑菇 2021-01-14 09:52

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/

相关标签:
1条回答
  • 2021-01-14 10:27

    You could handle this in multiple ways.

    0) Vectors

    Simple and available in most 3D engines:

    • Grab the camera's forward vector / world direction
    • multiply it by the distance you want to move
    • add it to your position vector

    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:

    1) 2D - Polar Coordinates

    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.


    Theory is boring, so lets get to practice:

           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.

    2) 3D - Spherical coordinates

    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.

    0 讨论(0)
提交回复
热议问题