a-frame のデモを触ってみる

# はじめに

以前、「手軽にVRで遊んでみたい。」と銘打って webVR の a-frame というフレームワークを少しいじってみました。

**a-frame に目をつけた理由は以下の通り**

- まず、webVR が特別なアプリのインストールを必要としない。
- PC・スマホなどブラウザを開くことができれば様々なデバイスで実行できる。
- 複雑なことをしないのならば html をちょっと書くだけで VR ができる。

ちなみに、前回言い忘れたが Ver.1.0.0 のメジャーアップデートで webXR に対応しているらしい。やったね。


というわけで、私は前回は a-frame の「Building a Basic Scene」にしたがってただの赤い箱を出力するところまではやったわけです。

```html
<html>
  <head>
    <script src="https://aframe.io/releases/1.0.1/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-box color="red" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box>
    </a-scene>
  </body>
</html>
```

<img width="888" alt="スクリーンショット 2020-03-18 11.51.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/f3a6d280-52a3-a25d-8b79-10d6fa86bb62.png">

`<head>` で a-frame を include して、`<body>`に`<a-scene>`という a-frame の全てを投入するタグを用意して、その中に`<a-box>`をおいただけ。

一応`<a-box>`に付いている各パラメーターの説明を書くと、

- `color="red"`:読んで字のごとく。色を設定できる。`#FFFFFF`みたいにカラーコードで指定するか`red`みたいにブラウザが対応している色の名前で指定できる。
- `position="0 2 -5"`:オブジェクトの位置指定。x(左右),y(上下),z(奥行き)の順。
- `rotation="0 45 45"`:オブジェクトの回転。ピッチ,ヨー,ロールの順。
- `scale="2 2 2"`:オブジェクトのサイズ。x(左右),y(上下),z(奥行き)の順。

これだとあまりに味気ないので、ガイドの続きにもう少ししたがっていきます。


# 画像をテクスチャにして貼る

```html
<a-scene>
  <a-box src="https://i.imgur.com/mYmmbrp.jpg" position="0 2 -5" rotation="0 45 45"
    scale="2 2 2"></a-box>

  <a-sky color="#222"></a-sky>
</a-scene>
```

`<img>`タグのように`src`に画像を指定すると`<a-box>`の、というかオブジェクトのテクスチャにできます。

また、都度画像を指定して読み込むのではなくasset様にして呼び出すこともできます。

```html
<a-scene>
  <a-assets>
    <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg">
  </a-assets>

  <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box>

  <a-sky color="#222"></a-sky>
</a-scene>
```


# 背景

```html
<a-scene>
  <a-box color="red" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box>

  <a-sky color="#222"></a-sky>
</a-scene>
```

`<a-sky>`というタグで背景を設定することができます。
正確には、このタグはVR空間を覆うように存在する大きな球の内側に色などを反映します。

なので、適当に360°画像を用意して

```html
<a-scene>
  <a-sky src="hogehoge_image"></a-sky>
</a-scene>

<!-- あるいは -->

<a-scene>
  <a-assets>
    <img id="backgroundimg" src="hogehoge_image">
  </a-assets>

  <a-sky src="#backgroundimg"></a-sky>
</a-scene>
```

とするだけで360°空間を作成できます。
公式デモの方でもイラストが用意されていますし、適当なところから360°画像を拝借してくれば簡単に空間の背景に設定できます。


# 床

```html
<a-scene>
  <a-plane rotation="-90 0 0"></a-plane>
</a-scene>
```

床を配置する専用のタグは存在せず、公式ガイドでも標準的なパネルを90°倒して床がわりにするように支持されています。

当然、`src`に画像を指定してテクスチャを貼れます。


# 光源
何も指定しなければデフォルトの光源が設定されるようなのですが、暗い背景を設定したのに光を反射するオブジェクトが強烈に白い、なんてこともあり得るので光源を設定します。

## 環境光

```html
<a-scene>
  <a-light type="ambient" color="#445451"></a-light>
</a-scene>
```

type を ambient と指定することで環境光を設定できます。
空間に存在する全てのオブジェクトが受ける光を設定します。

## スポット <a-light type="point">
```html
<a-scene>
  <a-light type="point" intensity="2" position="2 4 4"></a-light>
</a-scene>
```

type を point にするとスポットライトを設定できます。
蛍光灯の光や太陽光など、光源から直接向かってくる光はこちらで設定しましょう。
先ほどの環境光は、直接的でない光。例えば、森の中で太陽は木々に遮られているが視界が完全に真っ暗なわけではない。多方向からの反射光による明るさなどに使うと良いはずです。


# アニメーション

a-frame に組み込みのアニメーションシステムを使うことで html の記述のみでオブジェクトに簡単なアニメーションを設定することができます。

```html
<a-scene>
  <a-assets>
    <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg">
  </a-assets>

  <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"
         animation="property: object3D.position.y; to: 2.2; dir: alternate; dur: 2000; loop: true"></a-box>
</a-scene>
```

