Edited at

Aframe + Vue を使ってOculusGoでWebVRを(なるべく簡単に)はじめる


はじめに

Oculus Rift Advent Calendar 2018の14日目の記事です。

OculusといえばUnityやUE4による開発がメジャーですが、中にはブラウザ上でVRをやってみたい!という変態人たちも結構います。

しかし、いざ AframeReact360(元ReactVR) のページを見ても「よくわからん・・・」という人が多く、断念している人が多いと思います。


Aframeって何?

ざっくり説明すると、ブラウザ上でHMDやCardboard対応の3Dレンダリングを簡単に行えるフレームワーク(内部的にはthree.jsのVR向けラッパーライブラリ群)です。 公式サイトのデモでブラウザ上で3Dモデルが表示されていると思います。



右下のアイコンをクリックすると



といったVRおなじみの画面が出てくると思います。


Aframeを実際に使用するまでがわかりにくい

公式サイトのインストール項目を見ると、英語慣れしていないと何をすればよいのかわかりにくいです。

ここの項目は開発スタイルごとのHowTo的な話が盛り込んであり、Aframeを使うという意味では下の2項目になります。


Include the JS Build

HTMLからビルド済みファイルを使用する方法です。scriptタグを使ってCDNからファイルをロードします。

<head>

<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
</head>


Install from npm

パッケージ管理ソフトのnpmからAframeを利用できるようにします。単純にモジュールをローカルに持ってくるだけで実際に使用する時はnodeモジュール利用時の作法を守っていく必要があります。(本来 npm init を行ったり、コマンドも npm install aframe --save としてモジュールをdependenciesに追加する必要があるのですが、説明がありません)

さらに項目の続きに


  • If you use npm, you can use angle, a command line interface for A-Frame. angle can initialize a scene template with a single command:

とあり、angle自体は簡易的なジェネレータで、テンプレートのpackage.jsonに記述されている構成が古い(webpackが2.7で止まってたり、babelの設定が含まれていない、など)ため、これを使ってAframeの開発することはおすすめしません。


Vue CLIを使ってみる

Vue CLIはVueのためのCLIですが、ジェネレータが優秀で、Webpack導入からBabelの設定まで設定してくれるため、Aframeの開発にも利用すると、開発が非常に楽になります。

とりあえず、Vue CLIのインストールは省略し、ジェネレータから作成する場合に、どのようにAframeを含めていくかやっていきます。


ジェネレータを使用してプロジェクト作成する

コンソールから以下のコマンドを打ちます。[任意のプロジェクト名]の箇所は自分の好きな名前をつけてください

vue create 任意のプロジェクト名

するとCLIの選択画面が出てくるので、下にカーソルをあわせてエンターキーを押します

Vue CLI v3.1.3

┌───────────────────────────┐
│ Update available: 3.2.1 │
└───────────────────────────┘
? Please pick a preset: (Use arrow keys)
default (babel, eslint)
❯ Manually select features

とりあえずはBabelLinter / Formatter にチェックがはいっていればOKです。エンターキーを押します

? Check the features needed for your project: 

❯◉ Babel
◯ TypeScript
◯ Progressive Web App (PWA) Support
◯ Router
◯ Vuex
◯ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing

ESLint + Standard configにカーソルを合わせてエンターキーを押します

? Pick a linter / formatter config: 

ESLint with error prevention only
ESLint + Airbnb config
❯ ESLint + Standard config
ESLint + Prettier

Lint on save にチェックが入っていればOKです。エンターキーを押します

? Pick additional lint features: (Press <space> to select, <a> to toggle all,

<i> to invert selection)
❯◉ Lint on save
◯ Lint and fix on commit

どちらでも良いのですが、個人的に In dedicated config files のほうが管理しやすいです。エンターキーを押します

? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use a

rrow keys)
❯ In dedicated config files
In package.json

これまでのプリセットを保存して別のプロジェクトで使い回すか?という内容が表示されます。 N をタイプしてエンターキーを押します

? Save this as a preset for future projects? (y/N) 

インストールが終了するまで待ちます。終わったらエディタでプロジェクトが入ったフォルダを開きます。以下の例ではvscodeを利用しています。

