Unity5系列资源管理AssetBundle——加载
2015-10-07 20:32
841 查看
上次我们进行了AssetBundle打包,现在我们还把打包的资源加载到我们的游戏中。
在加载之前,我们需要把打包好的Bundle包裹放到服务器上,如果没有,也可以使用XAMPP搭建本地服务器。
加载的AssetBundle文件是放在内存中的,所以如果没有很好的管理,会使游戏性能大打折扣,因此,我们在这里最好使用缓存策略。
我们的AssetBundle:
AssetBundle管理:
缓存管理:
加载包裹中的场景:
新建一个场景,创建TestScript脚本,放到摄像机上。
加载包裹中的游戏对象等资源到场景中:
在上面的测试脚本中,修改部分代码。
在加载之前,我们需要把打包好的Bundle包裹放到服务器上,如果没有,也可以使用XAMPP搭建本地服务器。
加载的AssetBundle文件是放在内存中的,所以如果没有很好的管理,会使游戏性能大打折扣,因此,我们在这里最好使用缓存策略。
我们的AssetBundle:
using System; using UnityEngine; namespace MrCAssetFramework { public sealed class MrCAssetBundle { internal AssetBundle m_AssetBundle; internal string m_AssetBundleName; internal MrCAssetBundle(AssetBundle assetBundle,string name) { this.m_AssetBundle = assetBundle; this.m_AssetBundleName = name; this.m_ReferencedCount = 1; } #region ReferenceCountManage //yinyongjishujizhi private int m_ReferencedCount; public void Retain() { this.m_ReferencedCount++; } public void Release(){ this.m_ReferencedCount--; //当引用计数为0时,卸载资源 if (this.m_ReferencedCount == 0) { this.m_AssetBundle.Unload (true); MrCAssetCache.FreeBundle(this.m_AssetBundleName); } } public int RetainCount() { return this.m_ReferencedCount; } #endregion } }
AssetBundle管理:
using System; using UnityEngine; using System.Collections; using System.Collections.Generic; namespace MrCAssetFramework { public class MrCAssetManager:MonoBehaviour { #region Singleton private static GameObject s_go_MrCAssetManager = null; private static MrCAssetManager s_MrCAssetManager = null; public static MrCAssetManager DefaultAssetManager{ get{ if (s_MrCAssetManager == null) { s_go_MrCAssetManager = new GameObject ("LOAssetManager"); s_MrCAssetManager = s_go_MrCAssetManager.AddComponent<MrCAssetManager> (); } return s_MrCAssetManager; } } #endregion public static string URI{ set; get;} public static string ManifestName{ set; get;} //无返回值泛型委托.. public static Action<bool> InitBlock; public AssetBundleManifest manifest{ set; get;} ///<summary> /// To get the asset.. /// </summary> /// <returns>The asset..</returns> public T GetAsset<T>(string assetbundlename,string assetname) where T:UnityEngine.Object { MrCAssetBundle lab = MrCAssetCache.GetBundleCache(assetbundlename); if (lab == null) { return null; } else { return lab.m_AssetBundle.LoadAsset<T>(assetname); } } IEnumerator LoadManifestBundle() { //缓存中已经存在请求的bundle,中止.. if (MrCAssetCache.InCache(MrCAssetManager.ManifestName)) { yield break; } // 通过网络下载AssetBundle WWW www = IsLoadAssetBundleAtInternal(MrCAssetManager.ManifestName); yield return www; this.manifest = this.GetAsset<AssetBundleManifest>(MrCAssetManager.ManifestName,"AssetBundleManifest"); MrCAssetManager.InitBlock (this.manifest != null); } void Start() { StartCoroutine ("LoadManifestBundle"); } #region 加载包裹系列函数 ///<summary> /// 检查是否已经从网络下载 /// </summary> protected WWW IsLoadAssetBundleAtInternal (string assetBundleName) { //已经存在了呀 MrCAssetBundle bundle = MrCAssetCache.GetBundleCache(assetBundleName); if (bundle != null) { //保留数加一次 bundle.Retain (); return null; } //如果WWW缓存策略中包含有对应的关键字,则返回true if (MrCAssetCache.InCache (assetBundleName)) { return null; } //创建下载链接 WWW www = new WWW(MrCAssetManager.URI + assetBundleName); // 按版本号,按需要通过网络下载AssetBundle,一般在正式游戏版本中,不使用上面的,因为它会每次打开游戏重新下载 //WWW www = WWW.LoadFromCacheOrDownload(LOAssetManager.URI + assetBundleName, nowVersion); //加入缓存策略 MrCAssetCache.SetWWWCache(assetBundleName,www); return www; } IEnumerator LoadDependencies(string assetBundleName) { if (this.manifest == null) { yield return null; } // 获取依赖包裹 string[] dependencies = this.manifest.GetAllDependencies(assetBundleName); Debug.Log(dependencies.Length); if (dependencies.Length == 0) { yield return null; } // 记录并且加载所有的依赖包裹 MrCAssetCache.SetDependCache(assetBundleName, dependencies); for (int i = 0; i < dependencies.Length; i++) { yield return IsLoadAssetBundleAtInternal (dependencies [i]); } } 136 /// <summary> /// 加载资源包 /// </summary> IEnumerator LoadAssetBundle(string assetBundleName) { if (MrCAssetCache.InCache(assetBundleName)) { yield break; } // 通过网络下载AssetBundle WWW www = IsLoadAssetBundleAtInternal(assetBundleName); yield return www; // 通过网络加载失败,下载依赖包裹 yield return StartCoroutine(LoadDependencies(assetBundleName)); } ///<summary> /// 异步加载资源 /// </summary> public IEnumerator LoadAssetAsync (string assetBundleName, string assetName, System.Type type) { //开始加载包裹 yield return StartCoroutine(LoadAssetBundle (assetBundleName)); } ///<summary> /// 异步加载场景 /// </summary> public IEnumerator LoadLevelAsync (string assetBundleName, string levelName, bool isAdditive) { //加载资源包 yield return StartCoroutine(LoadAssetBundle (assetBundleName)); } #endregion #region Update void Update() { MrCAssetCache.Update(); } #endregion } }
缓存管理:
using System; using System.Collections.Generic; using UnityEngine; namespace MrCAssetFramework { internal sealed class MrCAssetCache { #region 包裹缓存机制 //创建缓存字典 private static Dictionary<string, MrCAssetBundle> assetBundleCache; //缓存字典属性 private static Dictionary<string, MrCAssetBundle> BundleCache { get{ if (assetBundleCache == null) { assetBundleCache = new Dictionary<string, MrCAssetBundle> (); } return assetBundleCache; } } //创建缓存WWW对象 private static Dictionary<string, WWW> wwwCache; //创建缓存WWW对象属性 private static Dictionary<string, WWW> WwwCache{ get{ if (wwwCache == null) { wwwCache = new Dictionary<string, WWW> (); } return wwwCache; } } //创建依赖缓存对象 private static Dictionary<string, string[]> dependCache; //创建依赖缓存属性 private static Dictionary<string, string[]> DependCache { get{ if (dependCache == null) { dependCache = new Dictionary<string, string[]> (); } return dependCache; } } private static Dictionary<string, string> errorCache; private static Dictionary<string,string> ErrorCache{ get{ if (errorCache == null) { errorCache = new Dictionary<string, string> (); } return errorCache; } } ///<summary> /// Instantiate the cache. /// </summary> /// <returns><c>true</c>, if cache was ined, <c>false</c> otherwise.</returns> /// <param name="assetbundlename">Assetbundlename.</param> internal static bool InCache(string assetbundlename) { return MrCAssetCache.BundleCache.ContainsKey(assetbundlename); } #endregion #region 卸载系列函数 ///<summary> /// 卸载资源包和依赖包 /// </summary> /// <param name="assetBundleName">Asset bundle name.</param> public static void UnloadAssetBundle(string assetBundleName) { UnloadAssetBundleInternal (assetBundleName); UnloadDependencies (assetBundleName); } internal static void UnloadDependencies(string assetBundleName) { string[] dependencies = null; //获取所有的依赖包名称 if (!MrCAssetCache.DependCache.TryGetValue(assetBundleName, out dependencies) ) return; //卸载依赖包 foreach(var dependency in dependencies) { UnloadAssetBundleInternal(dependency); } //删除依赖缓存策略 MrCAssetCache.DependCache.Remove(assetBundleName); } internal static void UnloadAssetBundleInternal(string assetBundleName) { MrCAssetBundle bundle; MrCAssetCache.BundleCache.TryGetValue(assetBundleName,out bundle); if (bundle == null) { return; } bundle.Release (); } #endregion #region GetFunction internal static WWW GetWWWCache(string key) { WWW www; MrCAssetCache.WwwCache.TryGetValue(key,out www); return www; } internal static void SetWWWCache(string key,WWW value) { MrCAssetCache.WwwCache.Add(key,value); } internal static MrCAssetBundle GetBundleCache(string key) { MrCAssetBundle ab; MrCAssetCache.BundleCache.TryGetValue(key,out ab); return ab; } internal static void SetBundleCache(string key,MrCAssetBundle value) { MrCAssetCache.BundleCache.Add(key,value); } internal static string[] GetDependCache(string key) { string[] depends; MrCAssetCache.DependCache.TryGetValue(key,out depends); return depends; } internal static void SetDependCache(string key,string[] value) { MrCAssetCache.DependCache.Add(key,value); } internal static string GetErrorCache(string key) { string error; MrCAssetCache.ErrorCache.TryGetValue(key,out error); return error; } internal static void SetErrorCache(string key,string value) { MrCAssetCache.ErrorCache.Add(key,value); } #endregion internal static void FreeBundle(string key) { MrCAssetCache.BundleCache.Remove(key); } #region Update internal static void Update() { // Collect all the finished WWWs. var keysToRemove = new List<string>(); foreach (var keyValue in MrCAssetCache.WwwCache) { WWW download = keyValue.Value; string m_bundleName = keyValue.Key; // 下载失败 if (download.error != null) { MrCAssetCache.ErrorCache.Add(m_bundleName, download.error); keysToRemove.Add(m_bundleName); continue; } // 下载成功 if(download.isDone) { MrCAssetCache.BundleCache.Add(m_bundleName, new MrCAssetBundle(download.assetBundle,m_bundleName)); keysToRemove.Add(m_bundleName); } } // 删除下载成功的WWW对象 foreach( var key in keysToRemove) { WWW download = MrCAssetCache.WwwCache[key]; MrCAssetCache.WwwCache.Remove(key); download.Dispose(); } } #endregion } }
加载包裹中的场景:
新建一个场景,创建TestScript脚本,放到摄像机上。
using UnityEngine; using System.Collections; //引入框架 using MrCAssetFramework; public class TestScript : MonoBehaviour { /// <summary> /// 加载场景资源函数 /// </summary> protected IEnumerator Load (string assetBundleName, string level) { IEnumerator b = da.LoadLevelAsync(assetBundleName, level, false); yield return StartCoroutine(b); Application.LoadLevel(level); } MrCAssetManager da; void Start () { //指定统一资源标志符 MrCAssetManager.URI = "http://....../UnityFiles/AssetBundlesForBlog/"; //主配置文件 MrCAssetManager.ManifestName = "Others"; //加载成功后的操作代理 MrCAssetManager.InitBlock = ((bool bundleObj) => { if (bundleObj) { //协程操作加载的AssetBundle包裹 StartCoroutine (Load ("scenes/loaderscene.unity3d", "LoaderScene")); } }); //开始我们的一切 da = MrCAssetManager.DefaultAssetManager; } }
加载包裹中的游戏对象等资源到场景中:
在上面的测试脚本中,修改部分代码。
/// <summary> /// 加载游戏对象资源函数 /// </summary> protected IEnumerator LoadObj(string assetBundleName, string obj) { IEnumerator b = da.LoadAssetAsync(assetBundleName, obj, typeof(GameObject)); yield return StartCoroutine(b); GameObject go = da.GetAsset<GameObject>(assetBundleName, obj); GameObject.Instantiate(go); } //------------------------------------------------------------------------------- //加载成功后的操作代理 MrCAssetManager.InitBlock = ((bool bundleObj) => { if (bundleObj) { //协程操作加载的游戏对象包裹 StartCoroutine(LoadObj("prefabs/cube.prefab", "MyCube")); } });
相关文章推荐
- Unity5系列资源管理AssetBundle——打包
- Unity Shader 表面着色器边缘光(Rim Lighting)一
- Unity跑酷类游戏自动生成销毁地图
- Unity Shader 在Shader中使用法线贴图
- unity之Ray、RaycastHit 、Raycast
- 【进阶】Unity资源解决方案之AssetBundle
- Advanced Global Illumination in Unity 5 - Unite Europe 2015
- unity3D 调用set和get方法
- Unity3D 常用函数
- Unity 5.1.2f1破解教程
- Unity Shader 表面着色器(Surface Shader)
- unity简易小地图的实现(NGUI)
- unity简易小地图的实现(NGUI)
- Unity 3d 帧同步
- Unity3D Mac 版本破解小记
- Unity3D 个人免费版不支持Camera.OnRenderImage
- unity官方demo学习之Stealth(二十四)敌人AI
- unity官方demo学习之Stealth(二十三)敌人射击功能
- unity3D 4.6与上述号码. UI穿透问题,而且不穿透的真机模拟器渗透问题解决
- unity官方demo学习之Stealth(二十二)敌人动画控制