标签:
之前说了 “Unity5.x版本AssetBundle打包研究”,没看过的请先看一下:http://www.shihuanjue.com/?p=57
再来看本文,有一定的连接性。
先梳理一下思路:
要加载一个资源A,必须先去加载它的所有依赖资源
要知道这个资源A依赖了哪些资源,必须先去加载AssetBundleManifest
通过AssetBundleManifest对象的GetAllDependencies(A)方法,获取它依赖的所有资源。
依赖资源都加载了,就可以去真正加载资源A了。
注意点:
1.资源A加载完了后,要记得Unload(false),资源A的依赖资源要在 资源A加载完成后,才能Unload(false),否则无法正常加载资源A
2.不Unload的话也可以,那就自己做一个字典记录所有加载过的AssetBundle,还有它们的引用计数器。那样就可以先判断是否存在,然后再确定是否要去加载。
我下面的例子,采用1的方式。就是加载完了后就Unload的方式。
上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class AssetBundleLoaderMgr : Singleton<AssetBundleLoaderMgr> { public string m_assetPath = Application.streamingAssetsPath; string assetTail = ".unity3d"; #region LoadAssetBundle /// <summary> /// 加载目标资源 /// </summary> /// <param name="name"></param> /// <param name="callback"></param> public void LoadAssetBundle(string name, Action<UnityEngine.Object> callback) { name = name + assetTail;//eg:ui/panel.unity3d Action<List<AssetBundle>> action = (depenceAssetBundles) => { string realName = this.GetRuntimePlatform() + "/" + name;//eg:Windows/ui/panel.unity3d LoadResReturnWWW(realName, (www) => { int index = realName.LastIndexOf("/"); string assetName = realName.Substring(index + 1); assetName = assetName.Replace(assetTail, ""); AssetBundle assetBundle = www.assetBundle; UnityEngine.Object obj = assetBundle.LoadAsset(assetName);//LoadAsset(name),这个name没有后缀,eg:panel //卸载资源内存 assetBundle.Unload(false); for (int i = 0; i < depenceAssetBundles.Count; i++) { depenceAssetBundles[i].Unload(false); } //加载目标资源完成的回调 callback(obj); }); }; LoadDependenceAssets(name, action); } /// <summary> /// 加载目标资源的依赖资源 /// </summary> /// <param name="targetAssetName"></param> /// <param name="action"></param> private void LoadDependenceAssets(string targetAssetName, Action<List<AssetBundle>> action) { Debug.Log("要加载的目标资源:" + targetAssetName);//ui/panel.unity3d Action<AssetBundleManifest> dependenceAction = (manifest) => { List<AssetBundle> depenceAssetBundles = new List<AssetBundle>();//用来存放加载出来的依赖资源的AssetBundle string[] dependences = manifest.GetAllDependencies(targetAssetName); Debug.Log("依赖文件个数:" + dependences.Length); int length = dependences.Length; int finishedCount = 0; if (length == 0) { //没有依赖 action(depenceAssetBundles); } else { //有依赖,加载所有依赖资源 for (int i = 0; i < length; i++) { string dependenceAssetName = dependences[i]; dependenceAssetName = GetRuntimePlatform() + "/" + dependenceAssetName;//eg:Windows/altas/heroiconatlas.unity3d //加载,加到assetpool LoadResReturnWWW(dependenceAssetName, (www) => { int index = dependenceAssetName.LastIndexOf("/"); string assetName = dependenceAssetName.Substring(index + 1); assetName = assetName.Replace(assetTail, ""); AssetBundle assetBundle = www.assetBundle; UnityEngine.Object obj = assetBundle.LoadAsset(assetName); //assetBundle.Unload(false); depenceAssetBundles.Add(assetBundle); finishedCount++; if (finishedCount == length) { //依赖都加载完了 action(depenceAssetBundles); } }); } } }; LoadAssetBundleManifest(dependenceAction); } /// <summary> /// 加载AssetBundleManifest /// </summary> /// <param name="action"></param> private void LoadAssetBundleManifest(Action<AssetBundleManifest> action) { string manifestName = this.GetRuntimePlatform(); manifestName = manifestName + "/" + manifestName;//eg:Windows/Windows LoadResReturnWWW(manifestName, (www) => { AssetBundle assetBundle = www.assetBundle; UnityEngine.Object obj = assetBundle.LoadAsset("AssetBundleManifest"); assetBundle.Unload(false); AssetBundleManifest manif = obj as AssetBundleManifest; action(manif); }); } #endregion #region ExcuteLoader public void LoadResReturnWWW(string name, Action<WWW> callback) { string path = "file://" + this.m_assetPath + "/" + name; Debug.Log("加载:" + path); StartCoroutine(LoaderRes(path, callback)); } IEnumerator LoaderRes(string path, Action<WWW> callback) { WWW www = new WWW(path); yield return www; if (www.isDone) { callback(www); } } #endregion #region Util /// <summary> /// 平台对应文件夹 /// </summary> /// <returns></returns> private string GetRuntimePlatform() { string platform = ""; if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) { platform = "Windows"; } else if (Application.platform == RuntimePlatform.Android) { platform = "Android"; } else if (Application.platform == RuntimePlatform.IPhonePlayer) { platform = "IOS"; } else if (Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXEditor) { platform = "OSX"; } return platform; } } #endregion |
测试一下咯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using UnityEngine; using System.Collections; using System.Collections.Generic; public class TestAssetBundleLoader : MonoBehaviour { Dictionary<string, GameObject> GameObjectPool = new Dictionary<string, GameObject>(); void Start() { //要加载的资源的队列 Queue<string> needLoadQueue = new Queue<string>(); needLoadQueue.Enqueue("ui/plane"); needLoadQueue.Enqueue("ui/cube"); needLoadQueue.Enqueue("ui/sphere"); Load(needLoadQueue); } void Load(Queue<string> needLoadQueue) { if (needLoadQueue.Count > 0) { string needLoadAssetName = needLoadQueue.Dequeue(); AssetBundleLoaderMgr.Instance.LoadAssetBundle(needLoadAssetName, (obj) => { GameObject go = GameObject.Instantiate(obj) as GameObject; int index = needLoadAssetName.LastIndexOf("/"); string assetName = needLoadAssetName.Substring(index + 1); //加载出来的GameObject放到GameObjectPool存储 GameObjectPool.Add(assetName, go); Load(needLoadQueue); }); } else { Debug.Log("all finished"); } } } |
可能代码写的还有很多优化的地方 ,毕竟100个人有100种写法,思路才是最重要的。你说呢?
其实我想说的是,代码都在了,自己尝试一下吧!
标签:
原文地址:http://www.cnblogs.com/joeshifu/p/4889579.html