FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Unity »【Unity】【C#】AssetBundleManager を WebGL で使う・エラー対処法

【Unity】【C#】AssetBundleManager を WebGL で使う・エラー対処法  


 大体の動作はわかってきたので、Unity Technologies から出ている「AssetBundleManager」を WebGL で使う方法を書いておこう。ただアセットバンドルは WebGL プラットフォームでそのまま使用すると、実行環境でいくつか不具合が出るようだ。JavaScript のエラーが出たり、一部素材が抜けたりする現象が起こることがある。それらの回避方法も確認した。それらは正しいやり方ではないかもしれないが、とりあえず上手く動くようになったので、参考までに書いておこう。


(※) Unity 5.5.1f1 / Windows10(x64) で確認




■AssetBundleManager の警告を消す

 まずはじめに「AssetBundleManager」をアセットストアからダウンロードしよう。既にダウンロードしてあるなら、新規プロジェクトで「Add Asset Package」を押して「AssetBundle Manager Example Scenes」にチェックを入れておけば、自動で解凍して読み込まれる。

 もし、自分で修正するのが面倒だと思うなら、今回は unitypackage を用意した。これをダウンロードしてインポートしても良い。その場合は「■開発環境のサーバURLを設定する」まで読み飛ばしても良いだろう。

>>サンプルのスクリプトをダウンロード
(Google Drive を利用。画面右上にあるダウンロードアイコンを押す)

 最初に、Unity5.5以降の場合、インポート直後に obsolete 系(廃止予定・非推奨)の警告が出てるのではないだろうか。とりあえずこれを直してしまおう。内容的にはただ単に旧仕様を新仕様に変更するだけだ。

 具体的には
・シーン遷移が (旧)Application.LoadLevelXXX → (新) SceneManager.LoadSceneXXX (using UnityEngine.SceneManagement を追加しておく)になった。
・旧WebPlayerが5.4以降廃止になった。

これらを修正・コメントアウトすれば良いだけだ。MonoDevelop で開いて編集しよう(警告をダブルクリックでも開ける)。

●[旧] Application.LoadLevelAsync → [新] SceneManager.LoadSceneAsync に修正する

(警告内容)
Assets/AssetBundleManager/AssetBundleLoadOperation.cs(89,30): warning CS0618: `UnityEngine.Application.LoadLevelAdditiveAsync(string)' is obsolete: `Use SceneManager.LoadSceneAsync'
Assets/AssetBundleManager/AssetBundleLoadOperation.cs(91,30): warning CS0618: `UnityEngine.Application.LoadLevelAsync(string)' is obsolete: `Use SceneManager.LoadSceneAsync'

●Unity5.4 以降 WebPlayer の廃止 → コメントアウトすれば良い

(警告内容)
Assets/AssetBundleManager/Utility.cs(32,21): warning CS0618: `UnityEditor.BuildTarget.WebPlayer' is obsolete: `WebPlayer has been removed in 5.4'
Assets/AssetBundleManager/Utility.cs(59,25): warning CS0618: `UnityEngine.RuntimePlatform.OSXWebPlayer' is obsolete: `WebPlayer export is no longer supported in Unity 5.4+.'
Assets/AssetBundleManager/Utility.cs(60,25): warning CS0618: `UnityEngine.RuntimePlatform.WindowsWebPlayer' is obsolete: `WebPlayer export is no longer supported in Unity 5.4+.'
Assets/AssetBundleManager/Editor/BuildScript.cs(121,21): warning CS0618: `UnityEditor.BuildTarget.WebPlayer' is obsolete: `WebPlayer has been removed in 5.4'
Assets/AssetBundleManager/Editor/BuildScript.cs(122,21): warning CS0618: `UnityEditor.BuildTarget.WebPlayerStreamed' is obsolete: `WebPlayerStreamed has been removed in 5.4'


 ちなみに「#pramga」を使って強制的に消す方法もある。以下に参考資料を載せておこう。しかし、根本的な解決にはならないので、これから使うなら修正した方が良いかも知れない(廃止となった場合、エラーとなるため)。

(参考)
Warningメッセージを消す
#pragma warning 警告を有効または無効[Unity,Swarm]




