はじめに
Oculus Rift Advent Calendar 2018の14日目の記事です。
OculusといえばUnityやUE4による開発がメジャーですが、中にはブラウザ上でVRをやってみたい!という変態人たちも結構います。
しかし、いざ Aframe や React360(元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
とりあえずはBabel
と Linter / 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についてはこちらを参照するとわかりやすいかもしれません。