code 任意のプロジェクト名


Aframeを追加する

package.json があるプロジェクトのルートディレクトリに移動し、以下のコマンドを利用します。 パッケージ管理ソフトはyarnをおすすめします。

yarn add aframe


HelloWorldのコードを書いていく


(任意).eslintrc.js書き換え

Linterに手を加えます。好みの問題になるのですが、自分は普段このような設定を使っています。個々の設定の意味はESLintのルールを見ると良いでしょう

module.exports = {

root: true,
env: {
node: true,
},
'extends': [
'plugin:vue/essential',
'@vue/standard',
],
rules: {
'no-extra-semi': 'warn',
'no-undef': 'warn',
'quotes': ['error', 'single'],
'space-before-function-paren': ['error', 'never'],
'arrow-parens': 0,
'generator-star-spacing': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
},
parserOptions: {
parser: 'babel-eslint',
}


main.js書き換え

エントリーポイントになっているmain.jsを書き換えます。ファイルはsrcフォルダ内に入っています。

import 'aframe'を追加します。

import Vue from 'vue'

import App from './App.vue'

import 'aframe'

Vue.config.productionTip = false

new Vue({
store,
render: h => h(App)
}).$mount('#app')


App.vue書き換え

App.vueはルートVueインスタンスになるもので、ここに子になるコンポーネントが追加されていきます。同じくsrcフォルダ内にあります。

.vueファイルはテンプレートとスクリプトに別れており、template(html)の記述とjsのスクリプトを一つにまとめて書くことができます。

以下のように書き換えます。


<template>
<div id="app">
<aframe-window></aframe-window>
</div>
</template>

<script>
import AframeWindow from './components/AframeWindow'

export default {
name: 'app',
components: {
AframeWindow
}
}
</script>


HelloWorld.vue削除、AframeWindow.vueを新規作成

プロジェクトのルートディレクトリ以下から、 /src/components/HelloWorld.vue を削除、同じディレクトリにAframeWindow.vue を追加し、以下のよう内容にします


<template>
<div id="aframe-window">
<a-scene background="color: #ECECEC" embedded>
<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>
</a-scene>
</div>
</template>

<style>
@media only screen and (min-width: 640px) {
#aframe-window {
width: 640px;
height: 320px;
margin-left: auto;
margin-right: auto;
}
}

@media only screen and (max-width: 640px) {
#aframe-window {
width: 320px;
height: 320px;
margin-left: auto;
margin-right: auto;
}
}
</style>

<script>
export default {
name: 'AframeWindow'
}
</script>

これだけでAframeで開発を行う準備ができました。ここからVueやAframeの世界がまっています!


ローカルサーバーを起動する

上記ファイルを保存後、以下のコマンドを実行します

yarn run serve

起動に成功すれば以下のようなメッセージが出ます。

PCとOculusGoが同じルーターに繋がっている場合は Network の箇所のアドレスをOculus Goのブラウザで開くことができます。

スクリプトのファイルを保存するたび、自動ビルド+ブラウザリロードがかかるので、すばやく開発をしていくことができます。

 DONE  Compiled successfully in 1179ms

App running at:
- Local: http://localhost:8080/
- Network: http://192.168.***.***:8080/


Aframeの開発にVueを使うメリットは?

今回は時間がなくてあまり説明できませんでしたが、Aframeの開発にVueを用いる理由として、


  • AframeはDOM操作を意識しないとオブジェクト間の連携ができない。が、Aframe自体はDOM操作が得意ではない

  • VueはDOM操作を意識しなくてもDOM構造をいじることができるので、よりプログラマブルに記述できる

  • AframeとVueどちらもコンポーネント指向のため、書いたコードがどのように動くのか把握しやすい

  • Vue CLIがめんどくさい設定を殆どやってくれるので、初期設定で悩むことが少ない

など、お互いのメリットを生かして利用できるため、それぞれ別の目的のフレームワークでありながら、共存させることができ、とても強力な組み合わせになっています。

また、AframeもVueもドキュメントが豊富で、リファレンスに困ることが少ないというメリットもあります。

Vueについてはこちらを参照するとわかりやすいかもしれません。