■開発環境のサーバURLを設定する(Local Asset Server の代わりに XAMPP を使う)

 次にメニュー「Assets>AssetBundles>Local Asset Server」を動かしたいのだが、どうやら Windows10 ではセキュリティ関係でディフォルトでは上手く起動できないらしい。ちなみに権限設定や「Windowファイアウォールによるアプリケーションの許可」では効果なかった。

(エラー内容)
Win32Exception: ApplicationName='"C:/Program Files/Unity5/Editor\Data\MonoBleedingEdge\bin\mono.exe"', CommandLine='D:/unity5/AssetBundleManagerTest/Assets\AssetBundleManager/Editor/AssetBundleServer.exe "D:/unity5/AssetBundleManagerTest\AssetBundles" 14944', CurrentDirectory='D:\unity5\AssetBundleManagerTest\AssetBundles'
System.Diagnostics.Process.Start_noshell (System.Diagnostics.ProcessStartInfo startInfo, System.Diagnostics.Process process)
System.Diagnostics.Process.Start_common (System.Diagnostics.ProcessStartInfo startInfo, System.Diagnostics.Process process)
System.Diagnostics.Process.Start (System.Diagnostics.ProcessStartInfo startInfo)
AssetBundles.LaunchAssetBundleServer.Run () (at Assets/AssetBundleManager/Editor/LaunchAssetBundleServer.cs:86)
AssetBundles.LaunchAssetBundleServer.ToggleLocalAssetBundleServer () (at Assets/AssetBundleManager/Editor/LaunchAssetBundleServer.cs:27)


 少し面倒くさそうだったので(笑)、XAMPP を使ってみることにした。ローカルサーバ(AssetBundleServer.exe)が起動できたなら、そのまま使っても良い。XAMPP で使う場合は、プロジェクトビューで「Assets>AssetBundleManager>Editor」にある「BuildScript.cs」を開いて「overloadedDevelopmentServerURL」に XAMPP でアクセスするURLを書き込もう。IPアドレスでも良いが、簡単なのは「http://localhost/~」で書いておけば、PCに関係なく使える。URL はプラットフォーム用のフォルダ名を除いたルートで、この階層以下に「WebGL」「Android」「iOS」などのフォルダが置かれることになる。XAMPP をインストールする必要がある場合は以下の記事などを参考にすれば良い。インストールできたら、「Apache」だけ起動すれば良い。

今さら聞けない!XAMPPをインストールする方法【超初心者向け】

●「BuildScript.cs」


 XAMPP を使う場合はもう1つ URL を書き換えておくファイルがある。プロジェクトビューで「Assets>AssetBundleManager>Resources>AssetBundleServerURL.bytes」を探し、これにも同じように開発環境のサーバURL「http://localhost/~」を書いておこう。この作業はローカルサーバ(AssetBundleServer.exe)を使うときには必要ない。自動で「自身のIPアドレス:7888」に書き換えられるようだ。ちなみに「BuildScript.cs」の「overloadedDevelopmentServerURL」を書き換えておくと、「AssetBundleServerURL」の URL が更新される。つまりこのファイルに書かれている URL を開発用サーバとして使用するようになっているわけだ。これらは1度設定しておけば良い。




※URL は任意で良い(開発用サーバに適当にフォルダを作る)




■アセットバンドルのビルド・ビルド先フォルダの指定

 ここまでできたら、実際に AssetBudle をビルドしてみよう。その前にビルドするプラットフォームを選択して置かなければならない。メニューから「File>Build Setting...」を開いて、「WebGL」をクリックし、「Switch Platform」を押そう。この設定は他のプラットフォームに変更しない場合は、ずっとそのままで良い。



 ビルドするアセットだが、自分で作った素材でも良いが、サンプルに入っている「AssetBundleSample」をそのまま使ってみよう。これなら、メニューから「Assets>AssetBundleManager>Build AssetBudles」を実行するだけで良い。

 しばらくしたら、プロジェクトのあるフォルダの「AssetBundles」を開けば(プロジェクトビューで右クリック>「Show in Explorer」(エクスプローラ)で「Assets」の1つ上の階層にいくと見える)、「WebGL」のフォルダの中にアセットバンドルが作成されているハズだ。ちなみにこの出力パスは「Assets/AssetBundleManager/Utility.cs」を開いて「AssetBundlesOutputPath」を書き換えれば変更できる。例えば「Assets/AssetBundles」と書き換えればプロジェクトビューからも見えるようになる(ただし *.meta ファイルなども自動で作られるようになるが。また初回はフォルダが認識されるまで出てこないことがあるが、しばらくすれば(フォーカスが変更されれば)出てくる)。

