¿Qué estás buscando?
Hero background image
Utiliza enums basados en ScriptableObject en tu proyecto Unity
Esta página se ha traducido automáticamente. Para ver la versión original para comprobar su exactitud y como fuente confiable

Esta página explica cómo utilizar enums basados en ScriptableObject en su proyecto Unity.

Esta es la tercera de una serie de seis miniguías creadas para ayudar a los desarrolladores de Unity con la demo que acompaña al libro electrónico, Crear arquitectura de juego modular en Unity con ScriptableObjects.

La demostración se inspira en la mecánica clásica de los juegos de arcade de pelota y paleta, y muestra cómo ScriptableObjects puede ayudarle a crear componentes comprobables, escalables y fáciles de diseñar.

En conjunto, el libro electrónico, el proyecto de demostración y estas miniguías proporcionan las mejores prácticas para utilizar patrones de diseño de programación con la clase ScriptableObject en su proyecto de Unity. Estos consejos pueden ayudarle a simplificar su código, reducir el uso de memoria y fomentar la reutilización del código.

Esta serie incluye los siguientes artículos:

Nota importante antes de empezar

Antes de sumergirte en el proyecto de demostración ScriptableObject y en esta serie de miniguías, recuerda que, en el fondo, los patrones de diseño son sólo ideas. No se aplicarán a todas las situaciones. Estas técnicas pueden ayudarte a aprender nuevas formas de trabajar con Unity y ScriptableObjects.

Cada modelo tiene sus pros y sus contras. Elija sólo las que beneficien significativamente a su proyecto específico. ¿Sus diseñadores confían mucho en el editor de Unity? Un patrón basado en ScriptableObject podría ser una buena opción para ayudarles a colaborar con sus desarrolladores.

En última instancia, la mejor arquitectura de código es la que se adapta a tu proyecto y a tu equipo.

tab 1
BORRAR O REORDENAR LOS VALORES DE UN ENUM PUEDE PROVOCAR UN COMPORTAMIENTO INESPERADO.
Enumeraciones ampliables

Los Enums son una forma práctica de gestionar un conjunto fijo de valores con nombre en el código. Sin embargo, tienen algunas limitaciones. Dado que los valores enum serializados se almacenan como enteros en lugar de sus nombres simbólicos, eliminar o reordenar un valor puede provocar un comportamiento incorrecto o inesperado. Esto significa que los enums, especialmente cuando tienes muchos de ellos, pueden crear dolores de cabeza en el desarrollo de Unity.

El enfoque estándar

Este es el aspecto de un enum típico:

[System.Serializable]
public enum HandGestures
{
Rock,
Papel,
Tijeras
}

Puedes serializar un enum con el atributo System.Serializable y aparecerá en el Inspector.

El problema

Reordenar o borrar un valor puede causar problemas. Dado que cada valor internamente es un entero, lo que representa puede convertirse en algo diferente. En el ejemplo dado, la eliminación del valor Papel haría que Tijeras asumiera el valor 1.

O, si añadimos un valor como en el ejemplo siguiente.

El valor del enum seleccionado cambiaría si viene después de la entrada eliminada.

Esto puede causar problemas a la hora de mantener y actualizar proyectos, sobre todo cuando el enum contiene numerosos valores. Puede mitigar este problema dejando un elemento en blanco o sin utilizar, o estableciendo explícitamente valores enteros. Sin embargo, ninguna de las dos soluciones es ideal.

tab3
COMPROBACIÓN DE LA IGUALDAD ENTRE OBJETOS SCRIPTABLES
Enumeraciones basadas en ScriptableObject

Los enums basados en ScriptableObject ofrecen la funcionalidad de los enums tradicionales, pero se almacenan como activos individuales. Por ejemplo, mira el PlayerIDSO ScriptableObject en el proyecto PaddleBallSO en el ejemplo de abajo.

Esencialmente, se trata de un ScriptableObject en blanco.

Puede utilizarlo para crear una serie de activos ScriptableObject en el proyecto, como P1, P2, etc. Incluso cuando no contienen ningún dato, puede utilizar ScriptableObjects para la comparación. Basta con crear un nuevo activo ScriptableObject en el proyecto y darle un nombre.

Puedes crear tantos ID de reproductores como necesites dentro del proyecto y cambiar fácilmente de uno a otro. Sólo tienes que cambiar el activo asignado en el script GameDataSO.

Si está comprobando la igualdad, funciona de forma similar a un enum. ¿Dos variables se refieren al mismo ScriptableObject? Si es así, son el mismo tipo de artículo. De lo contrario, no lo son.

Incluso sin ningún dato extra, el ScriptableObject representa una categoría o tipo de artículo.

ID de jugador en PaddleBallSO

En PaddleBallSO, el PlayerIDSO se convierte en una designación de equipo. Utilizamos los activos P1 y P2 en el GameDataSO para diferenciar entre las dos palas.

El script GameSetup asigna a cada paleta un ID de jugador. Durante el juego, los scripts de Paddle comparan la entrada del jugador con el ID del equipo designado.

