Primer tutorial de Unreal Engine! En esta ocasión voy a mostrar algo básico como para arrancar. Voy a tratar de ir por los conceptos más generales, pero empezando desde un proyecto vacío. La idea es que vean un poco la parte de Blueprints (uno de los puntos más destacados), y también un poco de C++ para ver las diferencias y poder elegir con cuál hacer cada cosa. Quizás sea un tema un tanto difícil si no manejan bien la programación orientada a objetos y algunas estructuras de datos, pero vamos a intentar hacerlo lo más fácil posible!

ACLARACIÓN IMPORTANTE

Tengan en cuenta que hace un par de meses que estoy en aprendizaje con Unreal, así que muchas de las cosas son basadas en lo que aprendí, al margen de si en la industria se trabaja o no de esa manera. Hecha dicha aclaración, vamos al tutorial!

01 – BREVE INTRODUCCIÓN AL EDITOR

Para empezar vamos a ver algunas cosas básicas del editor como las ventanas principales (vamos viéndolas a medida que las necesitemos), algunas opciones a tener en cuenta, configuraciones, y temas relevantes como para empezar de lleno a hacer cosas. Voy a hacer varias comparaciones con Unity3D, como para que los que ya trabajan en ese motor tengan una mayor facilidad.

 

Bien. Para arrancar Unreal Engine podemos hacerlo a través de un proyecto ya creado o desde el Launcher. Ya que todavía no creamos ningún proyecto, vamos por la segunda opción:

 

 

Una vez hagamos hecho click en el botón “Launch” vamos a esperar un buen rato hasta que abra el editor de Unreal (suele tomarse un poco de tiempo, más la primera vez).

Una vez abierto, vamos a ver una ventana como esta:

 

 

A continuación seguimos los pasos en el orden en que marca la imagen. Paso a explicar cada paso:

  1. Pestaña para crear un proyecto nuevo.
  2. Decidir para qué plataforma está orientado.
  3. Seleccionar la calidad con la que se verá el proyecto en el editor.
  4. Con esto se define si cargamos un contenido inicial (pedazos de edificio, partículas, etc).
  5. Ruta donde se va a guardar el proyecto (se va a crear una carpeta).
  6. Nombre del proyecto.
  7. Donde empieza la diversión!

Luego del paso 7 nos toca una espera más larga hasta que el editor de Unreal cree el proyecto. Pero una vez finalizado, abrimos la mitad del proyecto! :P.

 

 

Vamos a enumerar cada una de las principales partes del editor y hacer algunas comparaciones con Unity3D, para las personas que se sientan cómodas.

  1. Acá se mostrarán las opciones del objeto seleccionado. En Unity sería como el “Inspector“. 
  2. Es el explorador del proyecto. Muestra todos los archivos que vayamos creando. En Unity sería la pestaña “Project“.
  3. Representa la escena actual o nivel cargado. En Unity sería como la pestaña “Scene“.
  4. Lista de todos los objetos que están en la escena o nivel actual. En Unity sería la pestaña “Hierarchy“.
  5. Barra de herramientas. Acá encontramos accesos directos para guardar, crear objetos nuevos, configuraciones, etc.

Habiendo conocido un poco de las ventanas principales del editor ya estamos listos para empezar a trabajar un poco con Unreal. Lo primero que vamos a hacer es crear nuestro primer nivel vacío!

 

 

 

Con esto crearemos un nivel nuevo. Si les aparecen opciones pueden elegir entre “Empty” o “Default“. Para el caso no importa. Una vez creado nuestra nueva escena, nivel o mapa, como quieran llamarlo, vamos a crear nuestra primera caja! Para eso vamos a la pestaña que dice “Modes” y dentro de la parte que dice “Basic” buscamos una caja (o la figura que más les guste), y la tiramos a la escena. Una vez hecho esto, quedaría algo así:

 

 

 

Bueno… De nuevo… Vamos por partes:

  1. Este mensaje va a aparecer CADA VEZ que hagamos un cambio en la escena, agregando algún objeto nuevo que puede afectar a las luces/sombras.
  2. Esta pestaña es donde vamos a encontrar todas las primitivas del motor, junto con varias “cosillas” más que ya mostraré en otro post.
  3. Acá se puede ver lo que habíamos dicho más arriba. Esta pestaña, en este caso, está mostrando los detalles de la caja seleccionada.

 

