Unity3D游戏开发框架-资源管理类ResourceManage

发表于2018-09-10
评论0 929浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594
上篇内容给大家介绍了Unity3d游戏开发框架中创建txt文件,管理prefab路径的方法,本篇继续给大家介绍下Unity3D游戏开发框架系列,看看资源管理类ResourceManage的使用方法。


新建文件夹:ResMgr。接着新建三个C#脚本。代码如下:
IResLoadListener.cs
AssetInfo.cs
ResMgr.cs
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;
    }
}
来自:https://blog.csdn.net/u013108312/article/details/52351850

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台