3.使用ScriptableObject数据文件

  1. 3.ScriptableObject数据文件的使用
    1. 3.1 知识点
      1. ScriptableObject数据文件的使用
        1. 方法一:通过Inspector中的public变量进行关联
        2. 方法二:通过资源加载的信息关联
      2. ScriptableObject的生命周期函数
        1. ScriptableObject和 MonoBehaviour 类似,它也有生命周期函数,但数量较少。我们一般不常用。
        2. 生命周期函数代码
      3. ScriptableObject好处的体现
        1. 编辑器中的数据持久化
        2. 复用数据
      4. 总结
    2. 3.2 知识点代码
      1. Lesson03_ScriptableObject数据文件的使用
      2. MyData
    3. 3.3 练习题
      1. 请使用上节课做的游戏设置信息数据文件,做一个设置界面,使用该数据文件来更新界面,并且做到每次重启游戏数据能被记录
        1. 在场景中创建设置面板和各控件
        2. 创建SettingPanel脚本,外部关联变量。设置一个设置信息数据资源文件变量,关联上节练习题创建的设置信息数据文件。
        3. 在Start中一开始读取数据文件的值,赋值给各控件。并给各控件添加值改变监听,改变后记录修改后的值到数据文件中。
        4. 注意,在编辑器中看起来好像实现了数据持久化,但是其实打包出去并不能数据持久化,只是在编辑器上看起来有数据持久化。如果打包遇到报错可能是MenuItem特性用到了编辑器相关的代码,需要把他包一层放到Editor文件夹中。
    4. 3.4 练习题代码

3.ScriptableObject数据文件的使用


3.1 知识点

ScriptableObject数据文件的使用

  • Resources、AB包、Addressables都支持加载继承ScriptableObject的数据文件
  • 可以把数据文件理解成预设体的感觉
  • 注意:如果多个对象关联同一个数据容器文件,他们共享的是一个对象,因为是引用对象,所以在其中任何地方修改后,其它地方也会发生改变

方法一:通过Inspector中的public变量进行关联

创建一个数据文件,可以右键创建

在继承MonoBehaviour类中申明数据容器类型的成员,在Inspector窗口进行关联数据文件

public MyData myData;

在MyData中声明打印信息方法并调用,在继承MonoBehaviour类中可以打印出关联的数据文件信息

public void PrintInfo()
{
    Debug.Log(i);
    Debug.Log(f);
    Debug.Log(b);
}


myData.PrintInfo();


方法二:通过资源加载的信息关联

加载数据文件资源,并打印

myData = Resources.Load<MyData>("MyDataTest");
myData.PrintInfo();

ScriptableObject的生命周期函数

ScriptableObject和 MonoBehaviour 类似,它也有生命周期函数,但数量较少。我们一般不常用。

  • Awake:在数据文件创建时调用。
  • OnDestroy:在 ScriptableObject 对象将被销毁时调用。
  • OnDisable:在 ScriptableObject 对象销毁时、即将重新加载脚本程序集时调用。
  • OnEnable:在 ScriptableObject 创建或加载对象时调用。
  • OnValidate:这是一个仅在编辑器下调用的函数,在 Unity 加载脚本或者在 Inspector 窗口中更改值时会被调用。

生命周期函数代码

private void Awake()
{
    Debug.Log("数据文件创建时会调用");
}

private void OnEnable()
{
    
}

private void OnDisable()
{
    
}

private void OnDestroy()
{
    
}

private void OnValidate()
{
    Debug.Log("值改变");
}

ScriptableObject好处的体现

编辑器中的数据持久化

通过代码修改数据对象中的内容,会影响数据文件,实现了在编辑器中数据的持久化。 这种数据持久化只在编辑模式下有效,在发布和运行时不会保存数据。

myData.i = 6666;
myData.f = 54250.66f;
myData.b = false;
myData.PrintInfo();


复用数据

当多个对象关联同一个数据文件时,它们实际上是共享一组数据的,这样可以更加节约内存空间。

总结

其实创建出来的数据资源文件,你可以把它理解成一种记录数据的资源
它的使用方式,和我们以前使用Unity当中的其它资源规则是一样的
比如:预设体、音频文件、视频文件、动画控制器文件、材质球等等
只不过通过继承ScriptableObject类生成的数据资源文件,它主要是和数据相关的


3.2 知识点代码

Lesson03_ScriptableObject数据文件的使用

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

public class Lesson03_ScriptableObject数据文件的使用 : MonoBehaviour
{
    public MyData myData;
    void Start()
    {
        #region 知识点一 ScriptableObject数据文件的使用
        //1.通过Inspector中的public变量进行关联
        //1-1.创建一个数据文件
        //1-2.在继承MonoBehaviour类中申明数据容器类型的成员 在Inspector窗口进行关联
        //myData.PrintInfo();

        //2.通过资源加载的信息关联
        //加载数据文件资源
        //注意:Resources、AB包、Addressables都支持加载继承ScriptableObject的数据文件
        myData = Resources.Load<MyData>("MyDataTest");
        myData.PrintInfo();

        //注意:如果多个对象关联同一个数据容器文件,他们共享的是一个对象
        //     因为是引用对象,所以在其中任何地方修改后,其它地方也会发生改变
        #endregion

        #region 知识点二 ScriptableObject的生命周期函数
        //ScriptableObject和MonoBehavior很类似
        //它也存在生命周期函数
        //但是生命周期函数的数量更少
        //主要做了解,一般我们使用较少

        //Awake 数据文件创建时调用

        //OnDestroy ScriptableObject 对象将被销毁时调用
        //OnDisable ScriptableObject 对象销毁时、即将重新加载脚本程序集时 调用
        //OnEnable ScriptableObject 创建或者加载对象时调用

        //OnValidate 编辑器才会调用的函数,Unity在加载脚本或者Inspector窗口中更改值时调用
        #endregion

        #region 知识点三 ScriptableObject好处的体现
        //1.编辑器中的数据持久化
        //通过代码修改数据对象中内容,会影响数据文件
        //相当于达到了编辑器中数据持久化的目的
        //(该数据持久化 只是在编辑模式下的持久,发布运行时并不会保存数据)
        myData.i = 6666;
        myData.f = 54250.66f;
        myData.b = false;
        myData.PrintInfo();

        //2.复用数据
        //如果多个对象关联同一个数据文件
        //相当于他们复用了一组数据,内存上更加节约空间
        #endregion

        #region 总结
        //其实创建出来的数据资源文件,你可以把它理解成一种记录数据的资源
        //它的使用方式,和我们以前使用Unity当中的其它资源规则是一样的
        //比如:预设体、音频文件、视频文件、动画控制器文件、材质球等等
        //只不过通过继承ScriptableObject类生成的数据资源文件,它主要是和数据相关的
        #endregion
    }
}