先ほどまでいじっていたマイ○クラフトの丸石みたいなテクスチャを貼ったboxを上下にフヨフヨさせます。
重要なのは　`animation=` 以下
3DオブジェクトのY軸を(初期配置である2から)2.2へ、2秒かけて、行ったり来たりする動きで、ループさせる。
という命令。htmlだけと言ったがちょっと露骨な命令を書いていく。
`dir: alternate;` とすることでフヨフヨ感を実現
`dir: normal;` とか `dir: reverse;` とかだとちょっと移動しては初期位置にボソンジャンプして戻ってくる。

# アクションの追加

さて、浮遊する丸石が3D空間に現れましたが、これではただのVR空間である意味がまだ薄い。
こちらから干渉できるようにします。

デモはお優しいことにコントローラーのついたVRデバイスを持っていない開発者向けにただのカーソルでのアクションを実装してくれています。

何も設定をしなければデフォルトでVR空間にカメラが設定されるのですが、カーソルをカメラの子要素とするために改めて定義します。

```html
<a-scene>
  <a-assets>
    <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg">
  </a-assets>

  <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"
         animation="property: object3D.position.y; to: 2.2; dir: alternate; dur: 2000; loop: true"></a-box>

  <a-camera>
    <a-cursor></a-cursor>
  </a-camera>
</a-scene>
```

画面中央に視点に追従する、FPSゲームの様なポイントが出てくるはずです。

さて、ここから script でイベントリスナーを実装していくこともできるが僕は手軽に行きたいのだ。
デモも「JavaScriptに慣れていない場合は、以下のイベントでのアニメーションにスキップしてください。」なんていっているのでお言葉に甘えよう。
(今回はスキップしただけでイベントリスナーでの実装方法も記載してあります。)

<a-box> にイベント発火する animation component を直接与えられます。

```html
<a-box
  src="#boxTexture"
  position="0 2 -5"
  rotation="0 45 45"
  scale="2 2 2"
  animation__position="property: object3D.position.y; to: 2.2; dir: alternate; dur: 2000; loop: true"
  animation__mouseenter="property: scale; to: 2.3 2.3 2.3; dur: 300; startEvents: mouseenter"
  animation__mouseleave="property: scale; to: 2 2 2; dur: 300; startEvents: mouseleave"></a-box>
```

`startEvents` を設定することでイベント発火します。
ポイントとしては複数の animation を設定する場合、アンダーバー2つを挟んでIDを指定してやる必要があること。


# 音声

四方八方から音がすればそれだけで広い空間を錯覚できる程度にVR体験には音声も重要です。
また、効果音とは別にいつでも聞こえるBGMを設定したいこともあるでしょう。

```html
<a-scene>
  <a-assets>
    <audio src="https://cdn.aframe.io/basic-guide/audio/backgroundnoise.wav" autoplay
      preload></audio>
  </a-assets>

  <!-- ... -->
</a-scene>
```

これが背景に一定の音を流す方法。音声ファイルはデモが提供しているノイズファイルです。
VR空間に不穏なノイズが走る様になりました。

せっかくのVR
前述の通り音にも位置をもたせたい場合 `<a-sound>` を使います。
用法は単純。音声元を座標を指定するだけ。

```html
<a-scene>
  <a-sound src="https://cdn.aframe.io/basic-guide/audio/backgroundnoise.wav" autoplay="true"
    position="-3 1 -4"></a-sound>
</a-scene>
```

先ほどの背景音と同じノイズなので `a-assets` の `<audio>` は削除してからVR空間に入ってください。

この設定だと少し左前方のあたりに設定されているはずです。
近づけば音量が大きく、離れれば小さくなります。


# テキスト表示

あとはテキストを空間に浮かせたりします。

```html
<a-entity
  text="value: Hello, A-Frame!; color: #BBB"
  position="-0.9 0.2 -3"
  scale="1.5 1.5 1.5"></a-entity>
```

ここまでデモを進めた人間なら個々の数値の説明は不要でしょう。
こんな内容で、こんな色のテキストが、この位置に、こんな大きさで表示される。
それだけ。

ちなみにこのテキスト正面からしかみることができず、裏側からだと見えなくなるらしい。

# a-frame inspector

ここまで色々基本的な項目を見てきたが、いちいち自分でこんなオブジェクトたちをコードから配置してVR空間を作るのはなかなかにコストが高い。

そこで a-frame inspector という便利な機能がある。
VR空間で `control` + `option` + `i` (mac) で表示される。
win なら `ctrl` + `alt` + `i`

<img width="1440" alt="スクリーンショット 2020-04-27 16.41.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/f9abaff6-af3a-bf76-ad7f-e59b2d1c8714.png">

ここで直接 3D オブジェクトを動かせる。
また、スポットライトや座標付き音声の位置などを動かすこともできる。

動かしたオブジェクトからは html を出力させることもでき、これをソースコードに反映させれば変更を恒常的に反映できる。

明示的に無効化しない限りはいつでも表示できる。
https://aframe.io/docs/1.0.0/introduction/visual-inspector-and-dev-tools.html

# デモURL 

https://aframe.io/docs/master/guides/building-a-basic-scene.html