[/fusion_text][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]
PRIMERAS LÍNEAS DE CÓDIGO
OnUpdate()
Las primeras líneas de código son las más sencillas para meternos en DOTS. Ya que sólo tendríamos que crear una clase para representar un sistema y con implementar un método ya estaría todo listo para que Unity la inicialice automáticamente. Todos los sistemas que forman parte de ECS son inicializados automáticamente por Unity y actualizados frame a frame mientras estos estén activos. Así que para empezar, vamos a crear nuestra primer clase en ECS. Vamos a empezar creando la clase EntitySpawnerSystem
. El nombre es ilustrativo y no tiene necesariamente que llamarse de esa manera, pero para seguir un conjunto coherente de reglas le pongo ese nombre.
Básicamente esto es crear una clase que herede de SystemBase
y sobreescribir el método OnUpdate()
. Este método tiene la misma funcionalidad que el Update()
en los MonoBehaviours
. Habrán notado que la primer parte dice partial
. Si nunca antes habían visto esta palabra les recomiendo la lectura que dejo en el link pero a grandes rasgos esta palabra reservada significa que esa clase puede ser escrita parcialmente en este archivo y parcialmente en otra. Más allá de los casos de uso, esto tenemos que hacerlo porque al generar la clase que hereda de SystemBase
Unity genera automáticamente una parte de esa clase en otro lado para hacer cosas internas (que ahora no vienen al caso).
Prueben darle play y van a notar que automáticamente ya empieza a funcionar, y frame a frame registra los logs con el mensaje que pusimos. Esto es porque Unity al compilar ya hace todas las tareas necesarias para que esto sea posible.
Vamos ahora a agregar dos métodos más que nos pueden servir. Estos son similares a Awake()
y Start()
respectivamente, y son los métodos OnCreate()
y OnStartRunning()
.
OnCreate() y OnStartRunning()
En estos dos métodos vamos a hacer lo mismo que hacemos comúnmente en Awake()
y Start()
por lo que no necesitan ninguna explicación adicional.
Assets Holder
Obviamente vamos a querer usar todo el sistema de prefabs que nos provee Unity desde siempre. El “temita” con esto es que no es del todo compatible con DOTS. Unity nos provee algunas herramientas para que podamos convertir de alguna manera este sistema de prefabs para utilizarlo en DOTS.
El proceso real por el cual tendríamos que pasar sin esto es crear una entidad, e ir agregándole los distintos componentes que sean los equivalentes al prefab, como un mesh, un componente para la posición, otro para la rotación, etc. Para hacer este proceso más “sencillo” lo que vamos a hacer es almacenar en un ScriptableObject el o los prefabs que necesitamos convertir. En mi caso voy a cargar dicho ScriptableObject con Resources. Se que este método no es el mejor ni el más óptimo, pero para este caso sirve porque es simplemente para entender el funcionamiento de DOTS. En cada uno de los proyectos que ustedes hagan realicen la manera que les parezca más pertinente.
Nuestro assets holder va a ser creado de la siguiente manera:
Luego de esto, procedemos a crearnos un archivo des este asset con click derecho => Create => CharacterAssetsHolder.
NOTA
La parte que dice nameof(CharacterAssetsHolder)
es para que Unity tome el nombre de la clase como un string. Hago esto siempre para que si en algún momento se cambia el nombre de la clase también se reemplacen automáticamente los strings relacionados.
Luego de creado el archivo lo tiramos en la carpeta Resources y arrastramos un prefab cualquiera. Puede ser un personaje que ya tengamos o simplemente un cubo o cualquier primitiva que quieran.
Y con esto ya estamos listos para convertir nuestro prefab a una entidad. Lo vamos a convertir a algo así como un “prefab entity”. Va a tener la misma funcionalidad (en términos de código), pero ahora va a estar dentro del sistema de entidades.
Convirtiendo nuestro prefab a entidad
El proceso es relativamente sencillo. Quizás haya una línea de código que no sepan bien por qué existe, pero vamos a ir de a poco.
Vamos a explicar qué son estas líneas, pero en líneas generales es bastante auto-explicativo.
La primera línea básicamente carga desde la carpeta Resources nuestro ScriptableObject. Nada más ni nada menos.
La segunda es un poco más complicada pero a grandes rasgos obtiene la configuración de conversión. Van a ver algo que se llama World
que básicamente contiene todos nuestros sistemas, se encarga de correrlos y demás. También controla el valor del tiempo que corre sobre estos sistemas y se encarga de gestionar todo lo que herede de ComponentSystemBase
.
La tercera y última se encarga de convertir nuestro prefab a una entidad. Básicamente va a seguir siendo un prefab, sólo que ahora va a permanecer al mundo de ECS.
Antes de darle play al proyecto vamos a abrir el Entity Debugger de Unity, para poder ver los resultados de lo que acabamos de hacer.
Al darle play van a notar que el prefab se convierte correctamente (aunque aún no pasa nada en la escena, obviamente). Y dentro del Entity Debugger verán nuestro prefab convertido.
Así como tenemos la ventana Hierarchy para ver lo que está en la escena, también tenemos el equivalente en DOTS y nos va a servir para ver todas las entidades creadas.
Podemos ver con todo esto que usamos el proceso de creación de una entidad y un poco del uso de los sistemas de DOTS. Vamos ahora a instanciar a nuestro personaje (o caja), directamente usando DOTS.
EntityManager.Instantiate()
El sistema de entidades tiene también una forma de instanciar sus propios prefabs y objetos, y es con el método Instantite()
.
Prueben este código dándole play al proyecto. Noten que cada vez que presionan la tecla SPACE va a aparecer un cubo en la escena (o sea, nuestro “personaje”). Noten la diferencia que tiene este con el prefab que habíamos convertido, dentro del DOTS Hierarchy.
Noten también que si van a la pestaña tradicional de Hierarchy, la que siempre usamos antes de DOTS, nuestro cubo no aparece. De hecho tampoco pueden seleccionarlo desde el editor porque realmente “no está ahí”, sino que simplemente está siendo representado por otro sistema.
Y con esto tenemos “el puente” para pasar a desarrollar en DOTS. Ahora podemos ir un poco más lejos empezando a controlar/desarrollar otros sistemas.
Resolución de posibles problemas