ARTÍCULOS

Iniciación al desarrollo de videojuegos: Comenzando a programar

Nuestros primeros pasos en la programación

Como ya vamos empezando a conocer el funcionamiento de la Interfaz de Unity y podemos movernos por sus paneles sin problemas, vamos a comenzar a escribir nuestro propio código que nos permitirá dar vida a los juegos que desarrollemos con este motor. Para explicar el funcionamiento de esto intentaré ser lo más claro posible y como siempre, partir desde cero para aquellas personas que no sepan nada de este mundillo, así que quienes ya sabéis del tema, paciencia que iremos complicando todo con el tiempo.

¿Qué es un programa?

Un programa es básicamente una lista de órdenes escritas que el ordenador ejecutará una a una para que en pantalla podamos ver los resultados que esperamos (y si cometemos errores también los que no esperamos).

En Unity tendremos “programas” o más bien Scripts de código en lenguaje C# que podemos asociar a cualquier objeto de nuestra escena de juego y con los que programaremos su comportamiento. Estos scripts, o archivos que contendrán las instrucciones que definirán como deben actuar los objetos creados, nos permitirán usar las capacidades del propio lenguaje C# junto con las funciones de Unity para manejar elementos de nuestro proyecto que de otra forma tendríamos que programar desde cero (sin ser nada fácil), como por ejemplo las físicas, bucles de juego, colisiones, tiempo y un largo etc.

Partes de un script

De momento no nos vamos a meter en programación orientada a objetos y vamos a considerar nuestros scripts como programas sencillos. Así, estos constarán de datos (que guardaremos en forma de variables y constantes), sentencias (instrucciones para hacer que nuestro juego funcione) y funciones o métodos que nos ayudarán a organizar nuestro código.

Con los datos manejaremos cosas como por ejemplo las vidas que le quedan al protagonista, el número máximo de balas que puede coger o el texto que “hablará” por pantalla antes de enfrentarse al malo final.

Las sentencias se irán ejecutando en momentos concretos para que los objetos de nuestro juego sepan cómo deben comportarse. Por ejemplo: carga el fondo, pon al personaje en la posición x e y correspondiente, etc.

En el caso de las funciones nos servirán para crear llamadas a las mismas y mantener una estructura de código organizada. Como ejemplo podemos pensar en definir una función disparo que contendrá las sentencias necesarias para hacer que nuestro personaje dispare cada vez que la llamemos al pulsar la tecla de disparo. Así mantenemos todo ordenado y si sabemos que algo falla en el disparo, sabremos también que hay que buscar el error en ese fragmento de código en concreto. Evitamos además de esta forma tener que copiar y pegar código mil veces, ya que el ordenador ya no lee el código secuencialmente si no que hace saltos donde necesitamos.

Un alto en el camino: El GUI de Unity

Programar  para sacar un mensaje por la consola de Unity me parecía aburrido, así que he pensado que podemos ver cómo funciona por encima las herramientas para hacer una GUI (Interfaz gráfica de usuario) y así obtener los resultados de nuestros scripts de ejemplo directamente en un texto por pantalla.

Para crear un texto de Interfaz de usuario en Unity debemos ir al menú GameObject/UI/Text, con esto vemos como se nos han creado en el Panel Hierarchy dos elementos: Canvas y Text y si la cosa ha ido bien un texto pequeñito en nuestra escena que dice “New Text”. (Si no os aparece nada no os preocupéis, puede que esté fuera de la vista de la cámara y ya lo configuraremos, lo importante es que aparezca en Hierarchy). También tendremos un EventSystem, que se encargará de gestionar eventos que se produzcan con el texto que hemos creado, como podrían ser interacciones con el ratón, pero esto de momento nos queda grande y lo vamos a dejar para más adelante.

En el Panel Scene, el texto creado es difícil que ver si no nos alejamos bastante, y es que Unity trata los elementos UI como gigantes y los adapta a su tamaño normal en la Vista Game. (Si no lo vemos bien haciendo doble clic sobre Text en Hierarchy, la cámara se acercará a este elemento).

