AR・VR

AR.js+A-Frameを使用したWebARゲームの開発方法を解説

開発者
AR.jsとA-frameを使用したWebARの具体的開発方法を知りたいです!!
好奇心旺盛な人
簡単なゲームを開発してみたいな!!

そんなあなたの悩みを解決します。

この記事を書いているのは、Internnectでインターンをさせていただいている古宮 皇(ふるみや ひろむ)です。

ゲームを開発しリリースした経験があるのに加えて、AR.jsとA-frameを使用したWebARを実際に開発したので、少しはお役に立てると思います。

今回はゲーム開発者である私がAR.jsとA-Frameを使用したWebARゲームの具体的開発方法を解説します。

AR.js+A-frameを使用したWebARゲームの開発方法

それでは実際にAR.js+A-Frameを使用したWebARゲームを開発していきたいと思うのですが、もしかしたらそもそも「WebARって何?」「AR.js+A-Frameとは?」という方もいるかも知れないので簡単に解説しておきます。

  • WebARとはブラウザだけで動くARコンテンツのこと
  • AR.jsはWEBARを開発できるオープンソフトウェアのJavaScriptライブラリ。
  • AFrameはカスタムされたHTMLを使用することで、WebVRを開発することができるフレームワーク

という感じですね。
更に詳しく知りたいという方は以下の「WebARとは?ARアプリとの違い&開発方法をアプリ開発者が解説」という記事で解説していますので、読んでいただければと思います。

https://eng.internnect.co.jp/what-is-webar/

クイズ&ドラッグWebARゲーム

今回開発していくのはクイズ&ドラッグWebARゲームです。

とはいえどんなゲームか全くわからないと思うので、実際の完成コードとサンプルを最初にお見せします。