Ahora… Vamos a convertir esta caja en un Blueprint. El Blueprint es básicamente lo que en Unity sería un “prefab“. Para los que no manejan Unity, el prefab (o Blueprint en este caso), sería básicamente un archivo que representa a un “prefabricado”. De este podemos crear varias copias, que ya tendrán configuradas las mismas cosas que el objeto original. La ventaja que tiene frente a copiar y pegar el mismo objeto, es que cuando editamos a este estamos trabajando sobre todas las copias. Esto se utiliza mucho al momento de crear juegos, ya que vamos a crear prefabs de balas, personajes, items, fragmentos de escenario, etc.

Para crear un prefab (Blueprint), seleccionamos el objeto y hacemos click en el botón “Blurprint”. Esto nos va a desplegar un menú. De este hay dos opciones que nos interesan, dependiendo de lo que queramos hacer. Vamos a verlas:

 

 

  • Convert Selected Components to Blueprint Class… Esta opción crea un Bluprint a partir de los objetos seleccionados, pero hace que este HEREDE del tipo de dato Actor. Este tipo de dato representa básicamente a un personaje (o lo que se parezca a un personaje dentro de nuestro juego), y contiene todo lo necesario para que spawnee, reaccione a la física, pierda vida, etc.
  • Convert Selected Actor to Blueprint Class… Crea el Blueprint con los objetos seleccionados PEEEEEROOOO… Hace que herede de la clase base de la cual es el objeto. Por ejemplo, si el tipo de dato es “StaticMeshActor”, este Bluprint heredará de esta clase.

Para este caso vamos a usar la primera opción, ya que nuestra caja representa a un personaje. Un poco más adelante vamos a ver que podemos crear un script y hacer que este objeto herede de dicho script, y que lo podamos manipular como queramos.

En la ventana que aparecerá vamos a ponerle un nombre, por ejemplo “Hero_Blueprint”. También podemos crear, como en la imagen, una subcarpeta parar guardarlo, haciendo click derecho => New Folder.

 

 

Suena media rara la idea de que, jerárquicamente hablando, nuestra caja o personaje están al final en la cadena de herencia, pero yo puedo moverla desde su clase base. Esto es porque nuestro Actor sería como el “contenedor” de nuestra parte gráfica. O sea que, a pesar de que esta caja hereda de nuestro Actor, la misma está DENTRO de él. Así que si movemos dicho contenedor, todo lo que esté dentro también se movería. También podemos acceder a las partes que tiene la parte gráfica. Para esto después vamos a ver que hay diferentes maneras de “buscar” dicho objeto o parte para moverlas o trabajarlas de manera individual.

Por lo pronto investiguemos un poco qué cosas contiene este Blueprint, para que podamos hacerle modificaciones. Para entrar en la configuración de este Blueprint basta con hacerle doble click (accede automáticamente luego de crearlo).

 

 

Vamos a repasar cada una de las partes en profundidad:

  1. Compile: Este es uno de los botones más importantes. Muchas partes de Unreal se compilan de manera individual. Esto se hace para que al testear el juego, no tengamos que esperar hasta que compile cada una de las partes. Así que cada cambio que hagamos dentro de nuestro Blueprint debemos compilarlo para que se vea reflejado al momento de testearlo.
  2. Save: Otro botón importante. Comúnmente, Unreal guarda al momento de compilarlo. Peeeeeeeero… Hay veces que no. Si no hacemos click en este botón, puede pasar el que Blueprint se compile, y al volver a entrar los cambios no se hayan guardado. O algo mucho peor… Que el archivo se borre. Para evitar esto, sería ideal que siempre hagan click en “Compile” y luego en “Save”.
  3. Class Settings: Contiene todos los seteos propios de este tipo de dato (recordemos que el Blueprint es un tipo de dato). Acá podemos hacer cosas como que nuestro Blueprint herede de otro script.
  4. Class Defaults: Cada Blueprint que se instancie en nuestros niveles se cargará con los seteos predeterminados puestos acá.
  5. Components: Dentro de esta pestaña vamos a ver cada una de las partes que están dentro de nuestro Blueprint. Por ejemplo, la cámara (si la tiene), el brazo, arma, etc. Y podremos editarlas.
  6. Viewport: Visualiza el contenido de nuestro Blueprint.
  7. Construction Script: Acá vamos a encontrar una serie de nodos que se ejecutan al momento de “construir” nuestro Blueprint (básicamente es el constructor que tenemos por código). Hay que tener en cuenta que esto se ejecutaría al compilar. Estos nodos, que veremos más adelante, podemos programarlos nosotros o usar los que ya vienen predeterminados (que son muchos).
  8. Event Graph: Es básicamente lo mismo que el anterior, sólo que los nodos puestos acá se ejecutan durante toda la vida de nuestro Blueprint DENTRO DE LA ESCENA. O sea, que si no está en la escena no ejecutaría nada.
  9. Details: Esta pestaña muestra información y nos permite editar cualquier objeto seleccionado.
  10. Visualización del contenido de nuestro Blueprint.
  11. Variables: Al igual que creamos variables dentro de nuestros scripts, también las podemos crear acá, para guardar cosas como la vida del personaje, o alguna de sus partes. Dichas variables las podemos utilizar en cualquiera de las pestañas que nos permiten programar con nodos, como “Construction Script” y “Event Graph”.
  12. Compiler Result: Muestra información acerca de cómo finalizó la compilación de nuestro Blueprint. Si algo salió mal lo veremos acá.

 