MyData

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

[CreateAssetMenu(fileName ="MrTangData", menuName ="ScriptableObject/我的数据", order = 0)]
public class MyData : ScriptableObject
{
    //声明成员时需要注意
    //我们可以声明任何类型的成员变量
    //但是需要注意:如果希望之后在Inspector窗口中能够编辑它
    //那你在这里声明的变量规则 要和 MonoBehavior当中public变量的规则是一样的

    public int i;
    public float f;
    public bool b;

    public GameObject obj;
    public Material m;
    public AudioClip audioClip;
    public VideoClip videoClip;

    private void Awake()
    {
        Debug.Log("数据文件创建时会调用");
    }

    private void OnEnable()
    {
        
    }

    private void OnDisable()
    {
        
    }

    private void OnDestroy()
    {
        
    }


    private void OnValidate()
    {
        Debug.Log("值改变");
    }

    public void PrintInfo()
    {
        Debug.Log(i);
        Debug.Log(f);
        Debug.Log(b);
    }

}

3.3 练习题

请使用上节课做的游戏设置信息数据文件,做一个设置界面,使用该数据文件来更新界面,并且做到每次重启游戏数据能被记录

在场景中创建设置面板和各控件

创建SettingPanel脚本,外部关联变量。设置一个设置信息数据资源文件变量,关联上节练习题创建的设置信息数据文件。

public class SettingPanel : MonoBehaviour
{
    public Toggle musicTog; // 音乐开关
    public Toggle soundTog; // 音效开关
    public Slider musicSlider; // 音乐滑动条
    public Slider soundSlider; // 音效滑动条
    
    public SettingInfo settingInfo; // 设置信息
}

在Start中一开始读取数据文件的值,赋值给各控件。并给各控件添加值改变监听,改变后记录修改后的值到数据文件中。

void Start()
{
    // 将设置信息应用到UI控件上
    musicTog.isOn = settingInfo.musicIsOpen;
    soundTog.isOn = settingInfo.soundIsOpen;
    musicSlider.value = settingInfo.musicValue;
    soundSlider.value = settingInfo.soundValue;

    // 当音乐开关控件值发生变化时,记录修改后的值到设置信息中
    musicTog.onValueChanged.AddListener((value) =>
    {
        settingInfo.musicIsOpen = value;
    });

    // 当音效开关控件值发生变化时,记录修改后的值到设置信息中
    soundTog.onValueChanged.AddListener((value) =>
    {
        settingInfo.soundIsOpen = value;
    });

    // 当音乐滑动条控件值发生变化时,记录修改后的值到设置信息中
    musicSlider.onValueChanged.AddListener((value) =>
    {
        settingInfo.musicValue = value;
    });

    // 当音效滑动条控件值发生变化时,记录修改后的值到设置信息中
    soundSlider.onValueChanged.AddListener((value) =>
    {
        settingInfo.soundValue = value;
    });
}

注意,在编辑器中看起来好像实现了数据持久化,但是其实打包出去并不能数据持久化,只是在编辑器上看起来有数据持久化。如果打包遇到报错可能是MenuItem特性用到了编辑器相关的代码,需要把他包一层放到Editor文件夹中。




3.4 练习题代码

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

public class SettingPanel : MonoBehaviour
{
    public Toggle musicTog; // 音乐开关
    public Toggle soundTog; // 音效开关
    public Slider musicSlider; // 音乐滑动条
    public Slider soundSlider; // 音效滑动条

    public SettingInfo settingInfo; // 设置信息

    void Start()
    {
        // 将设置信息应用到UI控件上
        musicTog.isOn = settingInfo.musicIsOpen;
        soundTog.isOn = settingInfo.soundIsOpen;
        musicSlider.value = settingInfo.musicValue;
        soundSlider.value = settingInfo.soundValue;

        // 当音乐开关控件值发生变化时,记录修改后的值到设置信息中
        musicTog.onValueChanged.AddListener((value) =>
        {
            settingInfo.musicIsOpen = value;
        });

        // 当音效开关控件值发生变化时,记录修改后的值到设置信息中
        soundTog.onValueChanged.AddListener((value) =>
        {
            settingInfo.soundIsOpen = value;
        });

        // 当音乐滑动条控件值发生变化时,记录修改后的值到设置信息中
        musicSlider.onValueChanged.AddListener((value) =>
        {
            settingInfo.musicValue = value;
        });

        // 当音效滑动条控件值发生变化时,记录修改后的值到设置信息中
        soundSlider.onValueChanged.AddListener((value) =>
        {
            settingInfo.soundValue = value;
        });
    }
}


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

×

喜欢就点赞,疼爱就打赏