¿Cuáles son las piezas de un personaje en Unreal Engine?
Tal y como se menciona en la sección de modo de juego y estado de juego, el marco de juego de Unreal Engine ayuda a comprender cómo funcionan los personajes en Unreal Engine. Desde el punto de vista conceptual, un jugador se compone de un peón, que representa su presencia física en el mundo del juego, y de un controlador, que define su comportamiento. Esta división es útil tanto para la IA como para la replicación de red. Como referencia, la jerarquía es así:
Comencemos importando los recursos y creando el peón, antes de pasar al controlador de jugador. En el caso de Parrot, nuestro héroe controlado por el jugador será el capitán Barbarossa (visita el sitio web de Quaternius para conseguir el Pirate Kit proporcionado por Quaternius).
Cómo importar recursos artísticos
En una herramienta de modelado 3D de tu elección, exporta las mallas/animaciones a un formato compatible con el motor. En este caso, los desarrolladores han utilizado el formato .fbx. Los recursos de Barbarossa están en Contenido/Parrot/Assets/Quaternius/PirateKit/Characters/Barbarossa. Puedes importar el .fbx haciendo clic derecho en el menú contextual o arrastrándolo y soltándolo en el explorador de contenido. Aparecerá una ventana de importación de .fbx. Elige las opciones adecuadas para la importación. En este caso, asegúrate de que no haya ningún esqueleto existente seleccionado y que la opción Import Animations esté marcada. También es necesario crear un nuevo material de atlas que pueda indexarse en la malla. Este material se podrá reutilizar en todos los recursos del Pirate Kit. Ahora deberías tener estos 3 archivos y animaciones incluidas en el .fbx.
Para mayor claridad, los archivos de secuencia de animación se encuentran debajo de la carpeta Animations adyacente a los 3 archivos:
Esqueleto, malla esquelética y recursos de física
Un esqueleto es una jerarquía que se utiliza para definir huesos (a veces llamados articulaciones) en una malla esquelética. Estos huesos deben corresponderse con el rig de tu herramienta de modelado 3D. Los esqueletos se pueden reutilizar en diferentes mallas esqueléticas siempre y cuando los rigs sean compatibles. También verás que se han creado unos recursos de física. Los recursos de física definen la física y la colisión que utiliza una malla esquelética. Contienen cuerpos y restricciones rígidos para la simulación. Solo se puede tener un recurso de física por malla esquelética, que se puede activar y desactivar de forma condicional. Puedes ajustar recursos de física al importarlos o crear nuevos recursos a partir de una malla esquelética.
Blueprint de animación
Ahora que tenemos una malla esquelética con la que trabajar, puedes empezar a animar con el blueprint de animación. El blueprint de animación se parece al sistema de animación Mecanim de Unity. El grafo de animación en los blueprints de animación debería resultarte familiar y funciona de una forma parecida. Ambos sistemas cuentan con una lógica condicional que permite transicionar entre estados de animación hasta llegar a una pose de salida final. En tu carpeta, crea un nuevo blueprint de animación desde el menú contextual y selecciona tu esqueleto. Nuestro blueprint de animación se va a llamar ABP_Captain_Barbarossa en Contenido/Blueprints/Player.
En el lado izquierdo del inspector de blueprints, verás que hay dos gráficos: EventGraph y AnimGraph. AnimGraph es el autómata finito que controla la pose final de salida. EventGraph es donde puedes definir la lógica relacionada con la animación. A diferencia de Unity, donde hay que pasar datos al componente Mecanim, los blueprints de animación pueden obtener lo que necesitan en un evento dado. Por ejemplo, puedes querer consultar la velocidad de un personaje y conducir la animación en función de ese valor. Una forma limpia de conseguirlo es utilizar el nodo Event Blueprint Initialize Animation en EventGraph, obtener el actor propietario y almacenar en caché su componente de movimiento en una variable. A partir de ese momento, en cada tic de BlueprintThreadSafeUpdateAnimation, podrás consultar la velocidad desde el propio componente de movimiento. Además, las variables también se pueden compartir entre EventGraph y AnimationGraph.
Merece la pena explorar por tu cuenta el blueprint de animación configurado de Barbarossa. Al hacer doble clic en los nodos podrás ver cómo los autómatas finitos, los estados y las reglas de estado se configuran para la pose de salida final. También hay ejemplos de cómo utilizar un reproductor de secuencia y utilizar un espacio de mezcla. De forma similar, el EventGraph muestra cómo la animación se controla a partir de los datos del personaje; esta relación se irá aclarando a medida que avance este artículo.
Peones
Ahora que hay una malla esquelética que puede animar, puedes empezar a crear el peón que se utilizará en el modo de juego. Los desarrolladores han elegido trabajar a partir del personaje por defecto de Unreal Engine que es una clase hijo de la clase de peón de C++ por defecto. La clase personaje tiene un componente movimiento de personaje que es muy útil para este juego y es otra clase sobre la que trabajar.
Tanto el peón del jugador como los de los de los enemigos comparten algunas funciones como los puntos de impacto, recibir golpes y la muerte. Esta función se comparte al crear una clase de C++ AParrotCharacterBase que hereda de ACharacter. Esta clase es una buena base sobre la que construir a medida que los peones de jugador y de enemigos van difiriendo en comportamiento.
A continuación, crea AParrotPlayerCharacter de C++ para gestionar lógica específica del jugador. Por último, crearás un blueprint para gestionar la representación visual del personaje. El blueprint de Parrot está en BP_ParrotPlayerCharacter en Contenido/Blueprints/Player. La jerarquía de herencia tiene este aspecto:
Al abrir BP_ParrotPlayerCharacter deberías ver algunos componentes en el inspector de compontes a la izquierda de la ventana del editor. El componente Mesh es donde puedes establecer el recurso de malla esquelética además del blueprint de animación en Anim Class. Si la malla no está posicionada correctamente, puedes ajustar los valores de transformación para que se alineen con tu componente de cápsula. Deberías ver algo así:
A continuación, puedes asignar la clase de peón por defecto al blueprint en el recurso de modo de juego.
¡Ya hay un peón de animación que se puede utilizar en el juego!
Controlador de jugador
Con un peón utilizable, ya puedes crear el controlador de jugador. Los controladores de jugador esencialmente representan la voluntad del jugador humano. Algo a tener en cuenta al crear un juego es dónde definir los eventos de entrada. Para los juegos sencillos en los que los peones no cambian, el peón puede encargarse de esto. Sin embargo, cuando el comportamiento se empieza a complicar, el controlador de jugador es una mejor opción. Los peones son transitorios y los controladores de jugador pueden poseerlos y dejar de poseerlos. Los peones se pueden generar o destruir, mientras que los controladores de jugador persisten durante todo el juego.
No vas a necesitar ninguna lógica de C++ en el controlador de jugador, así que simplemente crea un blueprint para hacer lo necesario. BP_ParrotPlayerController se encuentra Contenido/Blueprints/Player. La jerarquía de herencia tiene este aspecto:
En el blueprint, fíjate en que hay nodos de evento de entrada que conducen a cierta lógica de jugabilidad básica. Estos eventos de entrada están relacionados específicamente con la entrada mejorada. Puedes encontrar más información acerca de cómo configurar esto en la documentación de entrada mejorada. Al almacenar en caché el peón de personaje jugable de Parrot al iniciar el juego, podemos utilizarlo más adelante para las funciones de movimiento, como Añadir entrada de movimiento, Saltar y StopJump.
¡Es hora de hacer una prueba! En el blueprint de modo de juego, establece la nueva clase de controlador de jugador y verifica que puedes utilizar el controlador en el juego:
Desde este menú desplegable en el editor de niveles, verifica que el está seleccionado el modo de juego correcto:
Por último, asegúrate de que el mapa tiene un actor y una cámara PlayerStart que puedas ver. Cuando pulses el botón de reproducción, deberías ver al personaje moviéndose y animado:
Componente de movimiento del personaje de Parrot
La clase base ACharacter tiene muchas funciones integradas fantásticas. Un ejemplo es el componente del actor UCharacterMovement. El componente de movimiento del personaje gestiona toda la lógica de cómo un personaje se mueve en el mundo. Es lo que permite andar, correr, caerse, nadar, volar y los modos de movimiento personalizados. Sin duda merece la pena explorarlo por tu cuenta para hacerte una idea de cómo funciona el movimiento de personaje básico y también para comprender un poco lo poderosos que son los componentes del actor.
En el caso de Parrot, el componente de movimiento de personaje base por defecto no conseguía trasladar la sensación que buscaban los desarrolladores. Sin embargo, les proporcionó una buena base desde la que avanzar. La clase de C++ UParrotCharacterMovementComponent deriva de UCharacterMovementComponent. Entonces, podemos establecer el componente de movimiento en el CDO en BP_ParrotPlayerCharacter así:
¿Pero qué hace en realidad el componente de movimiento de Parrot? Básicamente, el componente te permite definir un salto tipo ‘juego de plataformas’ anulando funciones del componente de movimiento base relacionadas con el salto. Con valores que se pueden ajustar mediante el diseño, cuando se produce un salto, puedes modificar la escala de gravedad del personaje jugable y la velocidad de salto para alcanzar una altura máxima en una cantidad fija de tiempo. Después de alcanzar la altura máxima, puedes empezar a aplicar una escala de gravedad de caída. Si el jugador suelta la entrada de salto antes de tiempo, puedes aplicar un multiplicador para aumentar la gravedad.
El resultado es un salto que ‘da una sensación’ más acorde a lo que se espera de un juego de plataformas, a diferencia de lo que sucede si solo se aplica un impulso en el eje Z.
Aprovechando que el componente de movimiento de personaje base se encarga de la mayor parte del trabajo, puedes centrar la lógica del componente de movimiento de Parrot únicamente en el salto. También merece la pena revisar los valores del componente de movimiento en BP_ParrotPlayerCharacter para tener una visión completa de cómo encajan todas las partes del sistema de movimiento. La lógica de movimiento se puede expandir para encajar con cualquier tipo de caso de uso.