【unityプロ技】 Advent Calendar 2019 - Qiita 6日目の記事です。*1
はじめに - ARFoundationとは
スマートフォンでのAR楽しいですね。それぞれiOSはARKit、AndroidではARCoreというAR用開発キットが公開されています。Unity用SDKもそれぞれUnity-ARKit-Plugin,Google ARCore SDK for Unityと開発がされてきました。今まではそれぞれのSDKをインストールして頑張ってきたのですが、ARCore, ARKit, HoloLens, Magic LeapのSDKをラップして、同じAPIでアクセスできるようにする、ARFoundationが発表されました。
ARFoundationの導入は、安定のテラシュールブログさんを御覧ください。 tsubakit1.hateblo.jp
何を作った?
ARFoundationはUnity-ARKit-PluginのときよりもAPIがシンプルでわかりやすいのですが。以前のこちらの日記でも簡単に書いたように、 Editorで動かない。毎回実機ビルドが必要という問題がありました。Unity-ARKit-Pluginのときはできていたんです…。つい昨日、公式からアナウンスがあり、2020年はじめにリモートでつなげてEditorでも動作できる機能をリリース予定です。とはいえ、今すぐ仕事で使うために、自分で使う一部機能だけでもEditorで動かせると便利だと思ったので、ARKit3の新機能だけでもEditorで動作するものを作りました。*2
今回エディタ側で対応した機能は、 - 人間の体部分を検出 - Face - 座標検出 - Mesh検出 - ブレンドシェイプ推定 です。 以下は作例です。Editorで動作することで、デプスを送りながらVisual Effect Graphでノードのパラメータをいじるなどといったこともできるようになっています。
AR Foundation (ARKit3) + Simulate on Editor + Visual Effect Graph (@_kzr 's Dkvfx) #madewithunity https://t.co/QsLRMkp6Ji pic.twitter.com/8zOGxRwlb0
— Koki Ibukuro (@asus4) 2019年10月25日
Streaming facial mesh from iPhoneX to UnityEditor #madewithunity #arkithttps://t.co/QsLRMkp6Ji pic.twitter.com/EGYO6Y0WQx
— Koki Ibukuro (@asus4) 2019年10月30日
使い方
簡単に使い方を説明します。
1. NDIのインストール
iPhoneのカメラで移している映像をUnityに送るためにNDIを使っています。iPhoneで使うためには、NDIを https://ndi.tv/sdk/ からインストールする必要があります。メールアドレスを登録してしばらくするとSDKのダウンロード先URLが送られてきます。
2. iPhoneに送信用アプリをインストール
GitHubからUnityプロジェクトをダウンロードして、 iPhone用にビルド。Xcodeから対応端末 (iPhoneX以降〜)へインストールします。
3. macとiPhoneをUSBでつなげる
高速のWi-Fiの場合は良いですが、私のオフィスのネットワーク環境ではiPhoneとmacをiPhone USBネットワークで接続したほうが遅延が少なく動作しました。
4. 再生する
iPhoneの送信側と対応するシーンをUnityEditorでも開きます。
iPhoneを再生すると、同じネットワークにNDIが飛んでいる場合、NDIの名前が表示させるので、NDI ReceiverコンポーネントのSource Nameにセットしてください。
Unity Editorを再生開始するとiPhoneと同じ画面が表示されると思います。
ARFoundationを中身を見てみよう
この開発をするために、ARFoundationの中身を詳しく知る必要があったので、紹介します。
最新のロードマップ、Unite Copenhagen 2019でのスライドにあるように、AR Foundationを抽象化されたAPIの一個深いレイヤーにはSubsystemというものがあります。平面を検出する機能を例に取ると、
それぞれのプラットフォームフォームがSubsustemを持っています。対応していないplatformではSubsystemがnullを返します。Manager側が何も動作しないので、シーン中にManagerコンポーネントが配置されていても問題ありません。そして、UnityEditorで実行するときは、Subsystemは存在しないので、エラーは返さないものの、動作しません。
そこでUnity Editor用のSubsystemを追加して、ARFoundationとは別の経路でiPhone実機から同等のデータを送信。このEditor用SubsystemをAR FoundationのハイレベルAPIに同じデータを転送。
一番上のレイヤーから見ると、動作は何も変わっていないので同じコードで動作する気がします。
Subsystemの作り方
ここまでがわかったいくつかのSubsystemを自分で作ってみました。GitHubのリンクはこちらです
セッション管理をしているXRSesseionSubsystemをEditorで対応する例です。
// 仮想コード namespace ARKitStream.Internal { // PreserveはCode strippingでコードが消されないようにしてるっぽい。 [Preserve] public class ARKitSessionRemoteSubsystem : XRSessionSubsystem { protected override Provider CreateProvider() => new ARKitRemoteProvider(); // サブシステムの初期化時にUnityEngineから実行される [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void RegisterDescriptor() { // UnityEditorのときだけサブシステムを作る #if UNITY_EDITOR const string id = "ARKit-Remote-Session"; XRSessionSubsystemDescriptor.RegisterDescriptor(new XRSessionSubsystemDescriptor.Cinfo { id = id, subsystemImplementationType = typeof(ARKitSessionRemoteSubsystem), supportsInstall = false, supportsMatchFrameRate = false }); #endif // UNITY_EDITOR } // サブシステム本体 // 各サブシステムにはProviderと呼ばれる本体のクラスがいる。 class ARKitRemoteProvider : Provider { // } } }
かなりシンプルに書いていますが、このようにRuntimeInitializeOnLoadMethod
アトリビュートでSubsystemを管理しているようです。RuntimeInitializeOnLoadMethod
は今回始めて使いましたが、UnityEngineネームスペースにあるので、ARFoundation以外にもSubsystemを使っているライブラリがあるのかもしれません。
まとめ
- AR Foundationを使うと簡単にマルチプラットフォームなARアプリを作成できます。
- Editorでも一部の機能を動作させることができた。
- Unity開発チームが来年はじめに、Editorで動くやつを公開してくれる予定。
以上です。
*1:ML-Agents付属のBarracudaのドキュメントが少ないので、詳細を書こうとしたのですが、玉砕したので内容を変更しています
*2:また別の選択肢とて1→10さんが開発しているZIG SIM PROもいいかもしれません。NDIとOSCで、ARKit3のいくつかの機能を送信できます。有料ですが、時間節約できるので一瞬で元取れます。