El Canvas es la raíz de todos los elementos de UI que creamos en Unity y será padre de todos ellos (aunque podemos tener varios). Con padre me refiero a que contendrá en este caso el objeto Texto (por eso el Canvas tiene una flechita y el Text aparece debajo y ligeramente desplazado a la derecha) y este dependerá de él por ejemplo en su posición.

El Canvas ayuda a adaptar la UI de nuestro juego a las distintas resoluciones de pantalla que podamos tener, ya sea la de un móvil, un monitor de ordenador, etc. Para ello seleccionamos nuestro Canvas en el Panel Hierarchy y en el Panel Inspector, bajo Canvas Scale cambiaremos el UI Scale Mode de Constant Pixel Size a Scale with Screen Size, dejando de momento todo por defecto (ya lo explicaremos más adelante).

Ahora que hemos configurado nuestro Canvas, podemos seleccionar el elemento Text y ver en el Panel Inspector que podemos hacer con él.

Para empezar tenemos el texto “New Text” que es lo que se muestra en nuestra pantalla y que si cambiamos podremos ver actualizado en el momento (probad a poner algo pero lo cambiaremos en tiempo real mediante código).

Encima, el componente Rect Transform es la versión del Transform que ya comentamos que tenían todos los objetos en Unity y que en este caso está adaptado a los elementos de Interfaz de Usuario, y es que en este, además de la rotación y la escala, tenemos la posición, la anchura y altura del cuadro que contendría nuestro texto (width y height), su punto de pivote (pivot) (desde el cual se harán transformaciones sobre el texto) y sus “anclas” (Anchors), que serán puntos de partida desde los que configuraremos la posición del ya mencionado texto.

En la sección Character tenemos la fuente que usará nuestro texto, su tamaño, su estilo e interlineado. Por otro lado en Paragraph lo que podremos modificar será el color, la alineación, el comportamiento de la fuente cuando sea mayor que su cuadro de texto (si se cortará o lo sobrepasará) y si este texto responderá a lo que se conocen como Raycast y que ya veremos en el futuro que son y para qué sirven (pero quedémonos con que nos permiten por ejemplo que el texto sea interactivo a clics del ratón).

Centrando el texto y cambiando su tamaño y color.

Llega el momento de cambiar el tamaño de la caja que lo envuelve (que no se ve si no estamos en el Panel Scene), para ello modificaremos los valores de Width y Height en, por ejemplo, 400×300 (para el Canvas la pantalla mide 800×600 en este caso, así que es la mitad de grande).

Ahora necesitamos centrar el texto en nuestra pantalla (si no lo está ya) y para ello tenemos que recurrir a sus Anchors Presets, que es ese icono con pinta de mirilla objetivo en el Rect Transform. Hacemos clic sobre este icono y veremos varias configuraciones de posición o pivote. Así, si pulsamos Alt y el elemento que indica center y middle, estaremos cambiando la posición al centro de la pantalla, si por el contrario hacemos lo mismo con la tecla shift pulsada, lo que cambiaremos será el punto de pivote de nuestro objeto a su centro. Aquí como vemos, además de la opción de center y middle hay configuraciones para colocar el texto o su pivote a la derecha, izquierda, arriba o abajo, incluso de posicionarlo expandido “Stretch” a lo largo de la horizontal, la vertical o de toda la pantalla.

Con esto que acabamos de hacer estaremos centrando el cuadro de texto, pero no el texto en sí, para conseguir esto último seleccionaremos el centro en la alineación vertical y horizontal (Alignment) dentro de Paragraph.

Vamos por fin a cambiar el tamaño de la fuente y su color dentro de Character/Font Size (por ejemplo un tamaño de 60 a mi me va bien) y de Paragraph/Color donde podemos poner un rojo para que se vea bien.

 

Nuestro primer Script