Esto tiene aplicaciones para cualquier tipo de juego multijugador. Alternativamente, considere la posibilidad de adoptarlos en cualquier otro lugar donde busque un enum.

Dado que son simplemente asignaciones en el Inspector, los ScriptableObjects no están sujetos a los mismos problemas con el cambio de nombre y la reordenación.

¿Quieres cambiar los nombres de los identificadores a "Jugador1" o "Jugador2", respectivamente? Puedes hacerlo y todo sigue funcionando. ¿Añadir más ScriptableObjects? No hay problema: la asignación de activos en el Inspector sigue siendo la misma.

tab5
BLOQUES UTILIZAN EQUIPOS ASIGNADOS PARA LAS COMPARACIONES.
Patterns demo

Este comportamiento es útil para crear juego. En la demostración de Patrones, haga clic en el botón Cambiar Enum para cambiar de equipo. Un MonoBehaviour en la DemoBall actualiza el SpriteRenderer en consecuencia.

¿Inflige el balón daños a un Bloque cuando choca? Descúbrelo realizando una rápida prueba de igualdad. He aquí una forma de compararlos en el siguiente ejemplo de código.

Este método puede determinar si dos GameObjects están en el mismo equipo, lo cual es útil cuando se comprueban interacciones amistosas versus enemigas. Esta simple comparación puede aplicarse a la recogida de objetos, al daño o a cualquier otra cosa que tenga un "equipo" o una "alineación."

Ampliar el comportamiento

La parte divertida ocurre cuando añades lógica a tus ScriptableObjects. A diferencia de un enum convencional, un ScriptableObject puede tener campos y métodos, además de contener datos.

Utilícelos para que cada ScriptableObject pueda tener una lógica de comparación especializada. Por ejemplo, podrías tener un ScriptableObject que defina efectos de daño especiales (por ejemplo, frío, calor, eléctrico, mágico, etc.).

Si tu aplicación requiere un sistema de inventario para equipar objetos de juego, los ScriptableObjects pueden representar tipos de objetos o ranuras de armas. ¿Hay personajes que no pueden llevar determinados objetos? ¿Algunos objetos son mágicos o tienen habilidades especiales? Los enums basados en ScriptableObject pueden añadir métodos para comprobarlo.

El MonoBehaviour DemoBall del ejemplo anterior incluye el método AreEqual para comparar ScriptableObjects. Al ampliar el comportamiento, puede agrupar la lógica de comparación dentro del propio ScriptableObject.

En la demo de Patrones, podrías modificar la bola para que sea más selectiva al colisionar con un objeto. Observe un elemento de uso general para colisión en el siguiente ejemplo de código.

Esto podría lograr resultados similares a la demostración actual, pero ahora tiene un campo m_Weakness. Esto permite que cada ScriptableObject defina otro ScriptableObject para destruir en colisión.

En lugar de llamar al método AreEqual, cada ScriptableObject simplemente gestiona su propia lógica de comparación.

El resultado es más flexible y ampliable. En lugar de hacer que el balón destruya un bloque de otro equipo, puedes ser específico. Múltiples bolas en la escena podrían destruir diferentes bloques, dependiendo de sus CollisionItems individuales.

Esto prepara el terreno para interacciones diferentes y más complejas. Si quisieras hacer un sistema de piedra-papel-tijera, podrías definir tres ScriptableObjects: Piedra, papel o tijera. Cada uno podría tener su propio y único m_Weakness, y utilizar el método IsWinner para manejar las interacciones.

A diferencia de los enums, los ScriptableObjects hacen que este proceso sea modular y adaptable. No hay necesidad de depender de estructuras de datos adicionales o añadir lógica extra para sincronizar con un conjunto separado de datos. Basta con añadir un campo y/o método adicional para gestionar la lógica.

Ventajas de los enums basados en ScriptableObject

Una vez que se familiarice con los enums basados en ScriptableObject, descubrirá que pueden mejorar su flujo de trabajo, especialmente cuando trabaje con compañeros de equipo. Al tratarse de activos, su actualización genera menos conflictos de fusión, lo que reduce el riesgo de pérdida de datos.

Añadir nuevos enums basados en ScriptableObject es como crear otro asset. A diferencia de los enums tradicionales, añadir nuevos valores no romperá el código existente. Además, Unity ya cuenta con herramientas integradas para buscarlos, filtrarlos y organizarlos, como cualquier otro activo.

Además, la interfaz de arrastrar y soltar del editor permite a los diseñadores ampliar los datos del juego sin la ayuda de un desarrollador de software. Tendrá que coordinar la configuración inicial de los campos, pero los diseñadores podrán rellenarlos con sus propios datos.

salida programable
Más recursos de ScriptableObject

Los enums basados en ScriptableObject son un recurso más que su equipo puede utilizar para mejorar la colaboración y la eficacia.

Más información sobre patrones de diseño con ScriptableObjects en nuestro libro electrónico técnico Crear una arquitectura de juego modular en Unity con ScriptableObjects. También puedes encontrar más información sobre patrones de diseño comunes en el desarrollo de Unity en Mejora tu código con patrones de programación de juegos.

¿Te gustó este contenido?