1.通常把项目中用到的所有Shader打到一个ab包里,在资源调用时首先加载所有Shader,因为项目中很多资源引用了Shader; 2.把一些共同引用的资源打到同一个包里,比如UIA用了materialC,UIB也用了materialC,UIA,UIB还用到了TexC,那么我们把materialC,TexC打到同一个包里,我们使用UIA或UIB时首先加载他们的引用包(也就是materialC和TexC所在的AB包) 3.然后所有Lua脚本类的打到同一个包里面 4.所有的字体可以打成同一个包,所有的例子特效单独一个包;
一些重要信息都在AssetBundleManifest,比如资源依赖,路径等信息,所以加载AssetBundle前,先要记载读取AssetBundleManifest的信息,读取完之后就没用了,我们把它卸载掉,节省内存空间
AssetBundle abManifestBundle = AssetBundle.LoadFromFile(GetFullLoadAbPath("AssetBundles")); abManifest = abManifestBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); abManifestBundle.Unload(false);我们从目标AssetBundle包里加载Asset进行实例化的时候,首先检查这个AB资源包的引用,先加载引用
比如UIA用了materialC,UIB也用了materialC,UIA,UIB还用到了TexC,那么我们把materialC,TexC打到同一个包里,我们使用UIA或UIB时首先加载他们的引用包(也就是materialC和TexC所在的AB包)
,当所有的相关应用加载完毕,再加载目标AssetBundle,最后LoadAsset我们所需要的打包在该AB包里面的内容。
但是这样存在一个问题,就是一个AB包里可能有很多资源,我们加载这些资源的时候,可能会出现重复加载同一个AssetBundle包的情况,这很费时间,所以我们要把加载过的AssetBundle存在内存中,每次加载AB包时判断该AB包是否已经加载过了,如果加载过了,那么它是被我们保存在内存中了,我们直接在内存中读取,这样会快很多。
public AssetBundle LoadAssetBundle(string resPath, bool unloadbundle = false) { resPath = resPath.ToLower(); // string abPath = resPath.Replace("/", "_"); string abPath = resAbMap[resPath]; if (!cacheMap.ContainsKey(abPath) || (cacheMap[abPath].request != null && cacheMap[abPath].request.assetBundle == null)) { List<string> deps = GetAllDependencies(abPath); bool depAllLoaded = true; for (int i = 0; i < deps.Count; i++) { if (!cacheMap.ContainsKey(deps[i]) || (cacheMap[deps[i]].request != null && cacheMap[deps[i]].request.assetBundle == null)) { AssetBundle depAb = AssetBundle.LoadFromFile(GetFullLoadAbPath(deps[i])); if (cacheMap.ContainsKey(deps[i])) { cacheMap[deps[i]].assetBundle = depAb; } else { cacheMap[deps[i]] = new AssetBundleCacheInfo(null, depAb); } if (depAb == null) { depAllLoaded = false; break; } } } if (depAllLoaded) { string fullPath = GetFullLoadAbPath(abPath); AssetBundle needLoadBundle = AssetBundle.LoadFromFile(fullPath); if (needLoadBundle != null) { if (cacheMap.ContainsKey(abPath)) { cacheMap[abPath].assetBundle = needLoadBundle; } else { cacheMap[abPath] = new AssetBundleCacheInfo(null, needLoadBundle); } } else { Debug.LogWarning("load ab fail:" + fullPath); } } } if (cacheMap.ContainsKey(abPath)) { if (cacheMap[abPath].assetBundle == null) { if (cacheMap[abPath].request != null) { cacheMap[abPath].assetBundle = cacheMap[abPath].request.assetBundle; } } return cacheMap[abPath].assetBundle; } else { return null; } }为了加快加载资源的速度,我们同样也将已经加载过的资源保存在内存中,加载之间判断内存中是否存在,存在则直接读取内存中的资源,不存在则加载资源然后将其保存在内存中,供下次读取。 我们每次加载资源时,都先要加载其所在的AssetBundle包,并且要记下加载资源AB包被引用的次数,这样方便我们在卸载AssetBundle时,检测当前这个要卸载的AssetBUndle包还有没有资源引用它,如果没有资源引用,我们才启用UnLoad卸载该AssetBundle
未完待续…
