La siguiente entrada del blog, a menos que se indique lo contrario, fue escrita por un miembro de la comunidad de Gamasutras.
Los pensamientos y opiniones expresados son los del escritor y no los de Gamasutra o su empresa matriz.
Objetivo
El objetivo principal de esta entrada del blog es darle una idea sobre ScriptableObject en Unity.
¿Qué es Scriptable Object?
¿Cuál es la diferencia entre ScriptableObject y la clase Monobehaviour?
¿Cuáles son los pros y los contras de Scriptableobject?
¿Cómo utilizar ScriptableObject?
Vamos a entender todas las preguntas dando un paseo por este blog sobre ScriptableObject
Según la documentación de la API de Unity,
«ScriptableObject es una clase de la que puedes derivar si quieres crear objetos que no necesitan estar unidos a los objetos del juego»
Confundido…
No te preocupes, si no lo has entendido. Aquí, voy a explicar lo que significa.
Como sabemos, con Unity, todo es un Objeto.
Los monoconductores son uno de los Objetos.
Objetos de Juego: En tu escena, puedes moverte con transformaciones.
ScriptableObject es un tipo de Objeto pero, sólo puede Contener Datos.
Así que, no se involucran en el juego real.
Espero que hayas entendido la definición de ScriptableObject.
Discutimos los Pros y los Contras de ScriptableObject.
Pros de ScriptableObject:
- Incorporados a Unity
- Están muy bien mantenidos por Unity.
- Puedes interactuar con ellos muy fácilmente en el inspector de Unity.
- Se pueden guardar como Assets
- Puedes crearlo como un mini archivo dentro de tu proyecto.
- Puedes actualizarlo y guardarlo según los requisitos de tu juego.
- Se puede guardar durante el tiempo de ejecución
- Si cambias algo durante el tiempo de ejecución lo recordará.
- Solución interna
- Cuando se trata de obtener los datos durante el tiempo de ejecución del juego, no se preocupa de analizar los archivos externos que entrarán más en juego.
- Grandes cantidades de datos
- Puede guardar millones de enteros dentro de un ScriptableObject.
- Así, hay un montón de espacio(sin función de límite de tamaño).
- Añadir a la estructura a medida que avanza
- Cuando usted está construyendo un objeto scriptable y crear algunas instancias de la misma y darse cuenta de ,ohh necesito un nuevo ajuste para ‘moveSpeed’ o cualquier variable adicional que usted necesita puede agregar, no va a interrumpir su variable.
- La eliminación de la variable puede tener un poco de impacto negativo.
Cons de ScriptableObject:
- Requiere un editor de scripting
- Si quieres hacer assets de scripting entonces tienes que saber un poco sobre ello.
- No se puede editar fuera de Unity
- Si estás trabajando estrictamente con Unity eso no es realmente un gran problema.
- Pero si usted tiene como solución de base de equipo, donde desea enviar los archivos a alguien y que ellos editen entonces no va a funcionar.
- No se puede guardar una vez desplegado
- No se puede guardar durante el tiempo de ejecución, una vez que haya construido el juego lo que significa que esto no es la solución para guardar los datos de un jugador.Esto es sólo para guardar los datos de desarrollo del juego.
Tomemos un ejemplo para entender cómo utilizar ScriptableObject en el juego.
Déjame darte una tarea primero.
Supongamos que tenemos un juego de 10 niveles y en cada nivel el comportamiento del enemigo cambiará.
¿Tienes alguna idea de cómo lo harás?
Ahh, podrías pensar en hacer 10 prefabricados de 10 enemigos diferentes y asignarlos a cada nivel.
¿Estás seguro de que es una buena práctica?
En realidad, la respuesta es No.
«Porque un objeto enemigo puede tener 4 variables y la función Update() con él, y supongamos que utiliza 4 Mb de memoria, por lo que 10 enemigos de nivel pueden requerir 40 Mb de cantidad de memoria.»
Así que, aquí está la solución. Usar ScriptableObject para almacenar los datos de los enemigos.
Desarrollemos nuestro mini juego con ScriptableObject.
Primero, crearé un simple script sin usar un ScriptableObject. (Según nuestra primera idea de crear diferentes prefab de cada enemigo diferente y asignarlo a cada nivel 😉 )
Paso 1
- Crear un GameObject vacío llamándolo Enemy.
Paso 2
- Crear un script en C# y llamarlo EnemyMove
Escribir el siguiente código en EnemyMove.cs
public class EnemyMove : MonoBehaviour {#region PUBLIC_VARIABLESpublic string name;public int moveSpeed;public Color color;public string colorName; public SpriteRenderer spriterendere;#endregion#region PRIVATE_VARIABLESprivate float speed;Vector3 newPosition;#endregion#region UNITY_CALLBACKSvoid Update () {ChangeSpeed();gameObject.name = name;spriterendere.color = color;newPosition=transform.position;newPosition.y = Mathf.Sin (Time.time) * speed;transform.position = newPosition;}#endregion#region PROVATE_METHODSprivate void ChangeSpeed(){speed = Mathf.MoveTowards (speed,moveSpeed,Time.deltaTime);}#endregion}
Paso 3
- Asignarlo a GameObject(Enemy) vacío.
- El script EnemyMove tiene tres variables públicas.
- Si el juego tiene tantos GameObject enemigos con el script enemyMove con él entonces utiliza mucha memoria.
- Para que según nuestra solución ScriptableObject, podemos hacer un script EnemyData En lugar de almacenar estas variables dentro del script EnemyMove.
Paso 4
- Crear un script en C# llamado EnemyData.
- que herede ScriptableObject en lugar de Monobehaviour.
Escribir el siguiente código en EnemyData.cs.
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Paso 5
- Cambiar el código dentro de ‘EnemyMove’,que fue creado anteriormente.
- Crear una variable pública ‘data’ que es la referencia de ‘EnemyData’.
- Quitar la pública que ya está en ‘EnemyData’
Cambiar según el siguiente código.
public class EnemyMove : MonoBehaviour {#region PUBLIC_VARIABLESpublic EnemyData data;public SpriteRenderer spriterendere;#endregion#region PRIVATE_VARIABLESprivate float speed;Vector3 newPosition;#endregion#region UNITY_CALLBACKSvoid Update () {ChangeSpeed();gameObject.name = name;spriterendere.color = data.color;newPosition=transform.position;newPosition.y = Mathf.Sin (Time.time) * speed;transform.position = newPosition;}#endregion#region PROVATE_METHODSprivate void ChangeSpeed(){speed=Mathf.MoveTowards (speed,data.moveSpeed,Time.deltaTime);}#endregion}
Ahora puedes ver que dentro del Inspector para el GameObject Enemigo en la variable ‘Data’ aparecerá,
¿Alguna idea..de lo que supones asignar por aquí?
Seguidme…
Paso 1
- Añadir una línea en EnemyData.cs como sigue
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Paso 2
- Crea una carpeta Game data y haz lo siguiente
Paso 3
- Nómbralo como quieras.
- Ahora, puedes ver todas las variables dentro del EnemyData en la ventana del inspector, puedes cambiar los valores de las variables aquí.
Paso 4
- Asigna esto en el script ‘EnemyMove’
Seguro que ahora tienes todas las respuestas.
Conclusión
- ScriptableObject son realmente buenos por el hecho de que pueden dividir tus datos en trozos de mayor tamaño.
- Para que no estés consumiendo mucha memoria.
- ScriptableObject es sólo para el propósito de desarrollo.