概述
ScriptableObject是什么
是Unity提供的数据配置存储基类,是一个可以存储数据的容器
数据复用
一个子弹对象,每次实例化的时候,N个子弹上都有脚本,脚本内存储子弹的信息,比如速度,攻击力等
这些大量的细粒度对象对内存来说是一定的浪费
我们可以用SO进行数据复用
配置文件
我们可以在unity内部进行数据的配置,避免xml,json等的使用
编辑模式下的数据持久化
在unity编辑器内SO有持久化特性
SO的好处
- 在unity内文件配置
- 数据复用
- 更好的处理数据的多态行为
数据文件的创建
自定义SO数据容器
1 2 3 4 5 6 7 8 9 10 11 12 13
| using UnityEngine; using UnityEngine.Video;
namespace SO { public class MyData : ScriptableObject { public GameObject obj; public float speed; public int atk; public VideoClip vc; } }
|
我们可以在inspector里关联成员变量,注意,这些只是默认数据
这只是一个类,我们还没有创建数据资源文件
创建数据资源文件
方法有两种
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| using UnityEngine; using UnityEngine.Video;
namespace SO { [CreateAssetMenu(fileName = "DefaultMyData",menuName = "MyData",order = 0)] public class MyData : ScriptableObject { public GameObject obj; public float speed; public int atk; public VideoClip vc; } }
|
用静态方法创建数据对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| using UnityEditor; using UnityEngine;
namespace SO { public class ScriptableObjectTool { [MenuItem("ScriptableObject/CreateMyData")] public static void CreateMyData() { MyData asset = ScriptableObject.CreateInstance<MyData>(); AssetDatabase.CreateAsset(asset,"Assets/Resources/MyDataTest.asset"); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } }
|
点击按钮,即可创建文件
数据文件的使用
数据文件的使用
直接在MonoBehaviour类中作为成员使用
- 通过Inspector关联使用
- 通过Resource.Load取用
SO的生命周期函数
Awake:文件创建时调用
OnDestroy:对象被销毁时调用
OnEnable:创建或加载对象时调用
OnDisable:销毁对象或即将重新加载脚本程序集时调用
OnValidata:编辑器才会调用的函数,unity在加载脚本或者Inspector窗口中更改值时调用
非持久数据
非持久数据指的是不管在编辑器内还是发布后都不会持久化的数据
我们可以根据自己的需求随时创建对应数据对象进行使用
使用SO生成非持久化数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| using UnityEngine;
namespace SO { public class Test : MonoBehaviour { private MyData data;
private void Start() { data = ScriptableObject.CreateInstance<MyData>(); Debug.Log(data.atk); } } }
|
非持久数据的优点
节约硬盘空间,仅在内存中使用
ScriptableObject数据持久化
Json结合SO存储数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| using System.IO; using UnityEngine;
namespace SO { public class SaveManager : MonoBehaviour { [SerializeField]private MyData data;
private void Start() { var str = JsonUtility.ToJson(data); File.WriteAllText(Application.persistentDataPath + "/testJson.json",str); } } }
|
1
| {"obj":{"instanceID":22550},"speed":5.0,"atk":5,"vc":{"instanceID":0}}
|
Json结合SO读取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| using System.IO; using UnityEngine;
namespace SO { public class SaveManager : MonoBehaviour { [SerializeField]private MyData data;
private void Start() { var str =File.ReadAllText(Application.persistentDataPath + "/testJson.json"); JsonUtility.FromJsonOverwrite(str,data); Debug.Log(data.atk); } } }
|
SO应用
SO适合做配置文件,因为配置文件一般是只读的,游戏不会修改配置文件
SO不需要第三方软件,比如Excel,Json编辑器等
当我们使用大量细粒度的对象时,比如子弹,许多子弹可以共享同一份数据,而不用为每个子弹都分配内存