您的位置:首页 > 移动开发 > Unity3D

Unity框架——资源管理

2017-02-10 14:05 309 查看
1.资源加载监听者接口

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 框架