●「Utility.cs」



※フォルダを変更した場合




■開発環境でのプレイと Simulation Mode

 そして先ほど作ったアセットバンドルをサーバに置いてみよう。プロジェクトビューで右クリック>「Show in Explorer」でエクスプローラを開いて、開発用サーバ(「overloadedDevelopmentServerURL」で指定したサーバ)のフォルダにコピーすれば良い(WebGLフォルダをまるごとコピーする。ただし *.meta ファイルは必要ない [例:D:\public_html\AssetBundles\test\WebGL のようになる] )。

 あとはプロジェクトビューで「Assets>AssetBundleSample>Scenes」以下にあるシーンを読み込んでプレイしてみよう。画面に素材が表示されれば成功だ。ちなみにコンソールに「[AssetBundleManager] Simulation Mode: Enabled」と出ていたら、メニュー「Assets>AssetBundles>Simulation Mode」がオンになっていて、サーバからではなくローカルから素材が読み込まれている。サーバからのダウンロードでテストをしたいときは、「Simulation Mode」をオフにすると良い(「[AssetBundleManager] Simulation Mode: Disabled」になる)。






■実行環境でのプレイ(WebGL出力)

 最後に WebGL でビルドして、開発環境ではなく実行環境で試してみたいと思う。今回は添付されているサンプルを使うことにするが、少しだけコードを修正(設定)しておく必要がある。これからテストするシーンに使われているスクリプト:例えばシーン「Assets/AssetBundleSample/Scenes/AssetLoader.unity」を開いてみよう。







 シーンを開いてみると、アセットバンドルを読み込むスクリプトとして「Loader」という GameObject に「Load Assets (Script)」がアタッチされている。これを開いて(MonoDevelop で「AssetBundleSample/Scripts/LoadAsset.cs」)「Initialize()」という関数の中にある実行環境のサーバURLを指定する部分を書き換えよう。具体的には「AssetBundleManager.SetSourceAssetBundleURL(Application.dataPath + "/")」の方はコメントアウトして、下にある「AssetBundleManager.SetSourceAssetBundleURL("http://www.MyWebsite/MyAssetBundles")」のURLを実行環境のURLに変更する。ここでは簡略のため開発環境と同じURLを書いておくが、実際には定数か変数にして、設定ファイルのようなものに書いた方が良いだろう(また実行環境のサーバにはアセットバンドルをダウンロードさせるために http.conf または .htaccess の設定が必要になるかもしれない)。またこれはそれぞれのサンプルシーン「SceneLoader」「TanksLoader」「VariantLoader」でも同じだ(スクリプトはそれぞれ「LoadScenes.cs」「LoadTanks.cs」「LoadVariants.cs」になる)。

●「LoadAssets.cs」



 修正できたら、メニュー「File>Build Settings...」から現在のシーン(テストするシーン)を追加(「Add Open Scene」)→「Build」で WebGL に書き出してみる。出力されたらフォルダごと実行環境のサーバに置いて、ブラウザでアクセスして動作を確認してみよう。




あれ?何かエラー出てる…




■実行環境(WebGL)での JavaScript のエラーを回避する

 ここまで順を追って作ってきた場合、もしかしたら上の画像のようなエラーダイアログが出たのではないだろうか。実はアセットバンドルのような部品化するに際して、気をつけなくてはいけないのは、「ストリッピング」によって、未使用の機能が最適化で削除されてしまう点だ。つまり、アセットバンドルには含まれているが、ビルドするアプリには含まれていない機能がある場合、不要なものとして削られてしまう。そして読み込まれたアセットバンドルで使おうとしてエラーが出る…そんな感じだ。

 というわけで、まずは「ストリッピング」をしないように設定しよう。メニューから「Edit>Project Settings>Player」で「Player Settings」が開くので(「File>Build Settings...」でダイアログ下の「Player Settings...」でも同じ)、インスペクタで「Other Settings」をクリックし、その中の「Strip Engine Code」をオフにしよう。これでストリッピング機能は無効になる。


 ストリッピング機能をオフにしたら、再度 WebGL ビルドしてみよう。ビルドし終わったらサーバにアップして、ブラウザで確認してみよう。今度はちゃんと表示されたハズだ(※ブラウザのキャッシュに注意。面倒なら別のフォルダにアップしても良い)。



 「特定のエンジンコードをストリップさせない」「link.xml でストリップするエンジンコードを指定する」など、この他のストリッピングのやり方は以下のURLを参照して欲しい。非常に詳しく書いてある。