02 – NUESTRO PRIMER SCRIPT EN C++

Teniendo lo más básico del tutorial listo, ya podemos empezar a ver un poco de código en C++. Recuerden que es necesario tener conocimientos de programación orientada a objetos, ya que estos no se van a contemplar en este tutorial.

Vamos a empezar viendo cómo crear un script, y algún concepto básico de C++, como su principal diferencia con otros lenguajes como C#. Si tienen conocimientos de programación no debería ser difícil agarrarle la mano (y cariño), a este lenguaje. Una de las primeras impresiones que tiene mucha gente es que hay que escribir mucho código para hacer algo que en otro lenguaje necesitaría mucho menos. Pero cuando entiendan un poco mejor los “por qué” y comprendan las capacidades del mismo, lo van a querer más. ;).

 

03 – RESOLUCIÓN DEL EJERCICIO 01

Si pudieron resolver el ejercicio correctamente, entonces van entendiendo un poco mejor la lógica de Unreal! Lo cual es bueno, así que podemos seguir. Si no pudieron, sigan intentando. No estaría mal que de hecho traten de buscar información por internet, así también se van acostumbrando al proceso. Algunas cosas las aprendí en tutoriales y otras buscando y probando hasta que funcionaba y también a ustedes les va a ser útil.

 

04 – PROGRAMACIÓN CON NODOS (BLUEPRINTS)

Ahora es el turno de los famosos “Blueprints”. Estos son la forma más sencilla de desarrollar algo en Unreal sin tener demasiados conocimientos de programación, ya que son tan sencillos de utilizar como tirar nodos y conectarlos. Básicamente sería ejecutar funciones de Unreal de manera más visual. Otra ventaja que tienen es que todos los Blueprints que escribimos son realmente funciones que ya están declaradas en cada objeto en C++, así que las podemos invocar también escribiendo puramente código.

 

05 – GAME MODES

Hasta donde los pude aprender, los Game Modes son una parte muy importante de cada proyecto hecho en Unreal. Básicamente representan l0s datos de la partida, condiciones de victoria y derrota. Estos nos permiten utilizar el mismo nivel, pero cambiar las reglas de la partida. Por ejemplo, podría tener un mapa del Counter Strike (assault, supongamos), y utilizarlo para una partida Free For All, y en algún momento cambiar las reglas del juego y que sea Capture The Flag. De más está decir que nada es mágico, así que también es necesario que tengan una estructura dentro de todo estable en cada juego que hagan.

 

06 – CONFIGURACIÓN DE TECLAS Y LLAMADO A FUNCIONES DESDE UN BLUEPRINT

Luego de ver ambos conceptos, tanto C++ como Blueprints, la idea ahora es que puedan ver cómo combinar ambos para trabajar juntos. En muchas ocasiones es muy útil mezclarlos, como por ejemplo, una persona podría hacer la parte de C++ como alguna herramienta o alguna parte del juego que sea importante como distintas acciones de algunos players, y la otra podría hacer tareas utilizando funciones desde Blueprints (o viceversa, why not?).

Para mostrar un ejemplo de esto, vamos a aprovechar y ver también la parte de configuración de inputs, para detectar cuando el usuario presiona determinadas teclas. La idea es que el Blueprint lo detecte y llame a una función de C++.

Una cosa importante a tener en cuenta es que Unreal va a mandar las entradas de teclado predeterminadamente al que sea el Default Pawn. Se puede hacer, hasta donde investigué, que Unreal envíe eventos a más de uno, aunque a mi parecer se debería programar, en el caso de que se necesite más de un player, un sólo objeto que contenga la detección entera de todos los inputs y los redirija a cada Controller según sea necesario, pero si encuentran una manera mejor de hacerlo bienvenido sea!

 

