ARコンテンツ作成勉強会
Oculus Quest1&2開発のはじめの一歩
もろもろのダウンロード
http://arfukuoka.lolipop.jp/quest2020/Sample.zip
自己紹介
氏名:吉永崇(Takashi Yoshinaga)
所属:Steampunk Digital株式会社
専門:医療支援AR,運動計測,3D Video
コミュニティ:ARコンテンツ作成勉強会
Twitterと勉強会ページで情報を発信しています
@AR_Fukuoka Googleで「AR勉強会」で検索
#AR_Fukuoka
ハッシュタグ
本題に入ります
開発ツール:A-Frameの概要
 Webブラウザ上でVRなどの3D表現を簡単に実現するフレームワーク
 HTMLのタグを書くだけで3Dオブジェクトを配置できる
 Firefox、Chrome、Edgeなど主要なブラウザがWebVR対応を表明
 Oculus QuestやHTC ViveなどのHMD、スマホVRにも対応
 上記Webブラウザやデバイスで動くのでコンテンツの公開・共有が容易
本日のゴール
https://youtu.be/an-aTYRQqgw
ハンズオン手順
Step1: サンプルを使ってA-Frame基本操作を覚える
Step2: CG見た目の調整を行い簡易VRコンテンツを作成
Step3: スクリプトを記述してインタラクションを実現する
ハンズオン手順
Step1: サンプルを使ってA-Frame基本操作を覚える
Step2: CG見た目の調整を行い簡易VRコンテンツを作成
Step3: スクリプトを記述してインタラクションを実現する
必要なもの
 Webブラウザ → コンテンツの体験や動作確認
 テキストエディタ → HTMLやjavascriptの記述
 Webサーバー → コンテンツの公開
サーバーに関して今回は・・・
 Glitchを利用 https://glitch.com/
 FacebookかGitHubのアカウントがあればOK
 サーバーとエディタの両方を無料で提供
この資料ではGlitch使用を前提に説明します
テンプレートコードの複製
https://glitch.com/~afrukuokaq-quest2-template
GET STARTED
テンプレートコードの複製
下にスクロール
テンプレートコードの複製
Remix Your Own
テンプレートの確認
index.htmlをクリックし、コードが表示されることを確認
index.html
テンプレートの確認
<html>
<head>
<meta charset="utf-8">
<title>Oculus Quest Demo</title>
<!--A-Frame-->
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<!--テレポート用コードのインポート-->
<script src="https://rawgit.com/fernandojsg/aframe-teleport-controls/master/
dist/aframe-teleport-controls.min.js"></script>
<!--物理演算用コードのインポート(メンテナンス終了)-->
<script src="//cdn.rawgit.com/donmccurdy/aframe-physics-system/v4.0.1/
dist/aframe-physics-system.min.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
A-Frameでの描画に関する記述
</a-scene>
</body>
</html>
テンプレートの確認
<html>
<head>
<meta charset="utf-8">
<title>Oculus Quest Demo</title>
<!--A-Frame-->
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<!--テレポート用コードのインポート-->
<script src="https://rawgit.com/fernandojsg/aframe-teleport-controls/master/
dist/aframe-teleport-controls.min.js"></script>
<!--物理演算用コードのインポート(メンテナンス終了)-->
<script src="//cdn.rawgit.com/donmccurdy/aframe-physics-system/v4.0.1/
dist/aframe-physics-system.min.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
A-Frameでの描画に関する記述
</a-scene>
</body>
</html>
Lesson01
テンプレートの確認
<html>
<head>
<meta charset="utf-8">
<title>Oculus Quest Demo</title>
<!--A-Frame-->
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<!--テレポート用コードのインポート-->
<script src="https://rawgit.com/fernandojsg/aframe-teleport-controls/master/
dist/aframe-teleport-controls.min.js"></script>
<!--物理演算用コードのインポート(メンテナンス終了)-->
<script src="//cdn.rawgit.com/donmccurdy/aframe-physics-system/v4.0.1/
dist/aframe-physics-system.min.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
A-Frameでの描画に関する記述
</a-scene>
</body>
</html>
Lesson01
テンプレートの確認
<a-scene background="color: #FAFAFA">
<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>
 基本図形はa-xxxタグで提供されている
