Sumit Sharma
Sumit Sharma

Reputation: 1237

How can i get a Third person perspective for a model using Aframe?

I want my A-frame camera to be behind the model and work as a TPP. I want a model to sync with the camera and rotate and move where ever the camera is moving but it should not move if the camera is pointing up and down it should not look like the model is stuck on the camera.

<html>

<head>
  <script src="https://aframe.io/releases/0.7.1/aframe.min.js"></script>
  <script src="https://cdn.rawgit.com/donmccurdy/aframe-extras/v3.13.1/dist/aframe-extras.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/aframe-physics-components.min.js"></script>
  <script src="https://unpkg.com/aframe-event-set-component@^4.0.0/dist/aframe-event-set-component.min.js"></script>
  <script src="https://unpkg.com/super-hands@^3.0.1/dist/super-hands.min.js"></script>
</head>

<body>
  <a-scene physics="gravity: -9.8; restitution: 0.7;" antialias="true">
    <a-assets>
      <img id="ground-grass" src="grass.jpg" />
    </a-assets>
    <a-entity universal-controls="" camera kinematic-body=""
      position="-2.9021956210846644 1.5405810531492952 -3.927244596410301"></a-entity>
    <a-plane src="#ground-grass" scale="50 50 1" repeat=" 5 5 1" rotation="-90 0 0" static-body></a-plane>
    <a-box color="#AA0000" scale="2 2 2" position="-2.5 0.5 -7.5" static-body></a-box>
  </a-scene>
</body>

</html>

If I move the camera the box should also move. Output image

Upvotes: 2

Views: 975

Answers (1)

Piotr Adam Milewski
Piotr Adam Milewski

Reputation: 14645

The easiest way would be simple reparenting:

 <!-- The default aframe camera entity -->
 <a-camera>
   <!-- The object with the same transform as the camera + some offset -->
   <a-box position="0 0 -0.5"></a-box>
 </a-camera>

<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<a-scene>
  <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
  <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
  <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
  <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>

  <!-- "Player" -->
  <a-camera>
    <a-box position="0 -0.5 -0.65" scale="0.25 0.25 0.25" color="red"></a-box>
  </a-camera>

</a-scene>


A more complex, but flexible solution, would be creating a controller with javascript. Lets say we want to:

  • Make the camera follow the box
  • Make the box rotate with the camera
  • Preferably not instant, but smooth.

we could do it with a component like this:

<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/aframe-orbit-controls.min.js"></script>

<script>
  AFRAME.registerComponent("follow-box", {
    schema: {
      target: {type: "selector"}
    },
    tick: (function() {
      // create once
      const tmpv = new THREE.Vector3();

      return function(t, dt) {
        if (!this.data.target) return; // ignore when there is no target
        const target = this.data.target.getObject3D("mesh"); // get the mesh
        // track the position
        const position = target.getWorldPosition(tmpv); // get the world position
        this.el.object3D.position.lerp(tmpv, 0.5) // linear interpolation towards the world position
      }
    })()
  })
  AFRAME.registerComponent("rotate-with-camera", {
    tick: (function() {
      // create once
      const tmpq = new THREE.Quaternion();
      const tmpe = new THREE.Euler();
      
      return function(t, dt) {
        if (!this.el.sceneEl.camera) return; // ignore when there is no camera
        const cam = this.el.sceneEl.camera.el; // get the camera entity
        cam.object3D.getWorldQuaternion(tmpq); // get the world rotation
          tmpe.setFromQuaternion(tmpq, 'YXZ')
          // set attribute is necesarry for wasd-controls
        this.el.setAttribute("rotation", {x: 0, y: tmpe.y * 180 / Math.PI, z: 0 })
      }
    })()
  })
</script>
<a-scene>
  <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
  <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
  <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
  <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>

  <!-- camera "rig" -->
  <a-entity follow-box="target: #player" look-controls>
    <a-entity camera position="0 1.6 2"></a-entity>
  </a-entity>

  <!-- the "player" -->
  <a-box id="player" color="red" wasd-controls="speed: 35" rotate-with-camera></a-box>
  
  <a-sky color="#ECECEC"></a-sky>
</a-scene>

Here's a glitch of it working in aframe networked


The best way would be to re-use the orbit-controls, but afaik they won't work with wasd controls without some customization

Upvotes: 3

Related Questions