🍎

【A-Frame】WebVRでの衝突判定(当たり判定)

2022/02/28に公開

株式会社palanのxR事業部でWebAR/VRの開発などしていますdamiと申します。
この記事ではA-Frame(v1.3.0)で衝突判定/当たり判定を実装する方法をまとめます。

物理演算の用意

衝突判定を取得するためには物理演算用のライブラリを併用します。
A-Frameで物理演算を使用する準備についてはこちらの記事をご覧ください。
https://zenn.dev/dami/articles/1456b68cd465aa

上の記事に合わせて物理演算のライブラリにはAmmo.jsを利用します。

TL;DR

  1. 当たり判定をとりたいオブジェクトにammo-body="emitCollisionEvents: true;"というプロパティを付与する
  2. お好きな名称でコンポーネントも付与する(今回はcolliderとする)

例:

<a-box
  collider
  ammo-body="type: dynamic; emitCollisionEvents: true;"
  ammo-shape="type: box"
  position="0.5 5 0.5"
></a-box>
  1. 2で付与したコンポーネントに対しcollidestartのイベントを登録
AFRAME.registerComponent("collider", {
  init: function () {
    const el = this.el;
    el.addEventListener("collidestart", function () {
      console.log("衝突");
      el.setAttribute("color", "red");
    });
  },
});
  1. できあがり

コード

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
    <script src="https://mixedreality.mozilla.org/ammo.js/builds/ammo.wasm.js"></script>
    <script src="//cdn.jsdelivr.net/gh/n5ro/aframe-physics-system@v4.0.1/dist/aframe-physics-system.min.js"></script>
    <script>
      AFRAME.registerComponent("collider", {
        init: function () {
          const el = this.el;
          el.addEventListener("collidestart", function () {
            console.log("衝突");
            el.setAttribute("color", "red");
          });
        },
      });
    </script>
  </head>

  <body>
    <a-scene vr-mode-ui="enabled:false" physics="driver: ammo; debug: true; ">
      <!-- 当たり判定を付与したオブジェクト -->
      <a-box
        collider
        ammo-body="type: dynamic; emitCollisionEvents: true;"
        ammo-shape="type: box"
        position="0.5 5 0.5"
      ></a-box>
	    
      <a-box
        position="0 0.5 0"
        ammo-body="type: static;"
        ammo-shape="type: box"
      ></a-box>
      <a-plane
        ammo-body="type: static"
        ammo-shape="type: box"
        position="0 0 0"
        rotation="-90 0 0"
        scale="7 5 1"
        color="#fff"
      ></a-plane>
      <a-sky color="#000990"></a-sky>
      <a-light
        type="directional"
        intensity="1.0"
        position="10 100 30"
      ></a-light>
      <a-light type="ambient" intensity="0.2" color="#404040"></a-light>
      <a-entity
        camera
        look-controls
        wasd-controls
        position="0 2 5"
      >
      </a-entity>
    </a-scene>
  </body>
</html>

参考

https://jgbarah.github.io/aframe-playground/physics-01/

Discussion