(参考)
【Unity】Unity 5.3からAssetBundleはどう変わるのか…まとめ - AssetBundleにのみ使われているクラスがある場合の注意
[Unityマニュアル] WebGL プロジェクトの作成と実行 - ストリッピング




■実行環境(WebGL)で表示されない素材などに対処する

 もう1つ、「エラーは出ないが、ある素材が表示されない」類の対処法を書いておこう。例えば、サンプルに入っている「TanksLoader」を同じように WebGL ビルドしてみよう。すると以下のように選択した文字(言語 [English/Danish])が表示されないという現象が起きる。


 実際に「Strip Engine Code をオフ」や「link.xml を作る」「シェーダーストリッピング」などをやってもなぜか効果がなかった。

 ただ何となく最適化の弊害のような気がしたので、「足りないなら付け足してしまえ」的な方法で回避できた。例えばこの例の場合、文字列は UI-Text を用いているので、シーン内に「GameObject>UI>Text」を非表示にして追加しておけば良い。

 実際に運用するには、ダミーのシーンを新しく作って、足りないと思われるオブジェクト(コンポーネント)を空でも良いので追加しておく。そしてメニューから「File>Build Settings...」で、このダミーのシーンを「Scenes In Build」の一番後ろにでも追加しておけば良い。プロジェクトで共有できる利点もある。あまりスマートなやり方ではないが、これなら最適化で削除されることは確実にない(笑)。

●ダミーのシーンを作り、UI-Text (足りないと思われるコンポーネント)を入れておく


●ダミーのシーンを含めてビルドする



 ただあまりダミーシーンに色々追加するとファイルサイズ大きくなってしまって、そもそもアセットバンドルとして分離する意味が無くなってしまうけどね。けど素材を変更したいときなどは、削除・追加すれば良いだけなので、管理が簡単なのもメリットかも。設定でできるならそれに越したことはないが…。


 また同じ考え方で、ダミーのスクリプトを作って、コンポーネントを参照する手もある。例えばこの UI-Text を使っているとわかっている場合、以下のようなスクリプトを作っておけば、テキストが正常に表示できる。

using UnityEngine.UI;

public class Dummy {

#pragma warning disable 0414

Text text; //足りないと思われるコンポーネントを使用しておくことで、最適化で削除されなくなる

}

 なお、「#pragma warning disable 0414」は、警告「warning CS0414: The private field `text' is assigned but its value is never used」(プライベート変数 text が一度も使われてないよ)」を消しているだけだ。

 スクリプトは作っておくだけで良い。またスクリプトはバンドル化されず、プロジェクト共有で利用されるようだ(シェーダなども内容的にはスクリプトなので共有っぽい)。どのコンポーネントが足りないのかが確実にわかっているなら、ダミーのオブジェクトより、ダミーのスクリプトの方がファイルサイズが小さくなるのでオススメだ。他の方法も試したければ、以下の記事などを参考にすると良い。

(参考)
【Unity】Unity 5.3からAssetBundleはどう変わるのか…まとめ - AssetBundleにのみ使われているクラスがある場合の注意


 ついでなので、「TanksLoader」を WebGL 出力したときのサイズ比較を載せておこう。「Strip Engine Code オフ」と UI-Text をシーンに置いたり、スクリプトで参照したりしてみた比較だ。



 ともかく「アセットバンドルは部品のようにバラバラに圧縮保存され、実行時に解凍されて再結合される」のような仕組みを覚えておけば、何となく「足りないものがある」と予測できるハズだ。とりあえずの方法だが役に立てば嬉しい。以下は既知の WebGL での問題らしく、環境や条件、バンドルの作り方などによって出たり出なかったりする。参考までに載せておこう。