https://aframe.io/docs/1.0.0/primi
tives/a-box.html (例:a-boxの詳細)
位置 回転 色
動作確認
①Show
②Next to The Code
動作確認
画面をクリック
回転:マウスでドラッグ
左右:[←][→]キー
前後:[↑][↓]キー
※前後左右は自分がどちらに動くかで考える
アレンジする場合(まだやらなくてOK)
タグ内の各パラメータ(Component)を編集してCGの見た目を調整
 position(位置):x y zの順にスペースで区切って指定
(0 1.25 -5)
位置 回転 色x y z座標
アレンジする場合(まだやらなくてOK)
タグ内の各パラメータ(Component)を編集してCGの見た目を調整
 position(位置):x y zの順にスペースで区切って指定
 rotation(傾き):各軸を中心とした回転で表現
 color(色):カラーコード等で指定
 他にも図形によって各種設定項目がある
X
Z
Y
(0 1.25 -5) 【設定項目の例】
radius(半径)
width(幅)
height(高さ)
depth(奥行)
src (画像など)原点
<a-scene background="color: #FAFAFA">
<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>
不要なオブジェクトの削除
 この後の演習のため板のみを残す
 HTMLの記述の中から不要なタグを削るだけ
 a-planeのみを残して削除してみましょう
<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>
Lesson02
<a-scene background="color: #FAFAFA">
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" color="#7BC8A4" shadow></a-plane>
</a-scene>
床を作ろう
Lesson03
①位置を変更
②widthとheightを変更
テクスチャをつけよう
テクスチャ画像
テクスチャをつけよう
①assets
②Upload an Asset
テクスチャをつけよう
①back.png
②開く
テクスチャをつけよう
クリック
テクスチャをつけよう
①Click
②何もないところをクリック
テクスチャをつけよう
index.htmlクリック
<a-scene background="color: #FAFAFA">
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" color="#7BC8A4" shadow></a-plane>
</a-scene>
テクスチャをつけよう
まずcolorを削除
<a-scene background="color: #FAFAFA">
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" src="画像のURL" shadow></a-plane>
</a-scene>
テクスチャをつけよう
Lesson04
画像のURLを指定
ハンズオン手順
Step1: サンプルを使ってA-Frame基本操作を覚える
Step2: CG見た目の調整を行い簡易VRコンテンツを作成
Step3: スクリプトを記述してインタラクションを実現する
ハンズオン手順
Step1: サンプルを使ってA-Frame基本操作を覚える
Step2: CG見た目の調整を行い簡易VRコンテンツを作成
Step3: スクリプトを記述してインタラクションを実現する
天井を作成
Copy & Paste
<a-scene background="color: #FAFAFA">
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" src="画像のURL" shadow></a-plane>
<a-plane position="0 5 0" rotation="90 0 0"
width="10" height="10" src="画像のURL" shadow></a-plane>
</a-scene> 位置と角度を変えて天井を作成
Lesson05
壁の作成
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" src="画像のURL"></a-plane>
<a-plane position="0 5 0" rotation="90 0 0"
width="10" height="10" src="画像のURL"></a-plane>
<a-plane position="0 2.5 -5" rotation="0 0 0"
width="10" height="5" src="画像のURL"></a-plane>
<a-plane position="0 2.5 5" rotation="0 180 0"
width="10" height="5" src="画像のURL"></a-plane>
<a-plane position="5 2.5 0" rotation="0 -90 0"
width="10" height="5" src="画像のURL"></a-plane>
<a-plane position="-5 2.5 0" rotation="0 90 0"
width="10" height="5" src="画像のURL"></a-plane>
同じ要領でコピー&ペーストを使って前後左右、合計4枚の壁を追加
Lesson06
URLの変更
クリック
URLの変更
ここを書き換える
URLの確認
https://XXXX-XXXX.glitch.me
Oculus Questで動作確認
アプリ
Oculus Questで動作確認
ブラウザ
Oculus Questで動作確認
自分のコンテンツのURL入力
or
Glitchにアクセス(次ページ)
Oculus Questで動作確認 (Glitchから)
ログインしておく
Oculus Questで動作確認 (Glitchから)
Dashboard
Oculus Questで動作確認 (Glitchから)
今回作っているコンテンツ
Oculus Questで動作確認 (Glitchから)
① Show
② In a New Window
Oculus Questで動作確認 (Glitchから)
VRをクリック
Oculus Questで動作確認 (Glitchから)
コントローラを追加
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" src="画像のURL" shadow> </a-plane>
<a-plane position="0 5 0" rotation="90 0 0"
width="10" height="10" src="画像のURL" shadow> </a-plane>
<a-plane position="0 2.5 -5" rotation="0 0 0"
width="10" height="5" src="画像のURL" shadow> </a-plane>
<a-plane position="0 2.5 5" rotation="0 180 0"
width="10" height="5" src="画像のURL" shadow> </a-plane>
<a-plane position="5 2.5 0" rotation="0 -90 0"
width="10" height="5" src="画像のURL" shadow> </a-plane>
<a-plane position="-5 2.5 0" rotation="0 90 0"
width="10" height="5" src="画像のURL" shadow> </a-plane>
<a-entity oculus-touch-controls="hand: left"> </a-entity>
<a-entity oculus-touch-controls="hand: right"> </a-entity> Lesson07
Oculus Questで動作確認の前に
必ずリロード
Oculus Questで動作確認
コントローラ
ハンズオン手順
Step1: サンプルを使ってA-Frame基本操作を覚える
Step2: CG見た目の調整を行い簡易VRコンテンツを作成
Step3: スクリプトを記述してインタラクションを実現する
ハンズオン手順
Step1: サンプルを使ってA-Frame基本操作を覚える
Step2: CG見た目の調整を行い簡易VRコンテンツを作成
Step3: スクリプトを記述してインタラクションを実現する
コントローラの挙動を追加
<a-plane position="0 2.5 -5" rotation="0 0 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-plane position="0 2.5 5" rotation="0 180 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-plane position="5 2.5 0" rotation="0 -90 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-plane position="-5 2.5 0" rotation="0 90 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-entity oculus-touch-controls="hand: left" input-listen> </a-entity>
<a-entity oculus-touch-controls="hand: right" input-listen> </a-entity>
コントローラのEntityに、ボタン操作時の挙動を記述したinput-listenを追加
↓
input-listenの具体的な挙動は独自に記述する(次のページで解説)
Lesson08
コントローラの挙動を追加
<script>
AFRAME.registerComponent('input-listen', {
init:function () { //初期化
} ,
tick: function () { //毎フレーム更新
}
});
</script>
<a-scene background="color: #FAFAFA">
<a-plane position="0 0 0" rotation="-90 0 0"
width="10" height="10" src="画像のURL" shadow></a-plane>
<!--中略-->
<a-entity oculus-touch-controls="hand: left" input-listen> </a-entity>
<a-entity oculus-touch-controls="hand: right" input-listen> </a-entity>
</a-scene>
Lesson09
コントローラの挙動を追加
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} , Lesson10
参考資料
https://aframe.io/docs/1.0.0/components/oculus-touch-controls.html
①Oculus-touch-controls
②Events
公式リファレンスでほかのボタンのイベント名を調べられます!
トリガーで弾を生成
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} ,
ここを編集
トリガーで弾を生成
this.el.addEventListener('triggerdown', function (e) {
//"this"はここでは、右/左のコントローラを意味する
//コントローラの3次元的な位置を取得
var point = this.object3D.getWorldPosition();
//ボールを生成
var ball = document.createElement('a-sphere');
ball.setAttribute('position', point);
ball.setAttribute('scale', '0.2 0.2 0.2');
ball.setAttribute('class', 'ball');
//a-sceneにアクセス
var scene = document.querySelector('a-scene');
//VR空間に弾を登場させる
scene.appendChild(ball);
}); Lesson11
Oculus Questで動作確認
VR空間に物理演算を適用
<script>
AFRAME.registerComponent('input-listen', {
init: function () {
//スペースの都合上省略
},
//毎フレーム更新 (今回は使わない)
tick: function () { }
});
</script>
<a-scene background="color: #FAFAFA">
<a-plane position="0 0 0" rotation="-90 0 0" width="10"
height="10" src="画像のURL" shadow></a-plane>
<!--スペースの都合上省略-->
</a-scene> Lesson12
<a-scene physics="gravity: 0; restitution: 0.9; "
background="color: #FAFAFA">
gravity→重力0、restitution →反発係数0.9
弾に物理演算を適用
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} ,
ここを編集
弾に物理演算を適用
this.el.addEventListener('triggerdown', function (e) {
//コントローラの3次元的な位置を取得
var point = this.object3D.getWorldPosition();
//ボールを生成
var ball = document.createElement('a-sphere');
ball.setAttribute('position', point);
ball.setAttribute('scale', '0.2 0.2 0.2');
ball.setAttribute('class', 'ball');
//物理演算を適用
ball.setAttribute('dynamic-body', 'shape: sphere; sphereRadius:0.2; ');
//a-sceneにアクセス
var scene = document.querySelector('a-scene');
//VR空間に弾を登場させる
scene.appendChild(ball);
});
Lesson12
dynamic-body→物理干渉を受けて動く
球が接触
すると反発
弾を撃つ
<a-scene physics="gravity: 0; restitution: 0.9;" background="color: #FAFAFA">
<!—スペースの都合上中略-->
<a-plane position="0 2.5 5" rotation="0 180 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-plane position="5 2.5 0" rotation="0 -90 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-plane position="-5 2.5 0" rotation="0 90 0"
width="10" height="10" src="画像のURL"> </a-plane>
<a-entity oculus-touch-controls="hand: left" raycaster input-listen>
</a-entity>
<a-entity oculus-touch-controls="hand: right" raycaster input-listen>
</a-entity>
</a-scene>
コントローラの向きを手軽に取得するためraycasterを追加 Lesson13
弾を撃つ
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} ,
ここを編集
弾を撃つ
this.el.addEventListener('triggerdown', function (e) {
//コントローラの3次元的な位置を取得
var point = this.object3D.getWorldPosition();
//ボールを生成
var ball = document.createElement('a-sphere');
ball.setAttribute('position', point);
ball.setAttribute('scale', '0.2 0.2 0.2');
ball.setAttribute('class', 'ball');
//物理演算を適用
ball.setAttribute('dynamic-body', 'shape: sphere; sphereRadius:0.2; ');
//a-sceneにアクセス
var scene = document.querySelector('a-scene');
//VR空間に弾を登場させる
scene.appendChild(ball);
});
このあとここに弾を発射するコードを追加
弾を撃つ
//コントローラのレイキャスターを取得
var dir = this.getAttribute("raycaster").direction;
//コントローラに対するレイの向きと力を設定
var force = new THREE.Vector3(dir.x, dir.y, dir.z);
force.multiplyScalar(2500);
//ボールにforceというプロパティを宣言して代入
ball.force = this.object3D.localToWorld(force);
//弾の準備ができたら上記で設定した力を加える
ball.addEventListener('body-loaded', function (e) {
var p = this.object3D.position;
var f = this.force;
this.body.applyForce(
new CANNON.Vec3(f.x, f.y, f.z),
new CANNON.Vec3(p.x, p.y, p.z)
);
});
Lesson14
衝突判定をつける
<a-scene physics="gravity: 0; restitution: 0.9; "
background="color: #FAFAFA">
<a-plane static-body position="0 0 0" --省略-- ></a-plane>
<a-plane static-body position="0 5 0" --省略-- ></a-plane>
<a-plane static-body position="0 2.5 -5" --省略-- ></a-plane>
<a-plane static-body position="0 2.5 5" --省略-- ></a-plane>
<a-plane static-body position="5 2.5 0" --省略-- ></a-plane>
<a-plane static-body position=“-5 2.5 0" --省略-- ></a-plane>
<a-entity oculus-touch-controls="hand: left" raycaster
input-listen> </a-entity>
<a-entity oculus-touch-controls="hand: right" raycaster
input-listen> </a-entity>
</a-scene>
Lesson15床・壁・天井(a-plane)にstatic-bodyを追加
発射!&壁で反発
弾を片付ける
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} ,
ここを編集
弾を片付ける
this.el.addEventListener('abuttondown', function (e) {
//全ての弾(クラス名=.ball)を取得
var els = document.querySelectorAll('.ball');
//ボールを一つ一つ削除
for (var i = 0; i < els.length; i++) {
els[i].parentNode.removeChild(els[i]);
}
});
Lesson16
障害物を作る
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="https://rawgit.com/fernandojsg/aframe-teleport-
controls/master/dist/aframe-teleport-controls.min.js"></script>
<script src="//cdn.rawgit.com/donmccurdy/aframe-physics-
system/v4.0.1/dist/aframe-physics-system.min.js"></script>
<!--箱を積み重ねた壁を作る-->
<script src="WallGenerator.js"></script>
</head>
<body>
<script>
window.onload=function(){
CreateBoxes();
}
AFRAME.registerComponent('input-listen', {
//スペースの都合上省略
});
</script>
//スペースの都合上以下省略
Lesson17
動作確認 (on PC)
障害物のリセット
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} ,
ここを編集
障害物のリセット
this.el.addEventListener('bbuttondown', function (e) {
//全ての箱(クラス名=.box)を取得
var els=document.querySelectorAll('.box');
for (var i = 0; i < els.length; i++) {
els[i].parentNode.removeChild(els[i]);
}
//再び箱を生成
CreateBoxes();
});
Lesson18
テレポート機能の追加
テレポート機能の追加
<a-scene physics="gravity: 0; restitution: 0.9;" background="color:#FAFAFA">
<a-plane static-body position= "0 0 0" rotation="-90 0 0"
width= "10" height=" 10" src="画像のURL" shadow></a-plane>
中略
<a-plane static-body position="-5 2.5 0" rotation="0 90 0"
width="10" height="5" src="画像のURL " shadow></a-plane>
<!--コントローラ-->
<a-entity oculus-touch-controls="hand: left" raycaster input-listen>
</a-entity>
<a-entity oculus-touch-controls="hand: right" raycaster input-listen>
</a-entity>
</a-scene>
カメラと左右のコントローラを<a-entity id="cameraRig">の子要素に
することにより、これらをまとめて目的地にテレポートさせることが可能になる
テレポート機能の追加
<a-scene physics="gravity: 0; restitution: 0.9;" background="color:#FAFAFA">
<a-plane static-body position= "0 0 0" rotation="-90 0 0"
width= "10" height=" 10" src="画像のURL" shadow></a-plane>
中略
<a-plane static-body position="-5 2.5 0" rotation="0 90 0"
width="10" height="5" src="画像のURL " shadow></a-plane>
<a-entity id="cameraRig">
<a-entity id="head" camera></camera>
<!--コントローラ-->
<a-entity oculus-touch-controls="hand: left" raycaster input-listen>
</a-entity>
<a-entity oculus-touch-controls="hand: right" raycaster input-listen>
</a-entity>
</a-entity>
</a-scene>
カメラと左右のコントローラを<a-entity id="cameraRig">の子要素に
することにより、これらをまとめて目的地にテレポートさせることが可能になる
テレポート機能の追加
<a-scene physics="gravity: 0; restitution: 0.9;" background="color:#FAFAFA">
<a-plane static-body position= "0 0 0" rotation="-90 0 0"
width= "10" height=" 10" src="画像のURL" shadow></a-plane>
中略
<a-plane static-body position="-5 2.5 0" rotation="0 90 0"
width="10" height="5" src="画像のURL " shadow></a-plane>
<a-entity id="cameraRig">
<a-entity id="head" camera></a-entity>
<!--コントローラ-->
<a-entity oculus-touch-controls="hand: left" raycaster input-listen>
</a-entity>
<a-entity oculus-touch-controls="hand: right" raycaster input-listen>
</a-entity>
</a-entity>
</a-scene>
カメラと左右のコントローラを<a-entity id="cameraRig">の子要素に
することにより、これらをまとめて目的地にテレポートさせることが可能になる
次はここをいじる
テレポート機能の追加
<a-scene physics="gravity: 0; restitution: 0.9;" background="color:#FAFAFA">
<a-plane static-body position= "0 0 0" rotation="-90 0 0"
width= "10" height=" 10" src="画像のURL" shadow></a-plane>
中略
<a-plane static-body position="-5 2.5 0" rotation="0 90 0"
width="10" height="5" src="画像のURL " shadow></a-plane>
<a-entity id="cameraRig">
<a-entity id="head" camera></a-entity>
<!--コントローラ-->
<a-entity
teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head;
startEvents: teleportstart; endEvents: teleportend"
oculus-touch-controls="hand: left" raycaster input-listen>
</a-entity>
<a-entity oculus-touch-controls="hand: right" raycaster input-listen>
</a-entity>
</a-entity>
</a-scene>
Lesson19
テレポート機能の追加(補足①)
<a-scene physics="gravity: 0; restitution: 0.9;" background="color: #FAFAFA">
<!--中略-->
<a-entity id="cameraRig">
<a-entity id="head"> </a-entity>
<!—コントローラ-->
<a-entity teleport-controls=
"cameraRig: #cameraRig; teleportOrigin:#head;
startEvents: teleportstart; endEvents: teleportend"
laser-controls="hand: left" input-listen> </a-entity>
<a-entity laser-controls="hand: right" input-listen> </a-entity>
</a-entity>
</a-scene>
#headを中心に#cameraRigの子要素ごと移動するという設定
テレポート機能の追加(補足②)
teleportstart は移動先をポインティングする際に呼び出すイベント。
teleportend は指定位置にジャンプする際に呼び出すイベント。
<a-scene physics="gravity: 0; restitution: 0.9;" background="color: #FAFAFA">
<!--中略-->
<a-entity id="cameraRig">
<a-entity id="head"> </a-entity>
<!—コントローラ-->
<a-entity teleport-controls=
"cameraRig: #cameraRig; teleportOrigin:#head;
startEvents: teleportstart; endEvents: teleportend"
laser-controls="hand: left" input-listen> </a-entity>
<a-entity laser-controls="hand: right" input-listen> </a-entity>
</a-entity>
</a-scene>
テレポート機能の追加
init:function () { //初期化
//トリガーを押した時(両手)
this.el.addEventListener('triggerdown', function (e) {
});
//Aボタンを押した時(右手のみ)
this.el.addEventListener('abuttondown', function (e) {
});
//Bボタンを押した時(右手のみ)
this.el.addEventListener('bbuttondown', function (e) {
});
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
});
} ,
障害物のリセット
//Xボタンを押した時(左手のみ)
this.el.addEventListener('xbuttondown', function (e) {
//テレポート先の選択を開始
this.emit('teleportstart');
});
//Xボタンを離した時(左手)
this.el.addEventListener('xbuttonup', function (e) {
//指定した先にジャンプ
this.emit('teleportend');
});
Lesson20
完成!
参考
サンプルを公開しています。
(1)各ボタンからの入力を取得
https://github.com/TakashiYoshinaga/Oculus-Quest-
Input-Sample
(2)オブジェクト操作/テレポート/シューティング
https://github.com/TakashiYoshinaga/Oculus-Quest-
Interaction-Sample
(3)A-Frame(WebVR/AR)ハンズオン資料
https://www2.slideshare.net/ssuserc0d7fb/glitch-
0webarvr-with
Oculus Quest 1&2 開発のはじめの一歩 with A-Frame WebVR

Oculus Quest 1&2 開発のはじめの一歩 with A-Frame WebVR