9.ScriptableObject单例

9.ScriptableObject应用-单例模式化的获取数据


9.1 知识点

为什么要单例模式化的获取数据

  • 对于只用不变并且要复用的数据
  • 比如配置文件中的数据
  • 我们往往需要在很多地方获取他们
  • 如果我们直接通过在脚本中 public关联 或者 动态加载
  • 如果在多处使用,会存在很多重复代码,效率较低
  • 如果我们将此类数据通过单例模式化的去获取
  • 可以提升效率,减少代码量
  • 就比如之前的RoleInfo数据文件,每次使用要不就得拖拽,要不就得Resource.Load,比较麻烦

实现单例模式化获取数据

  • 知识点:面向对象、单例模式、泛型等等

我们可以实现一个ScriptableObject数据单例模式基类
让我们只需要让子类继承该基类
就可以直接获取到数据
而不再需要去通过 public关联 和 资源动态加载

定义了一个名为SingleScriptableObject的泛型类

  • 继承自ScriptableObject
  • 该类用于实现单例模式的ScriptableObject对象
  • 定义一个私有静态字段instance,用于存储单例对象
  • 定义一个公共静态属性Instance,用于获取单例对象
  • 该属性的类型为泛型参数T
  • 检查单例对象是否为空
  • 如果为空,则需要加载或创建单例对象
  • 尝试从资源路径下加载对应的数据资源文件
  • 根据约定,数据资源文件的路径为Resources/ScriptableObject/
  • 文件名与类名相同
  • 如果没有找到对应的数据资源文件,可以在此处直接创建一个新的数据对象
  • 返回单例对象
public class SingleScriptableObject<T> : ScriptableObject where T : ScriptableObject
{
    private static T instance;

    public static T Instance
    {
        get
        {
            // 如果为空 首先应该去资源路径下加载 对应的 数据资源文件
            if (instance == null)
            {
                // 我们定两个规则
                // 1.所有的 数据资源文件都放在 Resources文件夹下的ScriptableObject中
                // 2.需要复用的 唯一的数据资源文件名 我们定一个规则:和类名是一样的
                instance = Resources.Load<T>("ScriptableObject/" + typeof(T).Name);
            }

            // 如果没有这个文件 为了安全起见 我们可以在这直接创建一个数据
            if (instance == null)
            {
                instance = CreateInstance<T>();
            }
            // 甚至可以在这里 从json当中读取数据,但是我不建议用ScriptableObject来做数据持久化

            return instance;
        }
    }
}
比如让RoleInfo继承SingleScriptableObject
public class RoleInfo : SingleScriptableObject<RoleInfo>
或者创建TestData类继承 SingleScriptableObject
[CreateAssetMenu]
public class TestData : SingleScriptableObject<TestData>
{
    public int i;
    public bool b;
}
就可以直接使用Instance单例来获取数据文件了。Resource/ScriptableObject下有没有数据都行。没有无非就是动态得到默认的。
print(RoleInfo.Instance.roleList[0].id);
print(RoleInfo.Instance.roleList[1].tips);

print(TestData.Instance.i);
print(TestData.Instance.b);

总结

  • 这种基类比较适合 配置数据 的管理和获取
  • 当我们的数据是 只用不变,并且是唯一的时候,可以使用该方式提高我们的开发效率
  • 在此基础上你也可以根据自己的需求进行变形
  • 比如添加数据持久化的功能,将数据从json中读取,并提供保存数据的方法
  • 但是不建议大家用ScriptableObject来制作数据持久化功能
  • 除非你有这方面的特殊需求

9.2 知识点代码

Lesson09_ScriptableObject应用_单例模式化的获取数据

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson09_ScriptableObject应用_单例模式化的获取数据 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 为什么要单例模式化的获取数据
        //对于只用不变并且要复用的数据
        //比如配置文件中的数据
        //我们往往需要在很多地方获取他们
        //如果我们直接通过在脚本中 public关联 或者 动态加载
        //如果在多处使用,会存在很多重复代码,效率较低
        //如果我们将此类数据通过单例模式化的去获取
        //可以提升效率,减少代码量
        #endregion

        #region 知识点二 实现单例模式化获取数据
        //知识点:面向对象、单例模式、泛型等等

        //我们可以实现一个ScriptableObject数据单例模式基类
        //让我们只需要让子类继承该基类
        //就可以直接获取到数据
        //而不再需要去通过 public关联 和 资源动态加载

        print(RoleInfo.Instance.roleList[0].id);
        print(RoleInfo.Instance.roleList[1].tips);

        print(TestData.Instance.i);
        print(TestData.Instance.b);
        #endregion

        #region 总结
        //这种基类比较适合 配置数据 的管理和获取
        //当我们的数据是 只用不变,并且是唯一的时候,可以使用该方式提高我们的开发效率
        //在此基础上你也可以根据自己的需求进行变形
        //比如添加数据持久化的功能,将数据从json中读取,并提供保存数据的方法
        //但是不建议大家用ScriptableObject来制作数据持久化功能
        //除非你有这方面的特殊需求
        #endregion
    }
}

SingleScriptableObject

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingleScriptableObject<T> :ScriptableObject where T:ScriptableObject
{
    private static T instance;

    public static T Instance
    {
        get
        {
            //如果为空 首先应该去资源路径下加载 对应的 数据资源文件
            if (instance == null)
            {
                //我们定两个规则
                //1.所有的 数据资源文件都放在 Resources文件夹下的ScriptableObject中
                //2.需要复用的 唯一的数据资源文件名 我们定一个规则:和类名是一样的
                instance = Resources.Load<T>("ScriptableObject/" + typeof(T).Name);
            }

            //如果没有这个文件 为了安全起见 我们可以在这直接创建一个数据
            if(instance==null)
            {
                instance = CreateInstance<T>();
            }
            //甚至可以在这里 从json当中读取数据,但是我不建议用ScriptableObject来做数据持久化

            return instance;
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