07 – RESOLUCIÓN DEL EJERCICIO 02

Bien… Resolvamos ahora el ejercicio. Al margen de cómo lo hayan resuelto, lo importante es que haya salido. Y si no salió, dense tiempo! Unreal no es algo fácil de aprender, pero cuando le agarren la mano todo se va a volver más accesible. Tengan paciencia nomas.

 

08 – PLAYERCONTROLLER CON BLUEPRINTS

 

Llegado a este punto esto es ya un poco extra, pero me parece que no está de más. Recuerdan el concepto de PlayerController que expliqué en ESTE POST. El concepto es útil a la hora de programar múltiples personajes, ya que nos permite que todos puedan tener comportamientos diferentes entre sí, haciendo que cada objeto tenga únicamente las acciones que va a realizar, pero que no las haga hasta que otro script se lo diga. Este script tendrá la tarea de darle órdenes basadas en distintos conceptos, como por ejemplo, las teclas que apreta el usuario, la lógica que tenga una determinada IA, o incluso recibir órdenes desde otro lugar. De esta manera estaríamos programando una especie de “soldados” que tienen todas las capacidades, pero otro les dice qué hacer y en qué momento. Así, cada personaje pasa a ser un peón (de acá la clase Pawn), y es “poseído” por un controller que le dice qué hacer.

Nosotros pasaríamos a programar dos partes entonces, un peón que tiene todas las acciones que puede realizar, y un controller que le dice a un peón cualquiera cómo manejarse. Si la estructura es correcta, en cualquiera sea el juego deberíamos poder poseer a cualquier peón con un controller y este debería poder darle órdenes. Por supuesto, esto no significa que hay que programar un controller capaz de manipular a cualquier peón en cualquier juego, ya que cada juego tiene conceptos diferentes. Pero al momento de tener múltiples personajes, ya sea que estén controlados por varios usuarios y/o simplemente distintos tipos de inteligencias artificiales, el concepto nos facilita el manejo estructural del juego.

En Unreal este concepto está muy ligado al motor, ya que lo vamos a ver en muchas partes. Por supuesto que se podría no utilizarlo, pero si empezamos a programar conceptos saliendo de lo que nos da el motor podría pasar que terminemos programando de más, y a la vez que estemos haciendo estructuras que perjudiquen el rendimiento final del juego CON EL MOTOR que estemos usando (en este caso Unreal).

En motores como Unity3D no existe (aún), esto de PlayerController. Quizás sea porque Unity apunta a otro tipo de targets, a que se puedan desarrollar una gama más amplia de juegos, sin meterse tanto en lo extenso. De todas maneras, aprender conceptos propios de otros motores los va a ayudar a tener distintas perspectivas, y puede pasar que después incluso quieran imitar de alguna manera ciertas características.

En mi caso, el concepto de PlayerController lo vengo implementando desde que empecé con As3 hace casi unos 10 años, y hasta ahora me trajo muchas ventajas.

Vamos a ver ahora cómo hacerlo con Blueprints y con C++.

 

09 – PLAYERCONTROLLER DESDE C++

Visto ahora el concepto desde Blueprints enteramente, vamos a pasarlo ahora a C++. La idea es que lo vean desde ambos lados, pero creo que muchas veces van a terminar usando una combinación. Quizás quieran arrancar el proceso desde un Blueprint y que un script en C++ termine la tarea. Por ejemplo: Detectamos eventos desde Blueprints, y ejecutamos funciones desde C++.

 

10 – EXPONER VARIABLES EN EL EDITOR

 

Llegado a este punto me acabo de dar cuenta de que dejé colgado un tema que había nombrado en el video, y es el exponer variables para que se puedan editar desde la ventana de Blueprints.

De todas maneras tampoco es difícil! Sólo hay que agregar, arriba de la variable que se quiere exponer, los siguiente:

UPROPERTY(EditAnywhere)
float CountdownTime;

También se pueden agregar más cosas a UPROPERTY, como por ejemplo:

UPROPERTY(EditAnywhere, Category = "Countdown")
float CountdownTime;

La parte que dice “Category = Countdown” es para que al aparecer en el editor aparezca en un bloque diferente al resto. Se pueden agrupar varias variables en un mismo grupo. 

Quedaría de esta manera:

 

 

Les dejo un link a la documentación oficial, donde pueden consultar más detalles:

https://docs.unrealengine.com/latest/INT/Programming/Tutorials/VariablesTimersEvents/2/

Espero que les sirva!

Saludos.