■ダウンロード中にフリーズしたようになる

 これは「効率の良いアセットバンドルの固め方は?」と実質同じ内容になるのだが、アセットバンドルを作るとき(名前を割り当てるとき)、メッシュ、マテリアル、テクスチャ、アニメータ、アニメーション、音声ファイルなど個別にバンドル化するか、それともまとめてフォルダなどでバンドル化するか(実際には同じフォルダでなくても、同じ名前さえ付ければ1つにまとまる)を考えることと同じになる。

 実際にあまり細かくバンドル化すると、ダウンロードしているときにフリーズしたように戻ってこなくなるようだ。特にマテリアルとテクスチャに別々の名前を付けてバンドル化して(つまり別々のバンドルとして)、ダウンロード後は1つのオブジェクト(プレファブ)として使用する場合、テクスチャがピンクになったり、フリーズしたように止まったままになってしまう事がある。しかしほとんどの場合、あるモデルに対してテクスチャやマテリアル、メッシュはそれ専用で使うことが多いので、そういった素材はまとめてバンドル化した方が良いようだ。またその方がダウンロードのリクエスト回数が少なくて済むため、効率良く読み込める利点もある。

 なお、それぞれの素材は依存関係を自動で解決して(コピーして)バンドル化されるので、マテリアルをバンドルに含めれば必要な個々のテクスチャなども自動でバンドル化、アニメータをバンドルに含めれば個々のアニメーションも自動でバンドル化されるようになる。特にアニメーションなどは FBX ファイルなどに含まれてることが多いが、その FBX をバンドルに含めるとファイルサイズが大きくなってしまうので、アニメータだけをバンドル化する方がファイルサイズが小さくて済む(FBX 内の必要なアニメーションだけをコピーしてバンドル化してくれる)。つまり、共有する素材がない場合、それを参照する大本の素材をまとめるのが一番効率が良い。またプレファブをバンドル化しても効果ないので、素材だけをバンドル化するだけで十分のようだ。私が色々なパターンでバンドル化して試した所、モデルに対して「メッシュ・マテリアル・アニメータ」をまとめて1つのバンドル、音楽ファイルを曲ごとバンドル(ファイルサイズが小さいならある程度まとめても良い)、常に使う効果音などをまとめて1つのバンドルにしたとき、ファイルサイズも小さく、ダウンロードも速かった。またそのようにしたら、ダウンロード中のフリーズも無くなった。ただシーンだけは他のものと一緒にバンドル化できず、個別にするしかないようだ(そういう仕様らしい)。




■シェーダー参照が壊れる

 アセットバンドルで色々部品化していると、稀にシェーダー参照が外れてテクスチャがピンクになること素材がある。そのときは以下のURLの方法で直る場合もある。

(参考)
【Unity】AssetBundle化したPrefabのシェーダー参照が壊れる現象
【Unity】AssetBundleに格納したSceneやPrefabがピンクになる問題

 あと私が試して修正できた方法は、メニューから「Edit>Project Settings>Graphics」で「Always Included Shaders」に必要なシェーダを入れておくことだ。これが上手くいく場合、上のURLの「Shader.Find()」は必要なくなる。だだ、ここに登録するとファイルサイズとコンパイル時間が増えるので注意。単にダウンロードに時間がかかり過ぎて、上手く再結合できなかっただけなら、リロードすれば次は成功する。

(参考)
[Unityマニュアル] シェーダーストリッピング




■エディタで音声の再生で失敗する

Error: Cannot create FMOD::Sound instance for resource archive:/BuildPlayer-Title/BuildPlayer-Title.resource, (Unsupported file or audio format. )

 Unity エディタのバージョンによっても症状が違うらしい。バンドルでの圧縮形式とエディタ上でのサポートフォーマットの違いによって出ているみたいなので、ビルドしたものはエラーは出ない。「Import Setting」で直ったというコメントもあるが、Unity5.5では上手く行かなかったので、とりあえず保留。

(参考)
Problem --- Cannot create FMOD::Sound instance for resource in Webgl Build/Editor





(関連記事)
【Unity】【C#】アセットバンドルのキャッシュを調べて不要なものを消す
【Unity】【C#】Addressable Assets でキー(アドレス)の存在(登録)を調べる
【Unity】【C#】Android実機でエラーログをファイルに書き出す
【Unity】5.6 の Canvas の警告:Shader channels Normal and Tangent are most often used with lighting~ を消す
【Unity】Japanese Otaku City(秋葉原モデル)のピンクテクスチャの修正方法


スポンサーサイト

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  C#  Unityトラブルシューティング 
tb: 0   cm: --



トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/237-7cceddda
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop