unity3d
ScriptableObject
Buscar..
Observaciones
ScriptableObjects con AssetBundles
Preste atención cuando agregue prefabs a AssetBundles si contienen referencias a ScriptableObjects. Dado que los ScriptableObjects son esencialmente activos, Unity crea duplicados de ellos antes de agregarlos a AssetBundles, lo que puede resultar en un comportamiento no deseado durante el tiempo de ejecución.
Cuando carga un GameObject de este tipo desde un AssetBundle, puede ser necesario reinyectar los activos de ScriptableObject en los scripts cargados, reemplazando los empaquetados. Ver Inyección de dependencia.
Introducción
Los ScriptableObjects son objetos serializados que no están vinculados a escenas o juegos como MonoBehaviours. Para decirlo de una manera, son datos y métodos vinculados a archivos de activos dentro de su proyecto. Estos recursos de ScriptableObject se pueden pasar a MonoBehaviours u otros ScriptableObjects, donde se puede acceder a sus métodos públicos.
Debido a su naturaleza como activos serializados, constituyen excelentes clases de administrador y fuentes de datos.
Creación de activos ScriptableObject
A continuación se muestra una implementación simple de ScriptableObject.
using UnityEngine;
[CreateAssetMenu(menuName = "StackOverflow/Examples/MyScriptableObject")]
public class MyScriptableObject : ScriptableObject
{
[SerializeField]
int mySerializedNumber;
int helloWorldCount = 0;
public void HelloWorld()
{
helloWorldCount++;
Debug.LogFormat("Hello! My number is {0}.", mySerializedNumber);
Debug.LogFormat("I have been called {0} times.", helloWorldCount);
}
}
Al agregar el atributo CreateAssetMenu
a la clase, Unity lo incluirá en el submenú Activos / Crear . En este caso, se encuentra en Activos / Crear / StackOverflow / Ejemplos .
Una vez creadas, las instancias de ScriptableObject se pueden pasar a otros scripts y ScriptableObjects a través del Inspector.
using UnityEngine;
public class SampleScript : MonoBehaviour {
[SerializeField]
MyScriptableObject myScriptableObject;
void OnEnable()
{
myScriptableObject.HelloWorld();
}
}
Crear instancias de ScriptableObject a través de código
Crea nuevas instancias de ScriptableObject a través de ScriptableObject.CreateInstance<T>()
T obj = ScriptableObject.CreateInstance<T>();
Donde T
extiende ScriptableObject
.
No cree ScriptableObjects llamando a sus constructores, es decir.
new ScriptableObject()
.
La creación de ScriptableObjects por código durante el tiempo de ejecución rara vez se requiere porque su uso principal es la serialización de datos. También podrías usar clases estándar en este punto. Es más común cuando se trata de extensiones de editor de secuencias de comandos.
ScriptableObjects se serializan en el editor incluso en PlayMode
Se debe tener especial cuidado al acceder a campos serializados en una instancia de ScriptableObject.
Si un campo se marca como public
o se serializa a través de SerializeField
, el cambio de su valor es permanente. No se reinician al salir de playmode como lo hacen MonoBehaviours. Esto puede ser útil a veces, pero también puede hacer un desastre.
Debido a esto, es mejor hacer que los campos serializados sean de solo lectura y evitar los campos públicos por completo.
public class MyScriptableObject : ScriptableObject
{
[SerializeField]
int mySerializedValue;
public int MySerializedValue
{
get { return mySerializedValue; }
}
}
Si desea almacenar valores públicos en un objeto Scriptable que se restablecen entre sesiones de juego, considere usar el siguiente patrón.
public class MyScriptableObject : ScriptableObject
{
// Private fields are not serialized and will reset to default on reset
private int mySerializedValue;
public int MySerializedValue
{
get { return mySerializedValue; }
set { mySerializedValue = value; }
}
}
Encuentra ScriptableObjects existentes durante el tiempo de ejecución
Para encontrar ScriptableObjects activos durante el tiempo de ejecución, puede usar Resources.FindObjectsOfTypeAll()
.
T[] instances = Resources.FindObjectsOfTypeAll<T>();
Donde T
es el tipo de instancia de ScriptableObject que está buscando. Activo significa que se ha cargado en la memoria de alguna forma antes.
Este método es muy lento, así que recuerde almacenar en caché el valor de retorno y evite llamarlo con frecuencia. Hacer referencia a ScriptableObjects directamente en sus scripts debe ser su opción preferida.
Sugerencia: puede mantener sus propias colecciones de instancias para búsquedas más rápidas. Haga que sus ScriptableObjects se registren en una colección compartida durante
OnEnable()
.