Unidad Ahora estás pensando con componentes

Si bien Unity es una increíble plataforma de juegos, acostumbrarse a ella requerirá un poco de trabajo inicial, ya que es probable que tenga que cambiar sus engranajes cognitivos para comprender su basado en componentes arquitectura.

Si bien la Programación Orientada a Objetos (OOP, por sus siglas en inglés) clásica se puede usar y se usa, el flujo de trabajo de Unity se basa en la estructura de los componentes, lo que requiere un pensamiento basado en componentes. Si estás familiarizado con los componentes, eso es genial; Si no, eso no es un problema. Aquí, te daré un curso intensivo sobre componentes en Unity.

Imagen de vista previa: Old Cogs por Emmanuel Huybrech.


Qué es un componente?

Antes de continuar con la forma de trabajar y pensar con componentes, asegurémonos de que entendemos exactamente qué son exactamente.

En el mundo de la programación, los conceptos de componentes y desacoplamiento van de la mano. Un componente puede considerarse como una pieza más pequeña de una máquina más grande. Cada componente tiene su propio trabajo específico, y generalmente puede (y de manera óptima) cumplir su tarea o propósito sin la ayuda de ninguna fuente externa. Además, los componentes rara vez pertenecen a una sola máquina y pueden unirse a varios sistemas para realizar su tarea específica, pero logran resultados diferentes cuando se trata de una visión más amplia. Esto se debe a que a los componentes no solo no les importa esa imagen más grande, sino que también ni siquiera se sabe que existe.

Un ejemplo clásico de componentes son las piezas de un automóvil, pero eso es aburrido, ya que no me gustan demasiado los automóviles. En su lugar, considere un controlador de Xbox 360. Tt tiene dos sticks analógicos, varios botones, disparadores, etc. No solo el controlador en sí mismo es un componente, sino que cada aspecto individual del controlador es un componente..

Foto de Futurilla..

El botón X puede: ser presionado; enviar la información que se ha presionado; ser liberado y enviar información que ha sido publicada. No tiene idea de que hay varios otros botones justo al lado, ni le importa.

El controlador en sí mismo es un componente, compuesto de otros componentes (todos los botones, joysticks y disparadores), porque puede enviar datos a lo que esté conectado, pero no le importa qué sea ese objeto (Xbox, PC, algunos Creación de Arduino, o lo que sea). Ni el botón X, ni el controlador en sí, necesitan saber qué juego estás jugando, ya que seguirá haciendo su trabajo sin importar el receptor de su información. 

La función del controlador es una calle de sentido único, y su tarea nunca cambiará debido a lo que está conectado. Esto lo convierte en un componente exitoso, ya que puede hacer su trabajo como un dispositivo independiente, pero también porque puede hacer su trabajo con múltiple dispositivos.


¿Cómo y por qué la unidad favorece a los componentes??

La unidad fue construida con componentes en mente, y se nota. Uno de los aspectos más valiosos y distintivos de Unity es que es un programa muy visual. He estado trabajando en el desarrollo de juegos durante años y, aparte de mis primeros días en Flash IDE, he trabajado principalmente con hojas de sprites PNG y un editor de código como FlashDevelop, que no es nada visual..

La unidad es exactamente lo contrario. Unity te permite ver todo en lo que estás trabajando y en tiempo real. Esto significa que puede probar su proyecto, ver su proyecto ejecutándose en una ventana separada, realizar ediciones en su código u objetos del juego y ver esas ediciones reflejadas en vivo. La cantidad de poder que este sistema le da a un desarrollador es inmensa, y ahora es, en mi opinión, un aspecto esencial del desarrollo de juegos modernos. Todo esto es posible gracias a la arquitectura basada en componentes de Unity..

El inspector

En caso de que no esté familiarizado con Unity, le explicaré al inspector. Este es un panel en Unity que muestra todas las propiedades de un objeto de juego. Si hace clic en su reproductor en el mundo (ya sea en tiempo de ejecución o antes) podrá ver todo sobre ese objeto.

