源码学习网

单例的继承之使用单例优化 Resouces.Load

单例的继承之使用单例优化 Resouces.Load

 

当项目中需要频繁使用Resouces.Load加载资源时 ,会感觉操作非常繁锁,

这时可以使用下面这段代码来减少代码的书写量,

哈稀表作为缓存的使用,同样使资源的复用得到改善,减少了不必要的系统性能开支

使用时只要 

ResourcesMgr.Load("资源文件名称")
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class ResourcesMgr:DanLiCtrl<ResourcesMgr>
{
    //继承自单例管理器,如果没有管理器也可自行做成单例
    //根据项目实际需求更改,代表类型文件所在的文件夹
    #region ResouseceType 资源类型的枚举
    /// <summary>
    /// 资源类型的枚举
    /// </summary>
    public enum ResouseceType
    {
        /// <summary>
        /// UI资源
        /// </summary>
        UIPrefabs,
        /// <summary>
        /// 角色资源
        /// </summary>
        role,
        /// <summary>
        /// 怪物资源
        /// </summary>
        monster,
        /// <summary>
        /// 声音资源
        /// </summary>
        Audios
    }
    #endregion

    /// <summary>
    /// 预设的键值对列表,作为缓存使用
    /// </summary>
    private Hashtable m_PrefabTable;
    public ResourcesMgr()
    {
        m_PrefabTable=new Hashtable();
    }

    //根据项目实际需要修改
    //1参数中bool如果不赋值,就是必传参数,写个值,就变成了可传可不传,因为有了默认值
    //2根据类型,把资源路径加入sb作为资源的前辍路径
    //3最后加上传递进来的短路径(路径或者名称),也就是资源的文件名称与前面的类型所对应路径拼接成一个完整路径
    //4用拼接后的完整路径,完成这次的资源加载
    /// <summary>
    /// 替代普通的resouces.Load
    /// </summary>
    /// <param name="T">资源的类型,swich里面定义对应路径</param>
    /// <param name="path">文件名称</param>
    /// <param name="B">是否加入缓存</param>
    /// <returns>加载完成的GameObject </returns>
    public GameObject Load(ResouseceType T, string path,bool B=false)//1
    {
        StringBuilder sb=new StringBuilder();
        //2
        switch (T)
        {
            ////根据项目实际需要修改即可, 字符串后面需要加 / ,因为这并不是一个完整路径
            case ResouseceType.Audios:
                sb.Append("prefabs/Audios/");
                break;
            case ResouseceType.UIPrefabs:
                sb.Append("prefabs/UIPrefabs/");
                break;
            case ResouseceType.monster:
                sb.Append("prefabs/monster/");
                break;
            case ResouseceType.role:
                sb.Append("prefabs/role/");
                break;
        } 
        sb.Append(path);   //3

        // 4
        GameObject obj = null;
        if (m_PrefabTable.Contains(path))
        {
            //如果缓存里面有
            obj = m_PrefabTable[path] as GameObject;
        }
        else
        {   //没有,就正常加载 
            obj = Resources.Load<GameObject>(sb.ToString());
            //如果使用缓存,就加入列表
            if (B)
            {
                m_PrefabTable.Add(path,obj);
            }
        }

        //加载完之后同时实例化出来
        //这里可return obj 也可以顺带实例化出来再返回
        return GameObject.Instantiate(obj);
    }

    //重载=== 原始的加载方法
    public GameObject Load(string path)
    {
        return Resources.Load<GameObject>(path);
    }
}
//使用示例 加载资源文件夹下李奎的预制体,并实例化存入tmp中

//Resources/prefabs/role/LiKui
GameObject tmp=ResourcesMgr.Instance.Load(ResourcesMgr.ResouseceType.role, "LiKui", B:true); //这里注意最后一个参数的写法

ResourcesMgr.Instance.Load(ResourcesMgr.ResouseceType.role, "宋江");//最后一个参数不传也没问题

 然后,切换场景时怎么办?资源还是存在于内存中, 这样会使内存变得臃肿,怎么办呢? 

看下面优化后的:

using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class ResourcesMgr:DanLiCtrl<ResourcesMgr>
{
    //继承自单例管理器,如果没有管理器也可自行做成单例
    //根据项目实际需求更改,代表类型文件所在的文件夹
    #region ResouseceType 资源类型的枚举
    /// <summary>
    /// 资源类型的枚举
    /// </summary>
    public enum ResouseceType
    {
        /// <summary>
        /// UI资源
        /// </summary>
        UIPrefabs,
        /// <summary>
        /// 角色资源
        /// </summary>
        role,
        /// <summary>
        /// 怪物资源
        /// </summary>
        monster,
        /// <summary>
        /// 声音资源
        /// </summary>
        Audios
    }
    #endregion

    /// <summary>
    /// 预设的键值对列表,作为缓存使用
    /// </summary>
    private Hashtable m_PrefabTable;
    public ResourcesMgr()
    {
        m_PrefabTable=new Hashtable();
    }

    //根据项目实际需要修改
    //1参数中bool如果不赋值,就是必传参数,写个值,就变成了可传可不传,因为有了默认值
    //2根据类型,把资源路径加入sb作为资源的前辍路径
    //3最后加上传递进来的短路径(路径或者名称),也就是资源的文件名称与前面的类型所对应路径拼接成一个完整路径
    //4用拼接后的完整路径,完成这次的资源加载
    /// <summary>
    /// 替代普通的resouces.Load
    /// </summary>
    /// <param name="T">资源的类型,swich里面定义对应路径</param>
    /// <param name="path">文件名称</param>
    /// <param name="B">是否加入缓存</param>
    /// <returns>加载完成的GameObject </returns>
    public GameObject Load(ResouseceType T, string path,bool B=false)//1
    {
        GameObject obj = null;
        if (m_PrefabTable.Contains(path))
        {
            //如果缓存里面有
            obj = m_PrefabTable[path] as GameObject;
        }
        else
        {   //没有,就正常加载 

            StringBuilder sb = new StringBuilder();
            //2
            switch (T)
            {
                ////根据项目实际需要修改即可
                case ResouseceType.Audios:
                    sb.Append("prefabs/Audios/");
                    break;
                case ResouseceType.UIPrefabs:
                    sb.Append("prefabs/UIPrefabs/");
                    break;
                case ResouseceType.monster:
                    sb.Append("prefabs/monster/");
                    break;
                case ResouseceType.role:
                    sb.Append("prefabs/role/");
                    break;
            }
            sb.Append(path);   //3

            // 4
            obj = Resources.Load<GameObject>(sb.ToString());
            //如果使用缓存,就加入列表
            if (B)
            {
                m_PrefabTable.Add(path,obj);
            }
        }

        //加载完之后同时实例化出来
        //这里可return obj 也可以顺带实例化出来再返回
        return GameObject.Instantiate(obj);
    }

    //重载=== 原始的加载方法
    public GameObject Load(string path)
    {
        return Resources.Load<GameObject>(path);
    }

    //释放资源
    //继承 :IDisposable接口 可以父类继承,子类从写,也可以子类直接继承
    public override void Dispose()
    {
        base.Dispose();
        m_PrefabTable.Clear();
        //把未使用的资源进行释放
        Resources.UnloadUnusedAssets();
    }
}

切换场景时调用 Dispose();方法就可以了。

 

posted @ 2018-04-06 00:58  马丁啉  阅读(316)  评论(0编辑  收藏  举报