業務上、AssetBundleを管理することになったので一から勉強します。
AssetBundleとはなんぞや?という場合は下記がわかりやすいです。
http://docs-jp.unity3d.com/Documentation/Manual/AssetBundlesIntro.html
AssetBundleの作成
Assets
├── Editor
├── ExportAssetBundles.cs
上記のようなフォルダ構成で下記ファイルしEditor拡張します。
using UnityEngine;
using UnityEditor;
public class ExportAssetBundles {
[MenuItem("Assets/Building")]
static void ExportResourceNoTrack () {
string path = EditorUtility.SaveFilePanel ("Save Resource", "", "Test", "unity3d");
if (path.Length != 0) {
BuildPipeline.BuildAssetBundle(
Selection.activeObject,
Selection.objects, path);
}
}
}
適当なGameObjectを作成 → Prefab化 → Prefabを右クリック → Building
にて作成します。
作成したものはWebサーバなどダウンロードサーバに適当に配置します。
ここでは"Test.unity3d"というものを作成しローカルのWebサーバのstaticに配置してみました。
AssetBundleのダウンロード・インスタンス化(キャッシュなし)
最小構成
まずは理解しやすいように最小構成でやってみます。
下記スクリプトをシーン上の適当なオブジェクトにアタッチして実行すると、上記手順で作成したものが表示されるはずです。
using UnityEngine;
using System.Collections;
public class UseAssetBundle : MonoBehaviour {
IEnumerator Start () {
WWW www = new WWW("http://localhost:8000/m/static/Test.unity3d");
yield return www;
Instantiate(www.assetBundle.mainAsset);
}
}
しかし、上記はエラーが処理が全く入っていないので実用的ではありません。
エラー対応
using UnityEngine;
using System.Collections;
using System;
public class UseAssetBundle : MonoBehaviour {
IEnumerator Start () {
WWW www = new WWW("http://localhost:8000/m/static/Test.unity3d");
yield return www;
if (www.error != null) {
throw new Exception("WWW Error: " + www.error);
}
AssetBundle bundle = www.assetBundle;
if (bundle == null){
throw new Exception("bundle is Null.");
}
Instantiate(www.assetBundle.mainAsset);
}
}
自分の環境でエラー原因は下記がありました。
通信エラー
WWW Errorのところで
Rejected because no crossdomain.xml policy file was found
となった場合は
http://qiita.com/okuhiiro/items/cdab95604b61cb189ad6
を参照ください。ファイルがない
WWW Errorのところで404 NOT FOUND
となった場合は、多分ファイルが存在しない可能性があります。ファイルがなんかおかしい
"bundle is Null"となる場合は、ファイルは存在するがなんか形式がおかしいとかでAssetBundleオブジェクト化できなかったりする可能性があります。
最適化
usingとbundle.Unloadを追加しました。
いろいろメモリ周りの最適化を図りました。
using UnityEngine;
using System.Collections;
using System;
public class UseAssetBundle : MonoBehaviour {
IEnumerator Start () {
using(WWW www = new WWW("http://localhost:8000/m/static/Test.unity3d"))
{
yield return www;
if (www.error != null) {
throw new Exception("WWW Error: " + www.error);
}
AssetBundle bundle = www.assetBundle;
if (bundle == null){
throw new Exception("bundle is Null.");
}
Instantiate(www.assetBundle.mainAsset);
bundle.Unload(false);
}
}
}
AssetBundleのダウンロード・インスタンス化(キャッシュあり)
WWW.LoadFromCacheOrDownloadを使うとキャッシュするのでよいらしい。
while(!Caching)〜もあったほうがよいっぽい。
using UnityEngine;
using System.Collections;
using System;
public class UseAssetBundle1 : MonoBehaviour {
IEnumerator Start (){
using(WWW www = WWW.LoadFromCacheOrDownload ("http://localhost:8000/m/static/Test.unity3d", 1))
{
yield return www;
while (!Caching.ready) yield return null;
if (www.error != null) {
throw new Exception("WWW Error: " + www.error);
}
AssetBundle bundle = www.assetBundle;
if (bundle == null){
throw new Exception("bundle is Null.");
}
Instantiate(www.assetBundle.mainAsset);
bundle.Unload(false);
}
}
}