Si el avatar de tu jugador tiene seis componentes, cada uno aparecerá en una pestaña separada, y cada variable pública estará disponible para que la veas y la modifiques. Si el avatar de tu jugador tiene un inventario, no solo verás que tiene un inventario, sino que también podrás ver los elementos de ese inventario y el índice de la lista o matriz que ocupa cada elemento en particular. Si recoges un nuevo elemento en el juego mientras estás probando, verás que se agrega al inventario en vivo. Incluso puede agregar o eliminar artículos de ese inventario, lo que le permitiría probar rápidamente nuevos artículos, que incluso podría estar creando. mientras se ejecuta el juego.

El inspector de la unidad.

Si bien la edición en vivo es increíblemente poderosa, no depende exactamente del uso de componentes. Podría cambiar un script y ver esas ediciones reflejadas en vivo, pero eso es limitante en comparación con lo que los componentes le permiten hacer.

Considere un tirador de espacio vertical. Cuando pruebe su proyecto en la mayoría de los otros entornos, verá cómo se juega su juego, tomará notas, luego volverá al código y modificará las cosas, solo para volver a compilar el proyecto y probar esos puntos. Si tiene una configuración en vivo, puede modificar ese código sobre la marcha y ver esos cambios mientras juega, lo que es aún mejor. Dicho esto, si no está utilizando componentes, tendrá que cambiar una gran cantidad de código para ver los efectos principales, lo que lleva tiempo, y esto anula el propósito de la edición en vivo..

Si está trabajando con componentes, puede agregar nuevos componentes en dos segundos sin interrupción. Puede cambiar las pistolas de su nave por las pistolas que usa un jefe (asumiendo que programó sus componentes para que funcionen por su cuenta, como deberían hacer los buenos componentes), puede cambiar su sistema de salud de cinco golpes a ese protector de recarga similar a Halo. Programado para otro juego. puedes agregar una serie de hechizos a uno de tus personajes, y todo en segundos.

No necesita cambiar ningún código, no necesita recompilar, simplemente arrastre y suelte, o seleccione el componente que desee de una lista desplegable, y se agrega. Ese tipo de poder tiene un valor incalculable para el equilibrio del juego, y ahorra enormes cantidades de tiempo.


Cambiar a pensamiento basado en componentes

La parte más difícil de trabajar con componentes es aprender a estructurar sus proyectos cuando los usa. Para la mayoría de los programadores, esto probablemente signifique que va a crear muchos más scripts, y cada uno de ellos realizará tareas más pequeñas y específicas..

La forma en que se comunica entre los scripts también es un obstáculo decente, ya que tendrá muchas más piezas y menos clases gigantes en las que todos los objetos conozcan todos los demás objetos. Obviamente, hay formas de evitar esto, como las variables estáticas para los componentes principales de su juego (jugadores, puntuación, etc.), pero eso rara vez funciona para todo (y no se recomienda), y existen métodos avanzados para estructurar adecuadamente sus componentes. , y permanecer desacoplado.

Afortunadamente, dado que la unidad se creó teniendo en cuenta los componentes, tiene una serie de funciones integradas que nos ayudan a lograrlo. Hay funciones para obtener referencias a un componente específico, para verificar todos los objetos para ver si contienen un componente específico, etc. Con estas diversas funciones, puede recuperar fácilmente la información necesaria para crear esa calle mágica de conocimiento en un solo sentido donde los componentes pueden comuníquese con los objetos que afectan, pero el componente en sí mismo no tiene idea de qué es exactamente ese objeto. Combine esto con el uso de interfaces, y tendrá suficiente poder de programación para abordar cualquier asunto, simple o complejo.

Ejemplo: tipos de enemigos

En un sistema de herencia OOP, podría tener una base Enemigo clase que contenía cualquiera y todas las funciones que la mayoría de tus enemigos usarían, y luego podrías extenderla para agregar funcionalidad específica.

Si alguna vez implementó un sistema así, es consciente de que entre su base Enemigo clase, y tal vez tu base GameObject (o equivalente) de clase, terminas con un montón de desorden innecesario de tener variables y funciones que algunas clases necesitan, pero muchas no. Interfaces Puede ayudar con esto, pero no siempre son la solución..

