赞
踩
ScriptableObject是一个数据容器,它可以用来保存大量数据,主要的用处就是在项目中通过将数据存储在ScriptableObject对象,避免值拷贝来减少游戏运行中的内存占用。
当你有一个预制体,上面挂了一个存有不变数据的MonoBehaviour 脚本时,每次我们实例化预制体时都将产生一次数据拷贝,这时我们可以使用ScriptableObject对象来存储数据,然后通过引用来访问预制体中的数据。这样可以避免在内存中产生一份拷贝数据。与MonoBehaviour 一样,ScriptableObject也继承自Unity基类object,但是与MonoBehaviour不同的是,ScriptableObject不能和GameObject对相关联,相反,通常我们会将它保存为Assets资源。
在编辑器模式下,我们可以在编辑和运行时将数据保存到ScriptableObject,因为保存ScriptableObject需要用到编辑器空间个脚本,但是在开发模式下不能使用ScriptableObject来保存数据,但是你可以使用ScriptableObject资源中已保存的数据。
游戏中我们创建并保存ScriptableObject数据时有两种方式
第一种:
- [CreateAssetMenu(fileName = "Data1", menuName = "ScriptableObjects/SpawnManagerScriptableObject1", order = 1)]
- public class SpawnManagerScriptableObject1 : ScriptableObject
- {
- public string prefabName;
-
- public int numberOfPrefabsToCreate;
- public Vector3[] spawnPoints;
- }
-
- [CreateAssetMenu(fileName = "Data1", menuName = "ScriptableObjects/SpawnManagerScriptableObject2", order = 2)]
- public class SpawnManagerScriptableObject2 : ScriptableObject
- {
- public string prefabName;
-
- public int numberOfPrefabsToCreate;
- public Vector3[] spawnPoints;
- }
在unity中可以看到已经生成了对应的工具选项如下:
第二种方式写法:
- public class MakeScriptableObject
- {
- [MenuItem("Assets/Create/My Scriptable Object")]
- public static void CreateMyAsset()
- {
- MyScriptableObjectClass asset = ScriptableObject.CreateInstance<MyScriptableObjectClass>();
- asset.init();
- AssetDatabase.CreateAsset(asset, "Assets/MyScripableObject.asset");
- AssetDatabase.SaveAssets();
-
- EditorUtility.FocusProjectWindow();
-
- Selection.activeObject = asset;
- }
- }
-
- public class MyScriptableObjectClass : ScriptableObject
- {
- public int age;
- public string name = "zxh";
- [Serializable]
- public class abc
- {
- public int grade;
- public int clas;
- }
- public abc ta;
- public void init()
- {
- age = 30;
- name = "hello";
- ta = new abc();
- ta.clas = 18;
- ta.grade = 19;
- }
-
- }
在unity中可以看到已经生成了对应的工具选项如下:
我们在挂有预制体的脚本中使用方式如下:
- using UnityEngine;
-
- public class Spawner : MonoBehaviour
- {
- // The GameObject to instantiate.
- public GameObject entityToSpawn;
-
- // An instance of the ScriptableObject defined above.
- public SpawnManagerScriptableObject spawnManagerValues;
-
- // This will be appended to the name of the created entities and increment when each is created.
- int instanceNumber = 1;
-
- void Start()
- {
- SpawnEntities();
- }
-
- void SpawnEntities()
- {
- int currentSpawnPointIndex = 0;
-
- for (int i = 0; i < spawnManagerValues.numberOfPrefabsToCreate; i++)
- {
- // Creates an instance of the prefab at the current spawn point.
- GameObject currentEntity = Instantiate(entityToSpawn, spawnManagerValues.spawnPoints[currentSpawnPointIndex], Quaternion.identity);
-
- // Sets the name of the instantiated entity to be the string defined in the ScriptableObject and then appends it with a unique number.
- currentEntity.name = spawnManagerValues.prefabName + instanceNumber;
-
- // Moves to the next spawn point index. If it goes out of range, it wraps back to the start.
- currentSpawnPointIndex = (currentSpawnPointIndex + 1) % spawnManagerValues.spawnPoints.Length;
-
- instanceNumber++;
- }
- }
- }
将上面的脚本挂到预制体上,然后将我们保存好的ScriptableObject数据赋给spawnManagerValues字段即可。
打开上述第二种方式生成的数据文件如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。