Unity框架——资源管理
2017-02-10 14:05
309 查看
1.资源加载监听者接口
2.资源信息类
3.资源管理者类
using UnityEngine; using System.Collections; /// <summary> /// 资源加载回调 /// </summary> public interface IResLoadListener { void Finished(object asset); void Failed(); }
2.资源信息类
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; /// <summary> /// 资源信息 /// </summary> public class AssetInfo { /// <summary> 资源 </summary> public object asset; /// <summary> 是否常驻于内存 </summary> public bool isKeepInMemory; /// <summary> 资源堆的引用计数 </summary> public int refCount = 0; } /// <summary> /// 资源加载信息 /// </summary> public class RequestInfo { /// <summary> 资源反馈信息 </summary> public ResourceRequest request; /// <summary> 是否常驻于内存 </summary> public bool isKeepInMemory; /// <summary> 加载完成后的回调 </summary> public List<IResLoadListener> listeners; /// <summary> /// 添加资源监听者 /// </summary> /// <param name="listener"></param> public void AddListner(IResLoadListener listener) { if(listeners==null) { listeners = new List<IResLoadListener>() {listener }; } else { if(!listeners.Contains(listener)) { listeners.Add(listener); } } } /// <summary> 资源路径(名称) </summary> public string assetPath; /// <summary> 资源类型 </summary> public Type assetType; /// <summary> /// 资源是否加载完成 /// </summary> public bool IsDone { get { return (request != null && request.isDone); } } /// <summary> /// 加载到的资源 /// </summary> public object Asset { get { return request != null ? request.asset : null; } } /// <summary> /// 异步加载 /// </summary> public void LoadAsync() { request = Resources.LoadAsync(assetPath, assetType); } }
3.资源管理者类
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; public class ResManager :EventNode,IEventListener { #region 单例 private static ResManager instance; public static ResManager Instance { get { if (instance == null) { instance = (ResManager)FindObjectOfType(typeof(ResManager)); if (instance == null) { Debug.LogError("An instance of " + typeof(ResManager) + " is needed in the scene, but there is none."); } } return instance; } } #endregion /// <summary> CPU数量 </summary> private int processorCount = 0; /// <summary> 所有资源的字典 </summary> private Dictionary<string, AssetInfo> AssetDic=new Dictionary<string,AssetInfo>(); /// <summary> 正在加载的列表 </summary> public List<RequestInfo> loadList = new List<RequestInfo>(); /// <summary> 等待加载的列表 </summary> public Queue<RequestInfo> waitQueue = new Queue<RequestInfo>(); /// <summary> 资源加载栈 </summary> public Stack<List<string>> assetStack; #region 加载资源 /// <summary> /// 加载 /// </summary> /// <param name="assetPath">资源路径</param> /// <param name="listener">监听</param> /// <param name="isKetInMemory">是否储存在内存中</param> /// <param name="assetType">类型</param> public void Load(string assetPath, IResLoadListener listener, bool isAsync = true, bool isKetInMemory = false, Type assetType = null) { if (AssetDic.ContainsKey(assetPath)) { listener.Finished(AssetDic[assetPath]); return; } if (isAsync) { LoadAsync(assetPath, listener, assetType, isKetInMemory); } } #endregion #region 异步Res加载 /// <summary> /// 异步加载 /// </summary> /// <param name="assetPath">资源路径</param> /// <param name="listener">监听</param> /// <param name="isKetInMemory">是否储存在内存中</param> /// <param name="assetType">类型</param> public void LoadAsync(string assetPath, IResLoadListener listener, Type assetType, bool isKetInMemory) { //判断是否在正在加载的加载列表中 for (int i = 0; i < loadList.Count; i++) { if (loadList[i].assetPath == assetPath) { loadList[i].AddListner(listener); return; } } //判断是否在等待加载的家在列表中 foreach(RequestInfo info in waitQueue) { if(info.assetPath==assetPath) { info.AddListner(listener); return; } } RequestInfo requestInfo = new RequestInfo(); requestInfo.assetPath = assetPath; requestInfo.AddListner(listener); requestInfo.isKeepInMemory = isKetInMemory; requestInfo.assetType = assetType == null ? typeof(GameObject) : assetType; waitQueue.Enqueue(requestInfo); } #endregion #region 资源处理 /// <summary> /// 获取资源 /// </summary> /// <param name="assetPath">资源名</param> /// <returns>资源</returns> public AssetInfo GetAsset(string assetPath) { AssetInfo info = null; AssetDic.TryGetValue(assetPath,out info); return info; } /// <summary> /// 释放资源 /// </summary> /// <param name="assetPath">资源名</param> public void ReleaseAsset(string assetPath) { AssetInfo info = null; AssetDic.TryGetValue(assetPath,out info); if (info != null && !info.isKeepInMemory) { AssetDic.Remove(assetPath); } } /// <summary> /// 修改是否为常驻内存 /// </summary> /// <param name="assetPath">资源名</param> /// <param name="isKeepInMemory">是否为常驻内存</param> public void IsKeepInMemory(string assetPath,bool isKeepInMemory) { AssetInfo info = null; AssetDic.TryGetValue(assetPath, out info); if (info != null) { info.isKeepInMemory = isKeepInMemory; } } #endregion #region 资源释放以及监听 /// <summary> /// 把资源压入顶层栈内 /// </summary> /// <param name="assetPath">资源名</param> public void AddAsset(string assetPath) { if(assetStack.Count==0) { assetStack.Push(new List<string>(){ assetPath }); } List<string> list= assetStack.Peek(); list.Add(assetPath); } /// <summary> /// 开始让资源入栈 /// </summary> public void PushAssetToStack() { List<string> list = new List<string>(); foreach(KeyValuePair<string,AssetInfo> info in AssetDic) { info.Value.refCount++; list.Add(info.Key); } assetStack.Push(list); } /// <summary> /// 释放栈内资源 /// </summary> public void PopAssetFromStack() { if(assetStack.Count==0) { Debug.Log("ResManager.PopAssetFromStack stack is null!"); return; } List<string> list = assetStack.Pop(); List<string> removeList = new List<string>(); AssetInfo info = null; for(int i=0;i<list.Count;i++) { if(AssetDic.TryGetValue(list[i],out info)) { info.refCount--; if (info.refCount < 1 && !info.isKeepInMemory) { removeList.Add(list[i]); } } } for (int i = 0; i <= removeList.Count; i++) { if(AssetDic.ContainsKey(removeList[i])) { AssetDic.Remove(removeList[i]); } } GC(); } /// <summary> /// 释放资源 /// </summary> public void GC() { Resources.UnloadUnusedAssets(); System.GC.Collect(); } #endregion void Awake() { DontDestroyOnLoad(this.gameObject); instance.AttachEventListener(1000, this); //获取cpu数量,如果是0-8核则返回核数,不满足则返回1核 processorCount = SystemInfo.processorCount > 0 && SystemInfo.processorCount <= 8 ? SystemInfo.processorCount : 1; } void Update() { if (loadList.Count > 0) { for (int i = loadList.Count - 1; i >= 0; i--) { if (loadList[i].IsDone) { RequestInfo info = loadList[i]; SendEvent(1000, info); loadList.RemoveAt(i); } } } while(loadList.Count<processorCount&&waitQueue.Count>0) { RequestInfo info= waitQueue.Dequeue(); loadList.Add(info); info.LoadAsync(); } } void OnDestroy() { if(instance!=null) { instance.DetachEventListener(1000, this); instance = null; } } public bool HandleEvent(int eventKey, params object[] objArgs) { switch(eventKey) { case 1000: RequestInfo info = objArgs[0] as RequestInfo; if(info !=null) { if(info.Asset!=null) { AssetInfo asset = new AssetInfo(); asset.isKeepInMemory = info.isKeepInMemory; asset.asset = info.Asset; if(!AssetDic.ContainsKey(info.assetPath)) { AssetDic.Add(info.assetPath, asset); } for(int i=0;i<info.listeners.Count;i++) { if(info.listeners[i]!=null) { info.listeners[i].Finished(info.Asset); } } AddAsset(info.assetPath); } } else { for (int i = 0; i < info.listeners.Count; i++) { if (info.listeners[i] != null) { info.listeners[i].Failed(); } } } return false; } return false; } public int EventPriority() { return 0; } }
相关文章推荐
- Unity手游框架之 资源管理
- java 高新技术【6】 反射开发框架以及用 类加载器 管理资源和配置文件
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- Unity 资源管理与更新
- java 高新技术【6】 反射开发框架以及用 类加载器 管理资源和配置文件
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- 资源管理框架(mesos/YARN/coraca/Torca/Omega)选型分析
- PHP资源管理框架Assetic简介
- 企业级Hadoop 2.x入门系列之四HDFS文件系统和YARN资源管理框架简介
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- LomoX 桌面UI框架更新,增加资源管理
- Unity资源管理与更新
- android游戏开发框架libgdx的使用(十八)—资源加载管理AssetManager的使用
- Unity运行时刻资源管理
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- Android资源管理框架(Asset Manager)简要介绍和学习计划
- Android资源管理框架(Asset Manager)简要介绍和学习计划