MRが楽しい

MRやVRについて学習したことを書き残す

AssetBundleを使って3Dオブジェクトを動的に取り込む(その2)

前回記事の続きとなります。技術の調査、実装内容については以下を参照ください。
bluebirdofoz.hatenablog.com


さて、実装したプロジェクトを試しに動かします。まずはUnityEditorでの動作確認です。
"Application.streamingAssetsPath"のファイルパスはUnityEditor上では「Asset/StreamingAssets」フォルダとなります。
docs.unity3d.com

「Asset/StreamingAssets」フォルダを作成して、そこに先ほど作成したAssetBundleをコピーします。
f:id:bluebirdofoz:20170612014907j:plain

LoadFromFileAsync.csを「ShowObject」オブジェクトにアタッチして起動してみます。
"mappingobject"内の3Dモデルが表示されました。
f:id:bluebirdofoz:20170612014922j:plain
AssetBundleに含まれていたゲームオブジェクトが読み込まれ、「ROOM(Clone)」として自動生成されています。


UnityEditor上の動作確認は成功です。次はhololensにインストールして確認します。

アプリはhololens上でも正常に動作しました。3Dオブジェクトがhololens上で確認できます。
f:id:bluebirdofoz:20170612014941j:plain
では"mappingobject"ファイルは何処にあるのかなと、デバイスポータルを確認しますが、何処にも見つかりません。

色々調べてみましたが、hololensでの「Application.streamingAssetsPath」のパス位置はデバイスポータルからは参照できないようです。
アセットを差し替える動作を手軽に実現したいため、デバイスポータルから見える位置に読み込みファイルを置きたいところです。

調べてみたところ、「LocalAppData/AppName/LocalState」が「Windows.Storage.ApplicationData.Current.LocalFolder.Path」で参照可能という情報がありました
forums.hololens.com

「LocalAppData/AppName」はアプリのローカル空間であるため、アプリは権限設定不要でこのフォルダを参照できます。
また、デバイスポータルからも参照可能です。ここを利用するのが良さそうですね。
f:id:bluebirdofoz:20170612015028j:plain

読み込みコードを以下のように修正し、hololens上(WINDOWS_UWP)では「LocalAppData/AppName/LocalState」を参照するようにしました。
・LoadFromFileAsync.cs

(略)
    IEnumerator Start()
    {
        string bundlepath = "";
#if WINDOWS_UWP
        bundlepath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "mappingobject");
#else
        bundlepath = Path.Combine(Application.streamingAssetsPath, "mappingobject");
#endif
        AssetBundleCreateRequest bundleLoadRequest = AssetBundle.LoadFromFileAsync(bundlepath);
(略)

以上の修正を行って再ビルド、そのままhololens上でアプリを起動します。
この時点では当然ながら、取得先のフォルダ「LocalAppData/AppName/LocalState」にファイルがないため、オブジェクトは表示されません。
f:id:bluebirdofoz:20170612015052j:plain

バイスポータルを用いて、"mappingobject"ファイルをhololensの「LocalAppData/AppName/LocalState」にアップロードします。
f:id:bluebirdofoz:20170612015105j:plain

再度アプリを起動すると…。
f:id:bluebirdofoz:20170612015116j:plain
"mappingobject"内の3Dモデルが表示されました。成功です。


この修正により、バイナリレベルでのアプリ本体とデータの切り分けが実現しました。

効果を体験するため、例えば、別の部屋データをAssetBundleとして作成してみます。
f:id:bluebirdofoz:20170612015134j:plain

アプリ本体の再ビルドは不要です。デバイスポータルから再作成した「mappingobject」ファイルをアップロードして置き換えます。
f:id:bluebirdofoz:20170612015144j:plain

後はhololensのアプリを再度起動するだけで…。
f:id:bluebirdofoz:20170612015153j:plain
表示される3Dオブジェクトが変わりました。
hololens内のファイルを更新することで、アプリの表示データを差し替えることに成功です。


この機能を使えば、アプリ本体に読み込みのロジックを組んでおくことで、後々からの3Dモデル追加や差し替えが可能になります。
例えば、自分のhololens上にアプリ本体とは別に、3Dモデルファイルを配置することで、自分がアプリを起動したときのみ、異なるモデルを表示するといったことが可能です。

余談ですが、記事の投稿まで時間があまったので、おいかっけアプリに機能追加しました。
タッチすると、キャラクタが嫌がります。
f:id:bluebirdofoz:20170612015324j:plain
でへへ。非常に申し訳ない。