scriptableobject类理解
ScriptableObject是一个数据容器,它可以用来保存大量数据,主要的用处就是在项目中通过将数据存储在ScriptableObject对象,避免值拷贝来减少游戏运行中的内存占用。当你有一个预制体,上面挂了一个存有不变数据的MonoBehaviour 脚本时,每次我们实例化预制体时都将产生一次数据拷贝,这时我们可以使用ScriptableObject对象来存储数据,然后通过引用来访问预制..
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字段即可。
打开上述第二种方式生成的数据文件如下:
更多推荐
所有评论(0)