#はじめに
どうもみなさんこんにちは.これはU-TOKYO AP Advent Calendar 2018 の25日目の記事です.
僕は東京大学計数工学科B4のDipというものです.
クリスマスですね.いかがお過ごしですか.独り身エンジニアですか?リア充エンジニアですか?僕はクリスマスに記事を書いているなぞなぞエンジニアです.
東京大学五月祭工学博覧会という学科同期でいろんな出し物をしようというコーナーがあるのですが,僕はそこで画像処理班としてARの街づくりゲームを出していました(半年以上前)
引き継ぎのついでに書いています
#作ったもの
動画を見てもらった方が早いと思います...ARを使った街づくりゲームを展示しました。
https://twitter.com/dipukamin/status/996741589031469057
このデモではソロプレイをしていますが、本番ではマルチプレイでみんなで街づくりする感じになっています。
ここでは実際にUnityでどのような実装をしたのか書いていきます
#開発環境
・MacbookPro(2017) 15inch
・iPad(2017~)
・Unity 2018.1beta
基本的には、Macであり、Unityが動かせれば大丈夫です。
#実装に用いたライブラリ
##AR
ARについては、ARKit1.5を使いました。(Swift諦めた勢)
https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/downloads/?tab=branches
ここから最新のブランチをダウンロードしてUnityに入れれば大丈夫です。
ARKitの機能としては、以下の機能を使いました。
・トラッキング(いわゆるSLAM)
・ワールドアンカー(任意のtransformに原点を設定する)
・画像認識
平面認識もできれば使いたかったのですが、別々のデバイスで別々の平面を作ってしまうのは共有上あまり意味がないし、共有するのがめんどくさいので諦めました。
#具体的な実装
##AR街づくり機能
ここに関してはあまり大したことはしていません.世の中にはARkitの使い方の記事がポロポロと出ているので,その辺を参考にしました.ARkitでは使うゲームオブジェクトとスクリプトの配置さえできていれば通常の3Dゲームと同じように動かせます.その辺はサンプルシーンからコピーすればいいと思います.
街づくり機能においては,建物を建てる,移動,回転,拡大縮小を行うの2機能をメインとして実装しました.建物を建てる機能においては,メニュー画面から建物を選択し,建てたい場所をタップしてもしその場所に地面があればその場所に建物が出現します.一度建てた建物をタップすると座標変更系のメニューが出現します.移動を選択するとタップした場所に移動,回転を選択すると建物が回転します.一度建てた建物は5分経つと消失するが,いいねボタンを押すと延長することができます.
この辺の機能は,UIを作ってメニューを選択したら編集モードになり,タップした点から地面に向けてRayCastを打って衝突判定をして...等をスクリプトに書いて実装しました.普通の3Dゲームを作るのとだいたい一緒の発想です.ただ,ARKitにおいてはスケールを普通の1/10で扱わないといけないのでタップの速度などをうまいこと調整しないと建てた建物が遥か遠くに吹っ飛びます.
##ネットワーク機能
この辺が一からの勉強だったので一番しんどかった気がします.ネットワークの実装にあたってはUNETとういうUnity用の高レベルAPIを使いました.UNETはローカルLANで動かす向けで,あまりオンラインゲームでは見ない気がします.というかUNET廃止されるらしいですね.
UNETの勉強はhttp://edom18.hateblo.jp/entry/2017/05/30/120811
などのサイトを参考にしました.結構慎重に読み込まないと詰みます.
サーバとクライアントですが,サーバにはMacbook Proを使用しました.iPadだけでは重い処理をこなすのに限界があるので,重い処理はすごく頭のいいパソコンに投げてこなしてもらうことで出来るだけiPadのFPSを上げます.
基本的な流れですが,ローカルなオブジェクトなのか共有するオブジェクトなのかしっかり分けます.
例えば,ローカルなオブジェクトなら
・UI
・カメラ
共有するオブジェクトなら
・建物
・地面の状態
等があります.ローカルなオブジェクトはそこまで苦労しなかったですが,共有するオブジェクトは必ず
という流れを守るようにします.これを守らないとちゃんと共有されなかったりエラーを吐きます.例えば建物の位置を変更したい時,
という流れが必要です.クライアントから変更する位置を送りつけてサーバから変更命令を出してもらうこともできないことはないのですが,いちいちサーバーを介しているとめちゃくちゃ遅いです.10FPSくらいしか出ませんでした.クライアントとサーバで作業を同期させるためには権限がすごく大事になってくるという話でした.
##ワールド共有
せっかくのマルチプレイですからきちっと各プレイヤー間の座標を共有させたいものです.プレイヤー間で共有させるにあたっていくつかアプローチはあるのですが,僕は一番簡単(だと思われる)な方法を取りました.
ARKitには画像を認識してその画像の位置と回転を取得する機能,そして指定したtransformを原点に設定する機能があります.画像をマーカーとして設置しておいてそのtransformを取得し,そのtransformからの差分をクライアントの座標とすることで全クライアントのワールド座標を合わせることができます.画像を認識するのはこの座標合わせ1回でしか使わないので,ゲームをプレイしているときにずっと画像を画面に収めていなくてもちゃんとゲームができるのが魅力的ですね.
ほんとは全部マーカーレスにしたかったんですが,GPSがミリ単位の精度になるまで進化しなかったりiPadが常に自分の座標の差分を計算しない限りは実現しません.どれくらい先の未来に実現するんでしょうか...
#終わりに
五月くらいの記憶を無理やり手繰り寄せて書いたのでかなり適当になってしまいました...アンカーがこんなんでいいのか...