Ahora, echemos un vistazo a la misma configuración, pero pensando en los componentes. Todavía tienes varios enemigos, todos los cuales comparten una gran cantidad de funcionalidades comunes, pero cada uno de ellos tiene características únicas.

El primer paso es romper toda la funcionalidad en piezas. Uno podria pensar que tener salud y moribundo son parte del mismo sistema, pero incluso ese ejemplo puede dividirse en un componente del sistema de salud y un componente del sistema de la muerte. Esto es porque tu salud es tu salud, y nada más. Cuando llega a cero, no le corresponde al sistema de salud decidir qué sucederá a continuación, solo le corresponde al sistema de salud saber que, de hecho, está en cero. Otros sistemas, como un sistema de muerte, pueden leer esta información y luego elegir hacer lo que les plazca..

Tal vez el sistema de la muerte engendre un nuevo enemigo (piensa en un gran enemigo que se rompe en pedazos); tal vez se caiga un power-up; Tal vez le agregue un efecto de explosión a la pantalla. Independientemente de lo que suceda, el sistema de salud no forma parte de eso, y así es como hacemos componentes limpios y útiles..

Cuando pensamos en movimiento, podríamos pensar que todo movimiento debe estar en un solo script. Pero algunos enemigos en algunos juegos no pueden caminar; Solo pueden saltar. Algunos enemigos pueden caminar, pero no pueden saltar. Pensar en estas cosas es cómo detectamos dónde podrían y deberían existir los componentes. Cuando se trata de movilidad, podemos separar el salto de caminar o correr, volar por separado, y así hacerlo nos dará un código más limpio y más versatilidad..

Los componentes hacen que nuestro código sea más limpio (sin variables ni funciones innecesarias), pero también hacen que el proceso de creación de enemigos sea mucho más flexible y agradable. Con cada pieza de la funcionalidad del enemigo configurada como un componente, podemos arrastrar y soltar aspectos de los enemigos y ver cómo se comportan, e incluso en tiempo real, si estamos usando Unity..

Supongamos que todas las siguientes características ya están programadas. Durante nuestro proceso de creación de enemigos, podríamos crear tres enemigos en blanco, que son solo prefabs vacíos en Unity. Luego podemos arrastrar un sistema de salud, un sistema de caída de objetos y un sistema de muerte, ya que sabemos que todos nuestros enemigos, sin importar las diferencias, tendrán salud, morirán y soltarán un elemento. De hecho, podemos seleccionar las tres prefabs a la vez, luego arrastrar y soltar estos componentes en el panel Inspector y actualizar los tres al mismo tiempo.

A continuación, sabemos que un enemigo podrá volar, así que seleccionamos ese enemigo y arrastramos un volador componente en él. Otro puede detectar un objetivo en el juego y dispararle, así que lanzamos un disparar al objetivo componente de script. El tercero puede lanzar una barrera que bloquea todos los ataques por un corto tiempo, por lo que lanzamos al barrera componente.

Ahora tenemos tres enemigos únicos, todos compartiendo ciertos componentes, pero todos también tienen componentes que se aplican solo a ellos. La parte agradable es que hacer a estos enemigos es simple, y experimentar con nuevas variaciones es tan fácil como arrastrar y soltar. ¿Quieres un enemigo volador, con una barrera, que pueda atacar a un enemigo y dispararle? Arrastra todos los componentes anteriores a un solo enemigo, y tienes justo eso!


Conclusión

Pensar con componentes puede no ser fácil, pero ciertamente tiene sus beneficios. Continuará usando los componentes y la herencia en su programación futura, pero es extremadamente valioso expandir su plétora de formas de abordar el mismo problema al ver varias perspectivas..

Cuando se trata de Unity, puede usar el método que prefiera, pero los componentes son definitivamente preferidos, y no tiene sentido luchar contra un flujo de trabajo tan increíble. Aprender Unity y cambiar mi forma de pensar para trabajar con componentes ha sido un obstáculo moderadamente difícil de superar, pero ahora que estoy aquí, no veo que regrese pronto..