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

Posted 马丁啉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例的继承之使用单例优化 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();方法就可以了。

 

以上是关于单例的继承之使用单例优化 Resouces.Load的主要内容,如果未能解决你的问题,请参考以下文章

单例模式

Lua面向对象----类继承多继承单例的实现

Java高级之单例的合理用法

iOS之深入解析单例的实现和销毁的底层原理

25面向对象设计模式之单例模式——带参单例的调试与理解

Java 设计模式之单例学习与掌握