![Hero background image](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F0c660eec367947d97e5c33fc2eb8f056c53365f2-1200x675.jpg&w=3840&q=100)
Esta página proporciona una descripción general de PaddleBallSO, el proyecto de demostración complementario del libro electrónico Cree una arquitectura de juego modular en Unity con ScriptableObjects, y explica cómo utiliza patrones de diseño y modularidad en su arquitectura de código.
Esta es la primera de una serie de seis miniguías creadas para ayudar a los desarrolladores de Unity con la demostración que acompaña al libro electrónico. La demostración está inspirada en la mecánica clásica de los juegos arcade de pelota y paleta y muestra cómo ScriptableObjects puede ayudarlo a crear componentes que sean comprobables, escalables y fáciles de diseñar.
Juntos, el libro electrónico, el proyecto de demostración y estas miniguías brindan las mejores prácticas para usar 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 promover la reutilización del código.
Esta serie incluye los siguientes artículos:
- Separe los datos y la lógica del juego con ScriptableObjects
- Utilice enumeraciones basadas en ScriptableObject en su proyecto de Unity
- Utilice ScriptableObjects como objetos delegados
- Utilice ScriptableObjects como canales de eventos en el código del juego
- Cómo utilizar un conjunto de tiempo de ejecución basado en ScriptableObject
Antes de sumergirse en el proyecto de demostración de ScriptableObject y en esta serie de miniguías, recuerde que, en esencia, los patrones de diseño son solo ideas. No se aplicarán a todas las situaciones. Estas técnicas pueden ayudarle a aprender nuevas formas de trabajar con Unity y ScriptableObjects.
Cada patrón tiene pros y contras. Elija sólo aquellos que beneficien significativamente su proyecto específico. ¿Sus diseñadores dependen en gran medida del Unity Editor? Un patrón basado en ScriptableObject podría ser una buena opción para ayudarlos a colaborar con sus desarrolladores.
En última instancia, la mejor arquitectura de código es la que se adapta a su proyecto y equipo.
![paddleball](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F192acf691c9a632c7bee44e3229c5f1d5347245e-1999x1125.png&w=3840&q=75)
PaddleBallSO se centra en el juego clásico que dio origen a los videojuegos modernos, con dos jugadores, dos palas y una pelota.
El énfasis aquí está en la infraestructura más que en la mecánica del juego. Piense en esto como “plomería del juego”, la base menos glamorosa pero de vital importancia que mantiene su aplicación en funcionamiento.
Este proyecto se centra en cómo ScriptableObjects puede funcionar entre bastidores para crear una aplicación unificada. Úselos para construir sistemas de juego versátiles que puedan simplificar el mantenimiento del proyecto y promover la reutilización del código. También puedes emplearlos para datos de jugadores, gestión del estado del juego, comportamientos en el juego y más.
El proyecto PaddleBallSO es compatible con la última versión de Unity Long Term Support (LTS), actualmente 2022 LTS. Incorpora el kit de herramientas de interfaz de usuario para crear una interfaz de usuario en tiempo de ejecución y el sistema de entrada para manejar las entradas del usuario.
![gestor de arranque](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F284426dcc53dbb2791e88cd61c83bbf21af058d3-1999x1158.png&w=3840&q=75)
Localiza y descarga el proyecto en el repositorio de GitHub.
Cargue Bootloader_scene o habilite Cargar escena Bootstrap en Play desde el menú GameSystems. Ingrese al modo Reproducir para comenzar.
Aunque no son específicos de ScriptableObjects, el proyecto de demostración utiliza un par de técnicas comunes para ayudar a iniciar la aplicación del juego en un estado consistente y predecible.
Un Scene Bootstrapper (o gestor de arranque) es un script de extensión del editor responsable de configurar el estado inicial del juego. Este código de inicialización está separado de la lógica del juego y garantiza que todas las dependencias estén configuradas correctamente para los objetos de la escena.
Para evitar problemas de dependencia, el programa previo configura objetos, administradores o servicios esenciales del juego cuando se carga una escena.
Si su aplicación Unity abarca varias escenas, el gestor de arranque puede forzar la carga de una escena de arranque específica, que es la primera escena de la configuración de compilación. Al salir del modo Reproducción, el Editor recarga la escena anterior.
Otro componente de la escena de arranque, el Administrador de secuencias, puede crear instancias de prefabricados esenciales al cargar la escena. En este proyecto de demostración específico, todo lo necesario para crear el juego es un Prefab, incluida una cámara, SplashScreen, menús de interfaz de usuario y un SceneLoader.
Luego, SceneLoader carga (y descarga) de forma aditiva cualquier escena de juego según sea necesario. En la mayoría de los casos, estas escenas se componen principalmente de casas prefabricadas.
Escenas del proyecto
Cada nivel de minijuego es una escena de Unity separada y aparece en la Configuración de compilación. Desactive SceneBootstrapper en el menú GameSystems si desea explorar esas escenas individuales.
Muchos proyectos también incluyen un área de preparación para el menú principal después de la escena de arranque. Este proyecto de demostración simplificado omite una escena del menú principal.
![tab5](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F8e86a91f23d941afb7c23afaef6b5e0a701a1ddd-1584x602.png&w=3840&q=75)
Utilice los menús Reproducir y Patrón para probar PaddleBallSO, que incluye:
- Diseñe demostraciones de patrones , o ejemplos breves, que muestren técnicas específicas e ilustren cada patrón de forma aislada.
- Minijuegos que los combinan en muestras funcionales y funcionales.
La carpeta Core contiene partes del código base que no son específicas de la aplicación, como los scripts de patrones básicos, la gestión de escenas y la lógica de la interfaz de usuario. Estas son clases más generales que podrían aplicarse a una variedad de aplicaciones.
![tab10](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F2d39fac6f824fba44cbca60a3136d0105d200b50-1999x1125.png&w=3840&q=75)
El juego de muestra recrea una simulación de física 2D icónica y muestra el potencial de los patrones de diseño basados en ScriptableObject.
Sin embargo, antes de profundizar en los patrones, querrás familiarizarte con los MonoBehaviours que componen la aplicación. Como era de esperar, componentes como los scripts Paddle, Ball, Bouncer y ScoreGoal gobiernan el juego básico.
Varios scripts de administrador de nivel superior controlan el flujo del juego:
- GameManger controla los estados del juego (inicio, finalización, reinicio), inicializa los componentes del juego, administra la interfaz de usuario y responde a los eventos.
- GameSetup trabaja con GameManager para configurar la pelota, las paletas, las paredes y las porterías.
- ScoreManager actualiza los valores de puntuación, maneja eventos del juego y controla las actualizaciones de la interfaz de usuario para mostrar la puntuación.
Estos MonoBehaviours funcionan con sus ScriptableObjects. Desempeñan un papel vital al unir estos componentes para que puedan hablar y compartir datos entre ellos.
Los eventos son fundamentales para la comunicación entre las diferentes partes del proyecto. Conectan estos scripts del administrador con otros objetos de la escena y la interfaz de usuario. Esta arquitectura basada en eventos puede ayudar a que el código sea más organizado y depurable.
También proporcionamos ejemplos de demostración simplificados para cada uno de los patrones de ScriptableObject más comunes. A medida que te familiarices con ellos, empezarás a reconocer cómo los ScriptableObjects sustentan la arquitectura del minijuego.
Podríamos haber creado el minijuego presentado con muchas menos líneas de código, pero esta demostración se centra específicamente en patrones de diseño con ScriptableObjects. Tenga en cuenta que también puede implementar muchos de estos patrones sin ScriptableObjects.
Decida en equipo cómo se podría aplicar cada patrón a su proyecto y elija el enfoque que funcione mejor para usted.
![tanb22](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fa8ee97164913a2af247ea6bad5c22c9c2ba7c2d2-1037x627.png&w=3840&q=75)
La modularidad en el desarrollo de software implica dividir una aplicación en partes más pequeñas e independientes. Estos módulos tienen propósitos específicos y se pueden desarrollar y probar por separado.
Cada pequeño conjunto de objetos funciona como una unidad y maneja un aspecto del juego. Esto podría ser cualquier cosa, desde controlar la entrada del jugador, manejar la física o contar la puntuación.
Mientras explora los guiones del proyecto, preste atención a los siguientes puntos clave:
- Construya sus escenas a partir de casas prefabricadas: Notarás que la mayoría de las escenas del proyecto son simplemente colecciones de prefabricados con anulaciones mínimas. Las casas prefabricadas proporcionan inherentemente un nivel de modularidad. La solución de problemas de una característica se convierte en una cuestión de probar esa casa prefabricada en particular de forma aislada. Al igual que los ScriptableObjects, los prefabricados son activos a nivel de proyecto que se pueden reutilizar y compartir en múltiples escenas.
- Utilice ScriptableObjects para almacenamiento de datos (y más): Evite el uso de MonoBehaviours para almacenar datos estáticos del juego. En su lugar, aproveche ScriptableObjects para una mejor reutilización. También puedes relegar cierta lógica del juego a ScriptableObjects o hacer que faciliten la comunicación entre los objetos de tu escena.
- Preocupaciones separadas: Mantenga una distinción clara entre datos, lógica e interfaz de usuario en su proyecto. Esto mejora la capacidad de mantenimiento del código y simplifica la depuración. Nuestro sistema de pantalla de menú utiliza el nuevo UI Toolkit. Este sistema de interfaz de usuario impone un flujo de trabajo que separa la interfaz de su lógica subyacente. Para obtener más detalles, consulte el libro electrónico Diseño e implementación de la interfaz de usuario en Unity .
- Minimizar dependencias: Reducir las dependencias entre componentes hace que sea más fácil modificar o reemplazar partes de su proyecto sin causar problemas imprevistos.
- Utilice eventos para la comunicación: Los eventos permiten un acoplamiento flexible entre componentes, lo que les permite enviarse mensajes entre sí sin dependencias directas. Puede desacoplarlos aún más con "canales de eventos" basados en ScriptableObject.
- Evite singletons innecesarios: Los patrones de diseño singleton pueden resultar útiles, pero sólo cuando una única instancia de una clase es esencial. El uso excesivo de singletons puede dar como resultado un código estrechamente acoplado y dificultar las pruebas. Omita el singleton si no es necesario.
Refactorizar un script monolítico grande en partes más pequeñas promueve la reutilización y la escalabilidad. Esto conduce a una mejor colaboración en equipo y pruebas simplificadas.
![patrones de diseño](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F12957c932379ffcad31516fd14bcc32200e43440-1999x1125.png&w=3840&q=75)
Hemos creado el proyecto PaddleBallSO para demostrar los casos de uso de ScriptableObject. Aquí hay algunos lugares específicos donde los verás en acción:
- GameDataSO ScriptableObject sirve como contenedor de datos central para la configuración del juego. Edite sus datos comunes una vez y luego compártalos con los demás objetos que los necesiten.
- Los minijuegos dependen de numerosos canales de eventos para comunicarse de forma desacoplada. Estos eventos basados en ScriptableObject forman la columna vertebral de cómo los objetos se envían mensajes entre sí.
- La reproducción de sonido utiliza un objeto delegado basado en ScriptableObject para separar la lógica del componente MonoBehaviour.
- Usamos una enumeración basada en PlayerIDSO ScriptableObject para diferenciar los "equipos" entre Player1 y Player2.
- LevelLayoutSO ScriptableObject sirve como contenedor de datos para las posiciones iniciales de elementos del juego como paletas, porterías, paredes y pelota. Esto permite modificar fácilmente los diseños de niveles dentro de Unity y externamente mediante archivos JSON exportados. La modificación de diseños de niveles fuera de Unity puede fomentar la creatividad del jugador y el intercambio de diseños personalizados.
¡Asegúrate de revisar también las demostraciones de patrones de diseño para ver algunos extras!
![parcelbox](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fed2297f0b3bd9714692a11d6b14786b9850ae6d8-989x755.png&w=3840&q=75)
Si bien ScriptableObjects puede ser una herramienta poderosa para almacenar datos de juegos y optimizar su flujo de trabajo, es esencial usarlos de manera efectiva para evitar saturar su proyecto.
Estas son algunas de las mejores prácticas para usar ScriptableObjects en Unity:
- Mantenga los datos modulares y organizados: Utilice ScriptableObjects separados para diferentes tipos de datos (por ejemplo, uno para las estadísticas del jugador, otro para el comportamiento del enemigo, etc.). Divida los datos complejos en partes más pequeñas que puedan gestionarse fácilmente.
- Utilice carpetas y convenciones de nomenclatura: ScriptableObjects puede ayudar a reducir el código en sus scripts, pero la contrapartida es tener más recursos en las carpetas de su proyecto. La organización adecuada de nombres y directorios puede ayudar a administrar estos ScriptableObjects de manera eficiente. Consulte nuestra guía de estilo de código para obtener consejos sobre nombres.
- Evite el uso excesivo de ScriptableObjects: Los ScriptableObjects son contenedores de datos increíbles, pero es importante no abusar de ellos. Tenga en cuenta que los ScriptableObjects pueden agregar complejidad a su proyecto, así que impleméntelos solo cuando ofrezcan un beneficio claro. (Por ejemplo, no los utilice para guardar datos persistentes).
- Haga una copia de seguridad de los datos periódicamente: Los cambios en ScriptableObjects ocurren "en vivo" en tiempo de ejecución y se guardan como archivos de activos. Asegúrese de hacer una copia de seguridad de su proyecto con regularidad para evitar perder datos. Utilice software de control de versiones para realizar un seguimiento de los cambios en sus ScriptableObjects.
- Utilice la ventana de inspección: Una ventaja clave de ScriptableObjects es que son serializables y aparecen en el Inspector. Aproveche la interfaz del Editor para ver y manipular datos almacenados en ScriptableObjects.
- Utilice scripts de editor personalizados a su favor: ScriptableObjects no puede hacer referencia a objetos en tiempo de ejecución desde la jerarquía de escenas de forma nativa. Utilice las secuencias de comandos del Editor para hacer del Inspector una interfaz más fácil de usar si necesita visualizar esos objetos.
Si sigue estas pautas, podrá evitar errores comunes de desarrollo.
![salida programable](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fb056e4b6effe69e49a8184113218ad2935520e52-810x540.jpg&w=3840&q=75)
Lea más sobre patrones de diseño con ScriptableObjects en el libro electrónico Cree una arquitectura de juego modular en Unity con ScriptableObjects. También puedes encontrar más información sobre los patrones de diseño de desarrollo comunes de Unity en el libro electrónico Mejora tu código con patrones de programación de juegos.