Vamos a ir al Panel Proyect y dentro de Assets haremos clic con el botón derecho para elegir Create/Folder, llamando a esta carpeta Scripts. Con esto, mantendremos organizados los assets del proyecto actual guardando cada cosa en su sitio. En este caso crearemos nuestro Script de C# dentro de esta carpeta y para ello haremos doble clic sobre ella y una vez dentro, haremos clic derecho y esta vez seleccionaremos Create/C# Script llamándole: TextController (importante respetar las mayúsculas y minúsculas).

Aconsejo no cambiar el nombre de un Script (haciendo clic con el botón derecho del ratón y seleccionando rename), ya que este tiene en su código un nombre de clase que se creará automáticamente. Este debe ser el mismo que el nombre del Script, por lo que si lo renombramos, aunque cambie el nombre del script, no cambiará el de clase en el código y se nos producirá un error. (Ya veremos lo que es una clase).

Una vez creado nuestro objeto TextController, al que hemos llamado así por que se ocupará del texto que hemos puesto en nuestra pantalla, haremos doble clic sobre él, para que se nos abra nuestro editor de Codigo (que en Unity es Monodevelop, a no ser que hayamos asociado otro que nos guste más como podría ser Visual Studio).

Al crear un Script, observamos que hay un código que siempre creará Unity de forma automática donde se encarga de cargar las librerías necesarias, crear la clase y, aunque no siempre las necesitaremos, coloca la función Start, que se ejecuta cuando ejecutamos la escena actual y la función Update que se ejecuta una vez cada fotograma.

Vamos a hacer un primer programa clásico en el mundo de desarrollo poniendo un “Hola Mundo” en la pantalla y después explicaré el código.

Copiad este código:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TextController : MonoBehaviour {
    public Text mainText;

    // Use this for initialization
    void Start () 
    {
        mainText.text = “¡Hola Gamuza!”;
    }
}

 

Ahora guardad este Script, volved a Unity y cuando os lo permita (puede tardar un poquito en “procesar” el código y ver que no tiene errores) arrastrad el Script con el ratón desde el Panel Project a la cámara en el Panel Hierarchy y soltad. Con esto asociamos nuestro código a la cámara de esta escena, cosa que podemos comprobar haciendo clic sobre Camera en Hierarchy y viendo como en sus propiedades (Panel Inspector) abajo del todo aparece nuestro Script con un dato importante que hemos añadido nosotros: mainText.

Main Text es una casilla que hemos añadido para que sea visible en el Inspector y que espera que arrastremos sobre él un objeto de tipo Texto, así que es el momento de arrastrar el objeto Text que creamos hace un rato hasta esta casilla y una vez lo tengamos, pulsar play para ver lo que pasa en nuestro Panel Game. El texto cambia por la frase “¡Hola Gamuza!”, es decir por lo que había entre comillas en nuestro código cuando escribimos la sentencia: mainText.text = “¡Hola Gamuza!”;

De hecho, si tenéis curiosidad podéis probar a volver al Script y cambiar el texto que hay entre comillas por otro, a ser posible que no sea muy largo para que no se salga del cuadro de texto que creamos (no toquéis ni las comillas, ni el punto y coma ni lo demás que es importante). Guardad, Volved a ejecutar el juego y observad los cambios.

¡Nuestro primer script! (aunque es copiado, pero por algo se empieza).

Explicación:

Para empezar debemos saber que cada sentencia de un script debe acabar con punto y coma, de lo contrario dará error. Los únicos casos que no llevan dicho punto y coma son los grupos de sentencias que se forman por ejemplo en las funciones o clases, que van entre llaves. Así que tenemos de inicio un grupo que nos puso Unity cuando creamos este Script junto con una línea de código que hemos añadido nosotros, siempre usando la palabra “using” y acabando en punto y coma (Hay que respetar Mayúsculas y minúsculas, ya que en C# no es lo mismo “Variable”, que “variable”, que “VARiable” por ejemplo, si no que son 3 palabras diferentes). Esta palabra, que es una palabra reservada del lenguaje, es decir, tiene asignada una función y no podremos usarla para definir datos o funciones propias, se encarga de “cargar” librerías de código para que nuestro programa pueda acceder a la funcionalidad que hay en ellas sin necesidad de ver cómo están programadas. Tenemos las que usan C# y Unity para permitirnos usar las funciones del motor y hemos añadido una última línea using UnityEngine.UI; que nos permitirá usar código para manejar los objetos UI de Unity como nuestro Texto.

La siguiente línea define la clase (en el futuro sabremos que son las clases), que como ya hemos dicho debe tener el mismo nombre que nuestro archivo de script y que además, indica que hereda de MonoBehaviour mediante dos puntos. En futuros capítulos de herencia veremos que significa esto, pero de momento quedémonos que esto es una cosa que hace Unity de inicio con todos los Scripts que creamos también por temas de funcionalidad.

Encerrados entre una llave de apertura ({) y otra de cierre (}) de la clase, tenemos las sentencias de nuestro “programa”, y es que normalmente todo nuestro código lo escribiremos dentro de estas llaves de la clase. (Observad que después de la llave de cierre no se escribe esta vez el punto y coma).

Llegamos al fin al dato. Una variable de tipo Text que nosotros hemos llamado mainText (aunque le podríamos haber puesto el nombre que nos diera la gana) y que va precedida de la palabra “public” para que aparezca en el Panel Inspector y podamos arrastrar hasta ella un objeto de tipo Text como ya hicimos. Conviene saber que las variables que especifiquemos como públicas (public) aparecerán en el Inspector y podremos cambiarlas de forma visual desde allí cuando el juego este detenido (durante la ejecución si las cambiamos volverán a su estado inicial cuando pulsemos stop).

Una variable es un dato representado por un nombre (mainText), que tiene un tipo (que en este caso es del tipo “objeto de Texto de UI”) y que puede variar su contenido (su valor) a lo largo del programa. Es decir, más adelante podríamos cambiar el texto por otra frase.

Existen muchos tipos para las variables que podemos definir, sobre todo si nos metemos en tipos complejos como es este Text, pero hay unos básicos y simples para manejar tipos numéricos con o sin decimales, de tipo verdadero/falso (booleanos), cadenas de texto…

Como ejemplo vamos a añadir otra variable escribiendo justo debajo de la que línea a la que nos estamos refiriendo de “public Text mainText;” pero esta vez usaremos un tipo numérico sencillo y le daremos un valor inicial mediante el operador “=”. Escribiremos siguiendo la siguiente formula “visibilidad tipo nombreDeVariable” por ejemplo una variable pública (se verá en el inspector), de tipo entero (números sin decimales) con el nombre var1 (para el nombre de variable debemos saber que no podemos escribir ninguna palabra que Unity ya tenga reservada y que este nombre no podrá empezar por números ni por ciertos caracteres especiales que ya comentaré más en detalle). Además asignaremos el valor de 3, por ejemplo, quedando la sentencia completa como: public int var1 = 3; (no olvidarse del punto y coma).

Si guardamos el script y nos vamos a Unity, hacemos clic en la cámara y observamos en el Panel Inspector veremos que ahora, bajo la entrada Main Text, tenemos otra llamada Var 1 (que así llamamos a nuestra variable) y que trae por defecto escrito un 3, que es el valor inicial que le dimos, pero que podemos cambiar escribiendo cualquier otro número, siempre que no intentemos usar decimales (porque es un número entero)

¡Y viendo lo poco que hemos aprendido hasta ahora nos damos cuenta de lo mucho que nos queda por aprender!, pero vamos a seguir con las explicaciones de las líneas que faltan.

Los comentarios son esas líneas que van después de dos signos “/”. Aquí se escribirán explicaciones para ayudar a que otros programadores que tengan que trabajar con nuestro código entiendan lo que estamos haciendo pero serán ignorados por el ordenador, que no hará nada con ellos. Los comentarios que comienzan con dos “/” se acaban al final de línea, pero existen otros que empiezan con “/*” y que no finalizan hasta que aparezca su versión opuesta, es decir “*/”, todo lo que se encuentre en medio de estos signos se considerará comentario y será ignorado en la ejecución del programa, aunque haya código.

void Start()” es una función predefinida de Unity que se ejecuta cuando el objeto que contiene este script (la cámara en este caso) se pone en juego. La palabra void indica que no va a devolver ningún valor, devuelve void o nulo y los paréntesis indican que es una función y que le podríamos pasar unos valores iniciales (en este caso no lo hacemos y por eso no hay nada entre los paréntesis) para que opere con ellos en el código que escribamos en su interior, que irá de nuevo entre llaves. Estas llaves se encargan de decir donde empieza y acaba la función como nos decían donde empezaba y acababa la clase.

Iremos profundizando en todo, tened paciencia si aun no lo entendéis.

Dentro de Start tenemos una línea de código que se encarga de cambiar el valor de nuestro objeto Text. Es por esto que lo que escribimos aquí entre las comillas, será lo que veremos en pantalla cuando ejecutemos el juego. El programa comenzará la función Start, dentro leerá: mainText.text = “frase”; y lo traducirá como: cambia la propiedad del texto del objeto mainText por lo que hay entre comillas. Lo que hará que nos muestre el texto escrito en la pantalla.

¡Y eso es todo!

Aprender a programar, aunque sea de forma torpe y básica requiere un tiempo y una forma de pensar, así que tened paciencia y guardad este proyecto de Unity para que podamos seguir practicando y sacando los resultados de nuestras pruebas por la pantalla de esta forma visual.

(File/Save Scenes)

 

Seguiremos en la próxima.

  1. Qué negado he sido siempre para estas cosas (era el Flash y tenía que tirar siempre de chuleta). Si bien evidentemente la programación te da acceso a mucha más libertad a la hora de diseñar, estaría bien también saber qué tipo de juegos se pueden hacer en Unity sin necesidad de tener que meter mano al código, las limitaciones que existen, o con ejemplos. Por ejemplo, en su día hacía mis pinitos con el vetusto RPG Maker. Había gente que con los scripts personalizados hacía maravillas (hubo un fulano que hasta convirtió un Metal Gear al motor), pero conociendo las reglas y las limitaciones, se podían hacer virguerías: yo mismo aproveché los tiles transparentes para crear juegos con fondos pre-renderizados, y no era complicado exploitear las capacidades del motor para crear aventuras conversacionales sin picar ni una sola línea de código.

    1. En Unity lo de hacer juegos sin escribir ni una sola linea de código es rebuscar mucho. Tienes que tirar de scripts que han escrito otros y si no escribes al menos un poco, estás muy limitado. Es fácil por ejemplo poner un muñeco y hacerlo andar por el escenario en primera o en tercera persona, pero las reglas de juego para que no sea un simulador de andar… Ya tienes que picar código para hacerlas.

      1. Ya veo. La gente siempre habla de estos motores como si te lo disen todo hecho, como si fuese un Minecraft de hacer videojuegos juntando piezas. Ya me imaginaba yo que no es tan sencillo (que tampoco complicado, como muestran tus tutoriales)

      2. De hecho, bien mirado, para visualización arquitectónica, un entorno por el que te mueves en tiempo real y ya está sería muy interesante. Sé que tanto Unity como Unreal cuentan con iluminación y materiales físicamente basados, pero ¿cual es el que mejor acabado da en sus últimas versiones?

        1. Hacer eso es relativamente sencillo tanto en Unreal como en Unity, pero hay que trabajar en las escenas y saber iluminar y aplicar materiales. En ese caso Unreal es algo superior a Unity en temas de visualización y rendimiento. Ambos manejan efectivamente materiales basados en físicas, pero de formas distintas.

          Por otro lado para temas de visualización arquitectónica puede quedar muy chulo animar puertas u objetos que formen parte de la escena y ahí, para hacer este tipo de cosas, tal vez gane Unity en sencillez, pero vamos que se llevan poco.

Responder a Lázaro Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *