javascript - 如何使用 Aframe 获得模型的第三人称视角?

标签 javascript three.js aframe webvr

我希望我的 A 框相机位于模型后面并充当 TPP。我想要一个模型与相机同步,并在相机移动的地方旋转和移动,但如果相机向上或向下指向,它不应该移动,它不应该看起来像模型被卡在相机上。

<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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4a2b2c382b272f673a223339232939672925273a25242f243e390a7b647b647a" rel="noreferrer noopener nofollow">[email protected]</a>/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>

如果我移动相机,盒子也会移动。 Output image

最佳答案

最简单的方法是简单的重新设置父级:

 <!-- 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>


一个更复杂但灵活的解决方案是使用 JavaScript 创建 Controller 。假设我们想要:

  • 让相机跟随盒子移动
  • 使盒子随相机旋转
  • 最好不是即时的,而是流畅的。

我们可以使用这样的组件来做到这一点:

<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script src="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f4959286959991d99b86969d80d9979b9a80869b9887b4c5dac6dac4" rel="noreferrer noopener nofollow">[email protected]</a>/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>

这是一个glitch它在 aframe 网络中工作


最好的方法是重复使用 orbit-controls ,但据我所知,如果没有一些自定义,它们将无法与 wasd 控件一起使用

关于javascript - 如何使用 Aframe 获得模型的第三人称视角?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71336022/

相关文章:

javascript - 使用 Greasemonkey 访问 Javascript 私有(private)变量

javascript - 如何从js向xml文件添加内容

javascript - 如何重新编译 Ionic 1.x 应用程序?

youtube - 没有iframe,Three.js,A帧的YouTube视频

javascript - A-Frame 组件之间的异步交互

javascript - 如果选择了父级,则选择子级单选按钮,反之亦然

javascript - Three.js setFromRotationMatrix 旋转超过 90 度时的奇怪行为

javascript - 三.JS | GLSL 通过场景纹理设置粒子颜色

three.js - 为什么 three.js 加载程序只需要某些浏览器的网络服务器?

ffmpeg - 将普通mp4转成180 VR