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

发布于 2025-01-11 20:23:01 字数 1658 浏览 0 评论 0原文

我希望我的 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/[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>

如果我移动相机,盒子也应该移动。 输出图像

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾其所爱 2025-01-18 20:23:02

最简单的方法是简单地重新调整父级:

 <!-- 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 创建控制器。假设我们想要:

  • 让相机跟随盒子
  • 让盒子随着相机旋转
  • 最好不是即时的,而是平滑的。

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

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

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


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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文