Unity3D遊戲開發框架-資源管理類ResourceManage
阿新 • • 發佈:2019-02-09
using UnityEngine;
using System.Collections;
/// <summary>
/// 資源載入回撥
/// </summary>
public interface IResLoadListener
{
void Finish(object asset);
void Failure();
}
using System;
using UnityEngine;
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 stackCount = 0;
}
/// <summary>
/// 資源載入資訊
/// </summary>
public class RequestInfo
{
/// <summary>
/// 資源反饋資訊
/// </summary>
public ResourceRequest request;
/// <summary>
/// 是否常駐記憶體
/// </summary>
public bool isKeepInMemory;
/// <summary>
/// 載入完成之後的回撥
/// </summary>
public List<IResLoadListener> linsteners;
public void AddListener(IResLoadListener listener)
{
if (linsteners == null)
{
linsteners = new List<IResLoadListener>() { listener };
}
else
{
if (!linsteners.Contains(listener))
{
linsteners.Add(listener);
}
}
}
/// <summary>
/// 資源名稱
/// </summary>
public string assetName;
public string assetFullName
{
get
{
return ResMgr.Instance.GetFileFullName(assetName);
}
}
/// <summary>
/// 資源型別
/// </summary>
public Type type;
/// <summary>
/// 資源是否載入完成
/// </summary>
public bool IsDone
{
get
{
return (request != null && request.isDone);
}
}
/// <summary>
/// 載入到的資源
/// </summary>
public object Asset
{
get
{
return request != null ? request.asset : null;
}
}
public void LoadAsync()
{
request = Resources.LoadAsync(assetFullName, type);
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
public class ResMgr : EventNode,IEventListener
{
private Dictionary<string, string> mAssetPathDic = new Dictionary<string, string>();
public string GetFileFullName(string assetName)
{
if (mAssetPathDic.Count == 0)
{
UnityEngine.TextAsset tex = Resources.Load<TextAsset>("res");
StringReader sr = new StringReader(tex.text);
string fileName = sr.ReadLine();
while (fileName != null)
{
Debug.Log("fileName =" + fileName);
string [] ss = fileName.Split('=');
mAssetPathDic.Add(ss[0], ss[1]);
fileName = sr.ReadLine();
}
}
return assetName = mAssetPathDic[assetName] + "/" + assetName;
}
/// <summary>
/// 所有資源字典
/// </summary>
private Dictionary<string, AssetInfo> mDicAaaet = new Dictionary<string, AssetInfo>();
/// <summary>
/// CPU 個數
/// </summary>
private int mProcessorCount = 0;
private static ResMgr mInstance;
public static ResMgr Instance
{
get
{
return mInstance;
}
}
// Awake is called when the script instance is being loaded.
void Awake()
{
mInstance = this;
DontDestroyOnLoad(this.gameObject);
AttachEventListener(EventDef.ResLoadFinish, this);
mProcessorCount = SystemInfo.processorCount > 0 && SystemInfo.processorCount <= 8 ? SystemInfo.processorCount : 1;
}
void OnDestroy()
{
if (Instance != null)
{
Instance.DetachEventListener(EventDef.ResLoadFinish, this);
}
}
/// <summary>
/// 正在載入的列表
/// </summary>
public List<RequestInfo> mInLoads = new List<RequestInfo>();
/// <summary>
/// 等待載入的列表
/// </summary>
public Queue<RequestInfo> mWaitting = new Queue<RequestInfo>();
/// <summary>
/// 資源載入堆疊
/// </summary>
public Stack<List<string>> mAssetStack = new Stack<List<string>>();
#region 載入資源
public void Load(string assetName, IResLoadListener listener, Type type = null, bool isKeepInMemory = false, bool isAsync = true)
{
if (mDicAaaet.ContainsKey(assetName))
{
listener.Finish(mDicAaaet[assetName]);
return;
}
if (isAsync)
{
LoadAsync(assetName, listener,isKeepInMemory,type);
}
}
#endregion
#region 非同步Res載入
private void LoadAsync(string assetName, IResLoadListener listener,bool isKeepInMemory,Type type)
{
for (int i = 0; i < mInLoads.Count; i++)
{
if (mInLoads[i].assetName == assetName)
{
mInLoads[i].AddListener(listener);
return;
}
}
foreach(RequestInfo info in mWaitting)
{
if (info.assetName == assetName)
{
info.AddListener(listener);
return;
}
}
RequestInfo requestInfo = new RequestInfo();
requestInfo.assetName = assetName;
requestInfo.AddListener(listener);
requestInfo.isKeepInMemory = isKeepInMemory;
requestInfo.type = type == null ? typeof(GameObject) : type;
mWaitting.Enqueue(requestInfo);
}
#endregion
#region 資源處理
/// <summary>
/// 從資源字典中取得一個資源
/// </summary>
/// <param name="assetName">資源名稱</param>
/// <returns></returns>
public AssetInfo GetAsset(string assetName)
{
AssetInfo info = null;
mDicAaaet.TryGetValue(assetName,out info);
return info;
}
/// <summary>
/// 釋放一個資源
/// </summary>
/// <param name="assetName">資源名稱</param>
public void ReleaseAsset(string assetName)
{
AssetInfo info = null;
mDicAaaet.TryGetValue(assetName, out info);
if (info != null && !info.isKeepInMemory)
{
mDicAaaet.Remove(assetName);
}
}
/// <summary>
/// 修改資源是否常駐記憶體
/// </summary>
/// <param name="assetName">資源名稱</param>
/// <param name="IsKeepInMemory">是否常駐記憶體</param>
public void IsKeepInMemory(string assetName,bool IsKeepInMemory)
{
AssetInfo info = null;
mDicAaaet.TryGetValue(assetName, out info);
if (info != null)
{
info.isKeepInMemory = IsKeepInMemory;
}
}
#endregion
#region 資源釋放以及監聽
/// <summary>
/// 把資源壓入頂層棧內
/// </summary>
/// <param name="assetName">資源名稱</param>
public void AddAssetToName(string assetName)
{
if (mAssetStack.Count == 0)
{
mAssetStack.Push(new List<string>() { assetName });
}
List <string> list = mAssetStack.Peek();
list.Add(assetName);
}
/// <summary>
/// 開始讓資源入棧
/// </summary>
public void PushAssetStack()
{
List<string> list = new List<string>();
foreach(KeyValuePair<string,AssetInfo> info in mDicAaaet)
{
info.Value.stackCount++;
list.Add(info.Key);
}
mAssetStack.Push(list);
}
/// <summary>
/// 釋放棧內資源
/// </summary>
public void PopAssetStack()
{
if (mAssetStack.Count == 0) return;
List<string> list = mAssetStack.Pop();
List<string> removeList = new List<string>();
AssetInfo info = null;
for (int i = 0; i < list.Count;i++ )
{
if (mDicAaaet.TryGetValue(list[i],out info))
{
info.stackCount--;
if (info.stackCount < 1 && !info.isKeepInMemory)
{
removeList.Add(list[i]);
}
}
}
for (int i = 0; i < removeList.Count;i++ )
{
if (mDicAaaet.ContainsKey(removeList[i]))
mDicAaaet.Remove(removeList[i]);
}
GC();
}
/// <summary>
/// 釋放
/// </summary>
public void GC()
{
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
#endregion
void Update()
{
if (mInLoads.Count > 0)
{
for (int i = mInLoads.Count - 1; i >= 0; i--)
{
if (mInLoads[i].IsDone)
{
RequestInfo info = mInLoads[i];
SendEvent(EventDef.ResLoadFinish, info);
mInLoads.RemoveAt(i);
}
}
}
while (mInLoads.Count < mProcessorCount && mWaitting.Count > 0)
{
RequestInfo info = mWaitting.Dequeue();
mInLoads.Add(info);
info.LoadAsync();
}
}
public bool HandleEvent(int id, object param1, object param2)
{
switch (id)
{
case EventDef.ResLoadFinish:
RequestInfo info = param1 as RequestInfo;
if (info != null)
{
if (info.Asset != null)
{
AssetInfo asset = new AssetInfo();
asset.isKeepInMemory = info.isKeepInMemory;
asset.asset = info.Asset;
if (!mDicAaaet.ContainsKey(info.assetName))
{
mDicAaaet.Add(info.assetName, asset);
}
for (int i = 0; i < info.linsteners.Count;i++ )
{
if (info.linsteners[i] != null)
{
info.linsteners[i].Finish(info.Asset);
}
}
AddAssetToName(info.assetName);
}
}
else
{
for (int i = 0; i < info.linsteners.Count; i++)
{
if (info.linsteners[i] != null)
{
info.linsteners[i].Failure();
}
}
}
return false;
}
return false;
}
public int EventPriority()
{
return 0;
}
}