クイズ&ドラッグWebARゲーム(サンプル)の遊び方

  1. URL(https://brave-goldstine-28d8db.netlify.app/quiz.html)にカメラ付きデバイスからアクセスする。
  2. カメラが起動(初回は許可が必要)するので、そのカメラで以下のマーカーを写す
  3. クイズが表示されるので、答えだと思う立方体に画面中央の緑色カーソルを合わせ続ける。
  4. 移動する立方体に一定時間カーソルを合わせ続けるとリンク先に飛ぶ
  5. リンク先でもう一度マーカーを写すとクイズに正解したか不正解したかがわかる
  6. Backと表示された立方体にカーソルを合わせるとクイズ画面に戻る
マーカー

完成コード

quiz.html

 command
<!DOCTYPE html>
<html>
    <meta charset="utf-8">

    <!--A-frameの読み込み-->
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <!--Ar.jsの読み込み-->
    <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
  </head>
  <body style='margin: 0; overflow: hidden;'>
    <!--A-FrameにAR.jsを紐付け&デバックUIを非表示-->
    <a-scene embedded arjs="debugUIEnabled:false;"vr-mode-ui="enabled: false">
      
      <!--ARmarkerの設定-->
      <a-marker preset="hiro">
        <a-sky color="white" opacity="0.8"></a-sky>
        <a-text
        value="正解だと思うものにカーソルをあわせ続けてみよう!!"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.6 0.6 0.6"
        position="0 0.5 -0.9"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="三大栄養素ではないものはどれ?"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 -0.7"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="タンパク質"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 -0.5"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="ビタミン"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 -0.1"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="脂質"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 0.3"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-box scale="0.2 0.2 0.2" position="-0.4 0.5 -0.3"link="href:https://brave-goldstine-28d8db.netlify.app/incorrect.html" color="black"
        animation="property: object3D.position.x;
             from: -0.4;
             to: 0.4;
             dur: 2500;
             easing: linear;
             dir: alternate;
             loop: true">
        </a-box> 
        <a-box scale="0.2 0.2 0.2" position="-0.4 0.5 0.1" link="href:https://brave-goldstine-28d8db.netlify.app/correct.html"color="black"
             animation="property: object3D.position.x;
             from: -0.4;
             to: 0.4;
             dur: 2500;
             easing: linear;
             dir: alternate;
             loop: true">
        </a-box>
        <a-box scale="0.2 0.2 0.2" position="-0.4 0.5 0.5" link="href:https://brave-goldstine-28d8db.netlify.app/incorrect.html"  color="black"
             animation="property: object3D.position.x;
             from: -0.4;
             to: 0.4;
             dur: 2500;
             easing: linear;
             dir: alternate;
             loop: true"> 
        </a-box>
      </a-marker>
      <!--カメラを配置-->
      <a-entity camera> 
        <a-entity cursor="fuse: true; fuseTimeout:2000" position="-0.015 0.057 -2" geometry="primitive:ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: #7cfc00; shader: flat"scale="0.5 0.5 0.5"></a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>
 

correct.html

<!DOCTYPE html>
<html>
    <meta charset="utf-8">

    <!--A-frameの読み込み-->
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <!--Ar.jsの読み込み-->
    <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
  </head>
  <body style='margin: 0; overflow: hidden;'>
    <!--A-FrameにAR.jsを紐付け&デバックUIを非表示-->
    <a-scene embedded arjs="debugUIEnabled:false;"vr-mode-ui="enabled: false">
      <!--ARmarkerの種類とパスを指定-->
      <a-marker preset="hiro">
        <a-text
        value="正解!!"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="1 1 1"
        position="0 0.5 -0.5"
        rotation="-90 0 0"
        color="#00ff00">
        </a-text>
        <a-text value="Back" position="0 0.5 -0.1" align="center" scale="0.7 0.7 0.7" rotation="-90 0 0"color="#ffa500"></a-text>
        <a-box scale="0.3 0.3 0.3" position="0 0.5 0.2" link="href:https://brave-goldstine-28d8db.netlify.app/quiz.html">
        </a-box>    
      </a-marker>
      <!--カメラを配置-->
      <a-entity camera> 
        <a-entity cursor="fuse: true; fuseTimeout:500" position="-0.015 0.057 -2" geometry="primitive:ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: #7cfc00; shader: flat"></a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>

incorrect.html

<!DOCTYPE html>
<html>
    <meta charset="utf-8">

    <!--A-frameの読み込み-->
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <!--Ar.jsの読み込み-->
    <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
  </head>
  <body style='margin: 0; overflow: hidden;'>
    <!--A-FrameにAR.jsを紐付け&デバックUIを非表示-->
    <a-scene embedded arjs="debugUIEnabled:false;"vr-mode-ui="enabled: false">
      <!--ARmarkerの種類とパスを指定-->
      <a-marker preset="hiro">
        <a-text
        value="不正解!!"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="1 1 1"
        position="0 0.5 -0.5"
        rotation="-90 0 0"
        color="#00ff00">
        </a-text>
        <a-text value="Back" position="0 0.5 -0.1" align="center" scale="0.7 0.7 0.7" rotation="-90 0 0"color="#ffa500"></a-text>
        <a-box scale="0.3 0.3 0.3" position="0 0.5 0.2" link="href:https://brave-goldstine-28d8db.netlify.app/quiz.html">
        </a-box>    
      </a-marker>
      <!--カメラを配置-->
      <a-entity camera> 
        <a-entity cursor="fuse: true; fuseTimeout:500" position="-0.015 0.057 -2" geometry="primitive:ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: #7cfc00; shader: flat"></a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>

前提知識&必要ツール

まずは前提知識と必要なツールについて紹介していきます。

前提知識

  • HTML&CSS
  • AR
  • Git
  • GitHub/Bitbucket

必要ツール

  • PC
  • カメラ付きデバイス(Android・IOS)
  • テキストエディター
  • GitHub/Bitbucket

開発前の準備

A-Frameについては基本のタグが分かる程度の知識が必要です。(コピペすれば問題なくゲームは開発できます)

そのため以下を読みA-Frameの基本的なタグの知識を得てください。

また以下の記事を参考にゲームをプレイするためのサイトを作成してください。

https://qiita.com/sugo/items/2ee64887d682

HTMLの基本コード&AR.js+A-Frameを読み込み

それではさっそく開発していきたいと思います。

quiz.html

<!DOCTYPE html>
<html>
 <head>
    <meta charset="utf-8">
    <!--A-frameの読み込み-->
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <!--Ar.jsの読み込み-->
    <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
  </head>
  <body style='margin: 0; overflow: hidden;'>

  </body>
</html>

まずはHTMLの基本コード&AR.js+A-Frameの読み込みです。

<head>の中で<script>を使用して、A-FrameとAR.jsの読み込みを行っています。

HTMLの基本コードについては、おそらくご存知だと思うので省略させていただきます。

シーンの作成&カメラとカーソルの配置

quiz.html

<!--A-FrameにAR.jsを紐付け&デバックUIとVRモードUIを非表示-->
    <a-scene embedded arjs="debugUIEnabled:false;"vr-mode-ui="enabled: false">※1
      <!--カメラを配置-->
      <a-entity camera> ※2
    <!--カーソルを配置-->
        <a-entity cursor="fuse: true; fuseTimeout:1000" position="-0.015 0.057 -2" geometry="primitive:ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: #7cfc00; shader: flat"></a-entity>※3
      </a-entity>
    </a-scene>

次は<body>の中にコードを記述していきます。

  1. a-seceneタグでシーン(AR世界?)を作成し、シーンにAR.jsを紐付け&デバックUIとVRモードUIを非表示にしています。
  2. カメラを配置しています。ユーザーがサイトにアクセスするとカメラが起動するようになります。
  3. カーソルを配置しています。fuseは導火線、fuseTimeoutは導火線がなくなる時間?(リンクに飛ぶまでの時間)みたいな感じです。後は位置・形・色を指定しています。詳しくはhttps://aframe.io/docs/1.0.0/components/cursor.htmlを参考にしてください。

マーカーの設定

今回はプリセットとして用意されているhiroマーカーを使用したいと思います。

quiz.html

略
<!--A-FrameにAR.jsを紐付け&デバックUIを非表示-->
    <a-scene embedded arjs="debugUIEnabled:false;"vr-mode-ui="enabled: false">
<!--今回の追加部分-->
      <!--ARmarkerの設定-->
      <a-marker preset="hiro">
      </a-marker>
<!--今回の追加部分-->
      <!--カメラを配置-->
略

今回の追加部分を記述することで、設定したマーカーを認識できるようになります。
自分で制作したマーカーを使用する場合は、また違ったコードになるので、注意してください。

日本語テキストを表示する

まず前提としてAR.js+A-Frameは日本語に対応していません。
そのため自分で日本語フォントを作成する必要があります。

日本語フォントを作成

日本語フォントを作成するには、以下のサイトを使用します。(公式でも紹介されています

https://msdf-bmfont.donmccurdy.com/

  1. Select character setに使用する日本語を全て記述する。※1
  2. Create MSDF fontでファイル名(自由)と画像サイズ(エラーが出たら大きくする)を決め、Create MSDFボタンをクリック
  3. Preview and download filesのDownloadをクリックし、ファイル名.pngとファイル名-msdf.jsonダウンロードする
  4. ファイル名.png→ファイル名.-msdf.pngに変更

※1今回使用する日本語(自分好みに変更してください)

正解!! 不正解!! 三大栄養素ではないものはどれ?! ビタミン 脂質 タンパク質 正解だと思うものにカーソルをあわせ続けてみよう!!

日本語を表示するコードを記述

次に先程作成したフォントを使用して、日本語を表示していきたいと思います。

quiz.html

<!--ARmarkerの設定-->
      <a-marker preset="hiro">
<!--今回の追加部分-->
        <a-text
        value="正解だと思うものにカーソルをあわせ続けてみよう!!"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.6 0.6 0.6"
        position="0 0.5 -0.9"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="三大栄養素ではないものはどれ?"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 -0.7"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="タンパク質"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
    scale="0.7 0.7 0.7"
        position="0 0.5 -0.5"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="ビタミン"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 -0.1"
        rotation="-90 0 0"
        color="black"
        ></a-text>
        <a-text
        value="脂質"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="0.7 0.7 0.7"
        position="0 0.5 -0.3"
        rotation="-90 0 0"
        color="black"
        ></a-text>
<!--今回の追加部分-->
      </a-marker>

fontとfontimageにフォントファイルを設定することで、日本語テキストを表示できます。

rotationで-90と設定しないと、文字が画面に対して垂直になってしまうので、注意してください。

オブジェクトの追加(立方体)

オブジェクトを追加するために以下のコードを記述します。

quiz.html

</a-text>
<!--今回の追加部分-->
        <a-box scale="0.2 0.2 0.2" position="0 0.5 -0.3">
        </a-box> 
        <a-box scale="0.2 0.2 0.2" position="0 0.5 0.1">
        </a-box>
        <a-box scale="0.2 0.2 0.2" position="0 0.5 0.5"> 
        </a-box>
<!--今回の追加部分-->
      </a-marker>

これらはクイズに解答するためのオブジェクトなので、それぞれ選択肢テキストの下に配置します。(positionの数値を変更して配置する)

リンク先のファイルを作成

オブジェクトにリンクを追加する前にリンク先のhtmlファイルを2つ(正解と不正解)作成します。

correct.html

<!DOCTYPE html>
<html>
    <meta charset="utf-8">

    <!--A-frameの読み込み-->
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <!--Ar.jsの読み込み-->
    <script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
  </head>
  <body style='margin: 0; overflow: hidden;'>
    <!--A-FrameにAR.jsを紐付け&デバックUIを非表示-->
    <a-scene embedded arjs="debugUIEnabled:false;"vr-mode-ui="enabled: false">
      <!--ARmarkerの種類とパスを指定-->
      <a-marker preset="hiro">
        <a-text
        value="正解!!"
        align="center"
        font="quiz-msdf.json"
        font-image="quiz-msdf.png"
        negate="false"
        scale="1 1 1"
        position="0 0.5 -0.5"
        rotation="-90 0 0"
        color="#00ff00">
        </a-text>
        <a-text value="Back" position="0 0.5 -0.1" align="center" scale="0.7 0.7 0.7" rotation="-90 0 0"color="#ffa500"></a-text>
        <a-box scale="0.3 0.3 0.3" position="0 0.5 0.2" link="href:https://brave-goldstine-28d8db.netlify.app/quiz.html">
        </a-box>    
      </a-marker>
      <!--カメラを配置-->
      <a-entity camera> 
        <a-entity cursor="fuse: true; fuseTimeout:500" position="-0.015 0.057 -2" geometry="primitive:ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: #7cfc00; shader: flat"></a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>
incorrect.html
こちらの不正解ファイルは、correct.htmlの正解!!部分を不正解!!に入れ替えるだけで大丈夫です。

オブジェクトにリンクを追加

ファイルを2つ作り終えたら、オブジェクトにリンクを追加します。

quiz.html

        <a-box scale="0.2 0.2 0.2" position="0 0.5 -0.3"link="URL/incorrect.html">
        </a-box> 
        <a-box scale="0.2 0.2 0.2" position="0 0.5 0.1" link="href:URL/correct.html">
        </a-box>
        <a-box scale="0.2 0.2 0.2" position="0 0.5 0.5" link="href:URL/incorrect.html"> 
        </a-box>

URLの部分には開発の準備で作成したサイトのURLを記述してください。

不正解か正解かがわかった後に、もう一度quiz.htmlに戻れるようにするため以下のコードをcorrect.html&incorrect.htmlの<a-box>内に記述してください。

link="href:URL/quiz.html"

オブジェクトにアニメーションを追加

最後にオブジェクトにアニメーションを追加します。

今回は往復左右移動アニメーションです。

quiz.html

             <a-box scale="0.2 0.2 0.2" position="-0.4 0.5 -0.3"link="href:https://brave-goldstine-28d8db.netlify.app/incorrect.html" color="black"
        animation="property: object3D.position.x;
             from: -0.4;
             to: 0.4;
             dur: 2500;
             easing: linear;
             dir: alternate;
             loop: true">
        </a-box> 
        <a-box scale="0.2 0.2 0.2" position="-0.4 0.5 0.1" link="href:https://brave-goldstine-28d8db.netlify.app/correct.html"color="black"
             animation="property: object3D.position.x;
             from: -0.4;
             to: 0.4;
             dur: 2500;
             easing: linear;
             dir: alternate;
             loop: true">
        </a-box>
        <a-box scale="0.2 0.2 0.2" position="-0.4 0.5 0.5" link="href:https://brave-goldstine-28d8db.netlify.app/incorrect.html"  color="black"
             animation="property: object3D.position.x;
             from: -0.4;
             to: 0.4;
             dur: 2500;
             easing: linear;
             dir: alternate;
             loop: true"> 
        </a-box>

property = アニメーションの種類

from = アニメーションの開始位置

to = アニメーションの終了位置

easing=速度の変化

loop = 繰り返し

という感じですね。

ファイルをサイトにアップロード

後は以下のファイルをサイトにアップロードすれば完成です。(開発前の準備を参考にしてください)

  • quiz.html
  • correct.html
  • incorrect.html
  • フォントファイル
  • フォントイメージファイル

まとめ:HTMLだけで簡単にWebARを開発!!

いかがだったでしょうか。

今回は最初から最後までHTMLだけで、WebARゲームを開発することができました。

こんなに簡単にARコンテンツを開発できちゃうなんて驚きですね。

この方法以外にもARを開発する方法はたくさんありますので、ぜひ挑戦してみてください。

ワクワクが止まらなくなること間違いなしです。

それでは楽しいARライフをお送りください。

-AR・VR
-

Copyright© Internect Engineering Blog , 2020 All Rights Reserved Powered by AFFINGER5.