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