書いた人:田中(エンジニア)
こんにちは。Zooops Japan(ズープス ジャパン)・エンジニアの田中です(社内ではYTって呼ばれています)。弊社ブログ初の投稿なので、軽く自己紹介をします。
新卒でZooops Japanに入ってエンジニア歴は2年目。仕事では、Unityを使用したアプリケーション開発やWebシステムの開発をメインにしています。Webに関しては、PHPフレームワークのLaravelが多めです。
2018年秋も様々なイベントがありましたね。一つは「ハロウィン」。もう一つは、AppleによるiOS12のリリース、それに伴って「ARKit2」も正式にリリースされました。
私も先日、北海道斜里町で開催された「第三回しれとこハロウィン2018」に参加してきました(
しれとこハロウィンの様子は、しれとこハロウィンさんのFacebookでご覧ください)。
と言うのも弊社はTech企業として子どもたちに最新技術でワクワクしてもらうために、催し物としてARハロウィンゲームを作成・提供したからです(
私はこのメイン開発者として参加しました。キリッ)。
アプリの紹介動画は同じくしれとこハロウィンさんのFacebookにあがっていますので是非ご覧ください。
というわけで、
今回記事にするのは「ハロウィン×AR」についてです。
「ARKit」って何?
今回、ARアプリの開発で使用したのが、「ARKit」ですが、あまり馴染みのない人のために最初に簡単に説明します。
「ARKit」とは、Appleが提供する開発者向けARフレームワークです。平面検出やポジショントラッキングといったAR機能をARKit側で吸収してくれるので、開発者側は簡単に検出された平面座標や自己位置などを取得することができます。
ARKitは現在Version2にまでアップデートされており、物体認識や空間情報の保存など様々な機能が追加で実装されています。
ますますAR開発の幅が広がり
激アツですね!(もっと知りたい方は、以下を参考にしてみてください)
● Apple公式サイト
https://developer.apple.com/jp/arkit/
● アプリエンジニアのための技術情報サイト「ギャップロ」の紹介記事
https://www.gaprot.jp/gaprot-x-chogiken/xr/arkit_position_tracking
●「Qiita」の紹介記事
https://qiita.com/k-boy/items/d935b76fed67e11b9fb2
今回の開発概要
今回行った開発概要を簡潔にまとめると、以下の通りです。
開発概要
●アプリについて
AR機能を使用
子供向けハロウィンアプリ
知床の良さを取り入れたアプリ
●バージョン
Unity 2018.2.6f1
.NET 4.x
設計の話からしようと思ったのですが、かなり分量が多くなりそうだったので今回は残念ですが(涙)、はしょります。アプリ全体として、UniRxをゴリゴリに使用して、イベント駆動で開発を進めました。
この記事では、ハロウィンアプリの最大のコンセプトであるAR機能について、今回は「Unity-ARKit-Plugin」を使用しましたのでそれに関する話と、あとは子どもたちに視覚的に楽しんでもらうために「シェーダ」を所々に用いましたのでその一部を紹介しようと思います。
「Unity-ARKit-Plugin」
「Unity-ARKit-Plugin」とは、ARKitのネイティブインターフェースに対応したScripting APIを提供するUnity公式プラグインです。これを使用することで、ARKitの機能を簡単に利用することができます。
制作で利用したARKitの主な機能は6自由度(以降6DOFと略)の「ポジショントラッキング」と「平面検出」のみですが、利用例を簡単に紹介します(Unity-ARKit-Pluginのバージョンは、ARKit2をサポートした以降のものを使用しています)。
ポジショントラッキング(6DOF)
ポジショントラッキングを実現するためには、「UnityARCameraManager.cs」をアタッチしたゲームオブジェクトをシーン上に配置する必要があります。
UnityARCameraManager.csの中で、m_session.RunWithConfig(config)を読んでいる部分があり、ここで引数であるconfigの中身を変えることで3DOFと6DOFを変更することができます。
今回は、自由に歩き回れるようにしたかったので、ARKitWorldTrackingSessionConfigurationをセットしました。
これで6DOFのポジショントラッキングを実現可能です。
また、詳しくは見ていませんが、AR機能の中核部分である「カメラで写した映像をゲームシーンに流す」という機能の実現は、主に「UnityARVideo.cs」で行われています。コマンドバッファを利用して、カメラからの映像をテクスチャに流し込んでいるようです。
平面検出
アプリの立ち上げ後の最初のアクションで、ゲームを十分に行えるスペースの確保をおこなっています。ARKitの平面検出機能を用いて、いくつかの条件を満たした平面アンカーを取得して、プレイエリアとして採用します。
その条件は以下の通りとしました。
● 一定の面積以上であること
● 自身(iPad)と一定距離以上離れていること
●(カーソルの出現が)自身の目の前であること
平面アンカーが更新されるたびに随時検証し、条件に適合する平面のみカーソルイメージとして画面にレンダリングします。
ARKitには、フレームの更新や平面アンカーの更新などをC#のイベントとして受け取ることができ、それに対してコールバック関数を呼ぶことができます。
各検出データの更新をイベントとして提供されていることからわかるように、UnityエンジンのフレームとARKitのフレームは両者独立しています。
イベント一覧は、以下の「API Overview」に記載されています。
https://bitbucket.org/Unity-Technologies/unity-arkit-plugin
また、Unity-ARKit-Pluginのチュートリアルドキュメント(https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/src/d381878da15b523610e4a69c66e150ac71c470b2/TUTORIAL.txt?fileviewer=file-view-default)にあるように、フレーム更新のサンプルは、ポイントクラウドの実装として「PointCloudParticleExample.cs」に、平面アンカー更新のサンプルは、「UnityARAnchorManager.cs」にあります。
取得する平面アンカーの条件設定の話に戻ります。
条件による平面抽出は上記の流れです。
条件にあてはまる平面のフィルタリング部分のみを抽出しています。
ループの中で取得しているARPlaneAnchorが平面アンカーの実体で、transform(行列として)やアンカーの範囲などが含まれています。
そこから必要に応じて、Utilityとして用意されている「UnityARMatrixOps」を利用してVector3など直接計算に利用しやすい形(Vector3型など)に変換することができます。
「シェーダ」
続いては「シェーダ」です。ここでは、非現実感を醸し出すために実装した「お化けシェーダ」と「墓のダンスシェーダ」を紹介します。
お化けシェーダ
まずは、こちらの動画をご覧ください(音がでますよ)。
うーむ、我ながらお化け的な雰囲気が出ているではありませんか。
このお化けは間違って偽物カボチャをタッチしてしまったときに出現させます。
以下が実装コードです。
サーフェースシェーダのみを使用しています。Transparentで半透明にし、リムライティングとして、視線ベクトルと法線ベクトルの内積が大きくなるほどRGBがMaxになる(=白くなる)、小さくなるほどGBが強くなる(=青緑になる)というような実装です。
墓のダンスシェーダ
次に、こちらの動画をご覧ください(音がでますよ)。
実装の途中で、墓をそのまま置いているだけでは物足りない感じがし、揺らすことにしました。
揺らしたほうが、非現実的で楽しい気分になってきませんか?(ね、ね?)
墓のダンスモーションに関しては、頂点シェーダ(vert関数)で、墓の頂点Y座標をパラメータにX軸方向に指数関数的な動きにしています。
iPadとUnityエディタでは墓の揺れ幅の見え方に差がでてしまったため、Unityエディタ側ではけっこうオーバーな動きになっています(
激しすぎ……ww)
まとめ
今回のアプリ制作では、開発設計、レベルデザイン、実装にわたり、かなり幅広く経験することができ、とても貴重な経験をさせてもらいました。これで、
キャッキャとなく赤子から半人前にはレベルアップできたかな。
ただ、個人的にはいろいろと力不足で思い通りのアプリを作り上げられなかったという思いが大きいです。
今後はもっと精進してみんなをわくわくさせるアプリを作ろうと思います!
続編として、イベント当日編も記事にしようと思います。ヒヤッとさせられたハプニングなども紹介しますのでぜひお楽しみに!