🏈

8th Wall/A-frameで物理演算を使う

2022/10/02に公開

概要

  • 8th Wall/A-frameで物理演算を使う方法を紹介します
  • 少し古い記述ではCANNON.jsを使った実装が多いですが、CANNON.jsは将来的に非サポートになるようです
  • 今回はCANNON.jsの代わりとなとなるAmmo.jsを使った方法を紹介します

事前準備

まず、Ammo.jsを使えるように読み込みます
8th Wallの場合はhead.htmlに記載します

<script src="//cdn.8thwall.com/web/aframe/ammo.wasm.js"></script>
<script src="//cdn.8thwall.com/web/aframe/aframe-physics-system-4.0.1.min.js"></script>

<a-scene>タグでAmmo.jsを有効にします

<a-scene physics=" driver: ammo; debug: true; debugDrawMode: 1;">
  <!-- ... -->
</a-scene>

debug: trueにするとコライダーがどの範囲かなどデバッグ表示をすることができます
表示内容はdebugDrawModeで切り替えることができます
詳しくは公式のソースコードをご覧ください
https://github.com/InfiniteLee/ammo-debug-drawer/blob/0b2c323ef65b4fd414235b6a5e705cfc1201c765/AmmoDebugDrawer.js#L3

シーンのセットアップ

次にシーン上にオブジェクトを設置していきます
物理はammo-bodyammo-shapeのコンポーネントを追加することで動作します

<a-sphere
    position="0 3 0"
    color="red"
    ammo-body="type: dynamic"
    ammo-shape="type: sphere"
    >
</a-sphere>

<a-plane
    width="100"
    height="100"
    color="green"
    rotation="-90 0 0"
    ammo-body="type: static"
    ammo-shape="type: box"
    >
</a-plane>

ammo-bodyのTypeには3種類

  • dynamic(物理で動く)
  • static(動かないもの。dynamicのオブジェクトに影響を与える)
  • kinematic(物理では動かないがdynamicのオブジェクトに影響を与える)

があり、適切なものを設定します。なおデフォルトではdynamicが設定されています。
また、ammo-bodyでは重さや摩擦など他の物理的なパラメータを設定することができます
https://github.com/n5ro/aframe-physics-system/blob/master/AmmoDriver.md#ammo-body

ammo-shapeでは主にコライダーについての設定を行います
typeではコライダーの形を設定しますBox,Shereなどがあります
https://github.com/n5ro/aframe-physics-system/blob/master/AmmoDriver.md#ammo-shape

これで実行すると球が平面に当たって止まる物理が実装されていることが確認できます

力を加える

物体に力を加えるには関数を使う必要があります
まず、専用のコンポーネントを作成します
今回はaddforceという名前にしています
物体が生成されてから2000msec後に力を加えています

AFRAME.registerComponent('addforce', {
  init() {
    setTimeout(() => {
      const force = new Ammo.btVector3(-10,0,-10)
      this.el.body.applyCentralImpulse(force)
    }, 2000)
  },
})

8th Wallの場合、Ammo.btVector3に警告が出ますが無視しても動作します。

次に、先ほどのSphereにaddforceを追加します

<a-sphere
    addforce
    position="0 3 0"
    color="red"
    ammo-body="type: dynamic"
    ammo-shape="type: sphere"
    >
</a-sphere>

applyCentralImpulse以外にもapplyCentralForce
力を加える位置を指定するapplyForceなどがあります

Discussion