Home | Clases | Unity: Introducción y primer proyecto en 3D | El primer proyecto desde 0: Roll-a-ball

El primer proyecto desde 0: Roll-a-ball


Introducción

En esta entrada, aprenderemos los conceptos básicos de Unity basándonos en el tutorial Roll-a-ball, que puedes encontrar en video en inglés en la siguiente dirección:

Roll-a-ball tutorial

Fuente: Unity


Este tutorial no requiere de ningún asset externo, ya que solo utiliza las formas básicas de Unity (cubos, esferas, planos, etc.), pero nos servirá para profundizar en el uso de GameObjects, Components, Prefabs y Physics, así como para introducir los Scripts.

Para ello, dividiremos el proyecto en varios apartados:

  • El proyecto
  • El suelo
  • El jugador
  • Materiales
  • Moviendo el jugador
  • La cámara
  • El área de juego
  • Los coleccionables
  • Recoger los coleccionables
  • Objetos estáticos y dinámicos
  • Contabilizar y mostrar la puntuación
  • Compilar el juego



El proyecto

Para comenzar, en File > New Project... crearemos un nuevo proyecto en Unity de tipo 3D al que llamaremos Roll a ball. Lo guardaremos en la ubicación más conveniente para nosotros, prestando especial atención a no usar ubicaciones que pudieran estar "congeladas" por los administradores de sistemas, esto es, que al reiniciar el ordenador se eliminen.



Una vez creado el proyecto, es recomendable guardar la escena. Para ello, haz clic en File > Save Scene, crea una carpeta llamada Scenes dentro de Assets y llama a la escena Juego.


El suelo

Es el momento de crear los elementos del juego. Empezaremos creando el suelo.

Para crear el suelo, haz clic con el botón derecho en la Hierarchy window, crea un 3D Object > Plane y renómbralo como Suelo haciendo un doble clic lento en el nombre o bien pulsando Enter con el elemento seleccionado.

Es importante en muchos casos resetear la posición del elemento para llevarlo a la posición 0,0,0, ya que por defecto Unity lo creará en la última posición conocida o utilizada. Para ello, con el elemento seleccionado, dentro de la ventana Inspector, haz clic en la rueda desplegable de la zona superior derecha de la sección Transform y selecciona Reset.

Esta sección Transform, como puedes ver, nos va a dar información sobre la posición del objeto, su rotación y su escala.

Si queremos ver el objeto completamente en nuestra Scene View, debemos seleccionarlo y pulsar la tecla F (Frame Selected).

Si aún así no conseguimos ver nuestro suelo completo, ha llegado el momento de hablar de los controles de teclado y ratón para navegar en la Scene View de Unity. No te preocupes, no es necesario que te los aprendas de memoria, las primeras veces los tendrás que consultar, pero con la práctica serán como "montar en bici".

Todos los controles están disponibles en Navegación del Scene View y te recomiendo consultarlos y probarlos antes de continuar.

A continuación te resumo los más importantes:

  • Scene Gizmo: Muestra la orientación de la cámara del Scene View y permite modificar rápidamente el ángulo de visión.
  • Arrow Keys: las teclas de flecha permiten movernos por la escena como si estuviéramos andando por ella.
  • Hand Tool: permite hacer clic y arrastrar la cámara o cualquier objeto. El acceso rápido es la tecla Q.
  • Orbit: con la Hand Tool seleccionada, hacemos Alt+clic y arrastre para orbitar/pivotar la cámara alrededor del punto seleccionado (no disponible en 2D)
  • Zoom: con la Hand Tool seleccionada, hacemos Alt+rueda de desplazamiento para cercarnos o alejarnos de la Scene View.

Existe además una forma más rápida e independiente de la herramienta seleccionada:

Para moverse, Alt+clic del medio y arrastre.
Para orbitar, Alt + clic y arrastre.
Para zoom, Alt + clic derecho y arrastre o rueda de desplazamiento.

Por último el Modo Flythrough nos permite navegar el Scene View "volando" en primera persona similar a cómo se navega en muchos juegos. Para activarlo, haz clic derecho y utiliza el mouse o las teclas WASD para moverte por la escena En este último caso, si mantienes pulsado MAYUS te moverás más rápido.

Como ya sabemos movernos por nuestro Scene View, vamos a cambiar algunas propiedades de nuestro suelo.

Empezaremos cambiando la escala, bien desde la Inspector Window, sección Transform si queremos introducir unos valores predeterminados, o bien seleccionando la Scale Tool y redimensionando el objeto. En cualquier caso, el resultado final debe ser 2,1,2, similar al mostrado en la figura.



El jugador

Para crear nuestro jugador, haciendo clic en la Hierarchy window, crearemos un 3D Object > Sphere y la renombraremos como Jugador. También, al igual que antes (si ya no te acuerdas, toca volver atrás) resetearemos su posición y haremos clic en F para centrar la cámara en el objeto.

Vemos que solo hay media esfera, ya que la otra queda por debajo al estar ambas en la misma posición. Para resolverlo, cambia la posición de la esfera en la Inspector window para que coincida con los valores 0,0.5,0, ya que la esfera por defecto tiene una altura de 1 unidad de Unity.



Materiales

Fijándonos en la figura anterior, vemos que apenas hay contraste entre los elementos del juego y el fondo por defecto. Para conseguirlo debemos añadir un color de fondo a cada uno de ellos. Esto se hace mediante la utilización de materiales, que pueden ir desde colores básicos a avanzadas texturas.

Para este tutorial nos centraremos en materiales básicos que generen un color de fondo. Desde la Project Window, crea una nueva carpeta llamada Materiales.

Dentro de ella, haz clic en Create > Material y renómbralo como Fondo. Con el Fondo seleccionado, haz clic en el Color Picker del Inspector Window (al lado del texto Albedo) y selecciona un azul oscuro. Para asignárselo al Suelo, simplemente arrastra el material Fondo al Suelo.

Por último, para cambiar la dirección de la luz sobre el Suelo, haz clic en la Directional Light de la Hierarchy Window y, en la sección Transform de la Inspector Window cambia el valor de Rotation Y a 60, de modo que obtengamos un fondo con mejor sombra.




Moviendo el jugador

El primer objetivo del juego será poder mover el jugador por el plano, evitando además que se salga de él mediante unas barreras con lsa que tendrá que chocar (collide).

Para ello, debemos hacer uso del sistema de física (physics) de Unity. En concreto, haremos uso del componente RigidBody que ya usamos en tutoriales anteriores. Selecciona el objeto Jugador y, desde la Inspector Window, haz clic en Add component, empieza a escribir RigidBody y en seguida podrás seleccionarlo.

Para que las flechas del teclado (o cualquier otro dispositivo de entrada) muevan al jugador, debemos crear un script. Ya comentamos que un script de programación es un conjunto de órdenes que nos permiten controlar la interactividad de nuestro juego.

Si bien en Unity se puede programar con diferentes lenguajes de programación, el más utilizado es C#, una evolución del lenguaje C original.

Crea una nueva carpeta en tu ventana de Project (dentro de Assets) llamada Scripts.

NOTA: Es recomendable y mejora la visualización tener la Project Window en vista de 2 columnas. Para ello, haz clic derecho en Project > Two Column Layout.

Dentro de la carpeta Scripts, clic derecho, Create > C# script con el nombre JugadorController. Haz doble clic en él y Visual Code Editor debería abrirse con el archivo JugadorController:



En la figura anterior podemos ver la estructura básica de un script C#. Sin entrar en mucho detalle, vemos que se compone de una clase pública public class (un objeto que se puede utilizar desde cualquier punto de la aplicación) que dentro tiene 2 funciones o métodos llamados Start y Update que no devuelven nada (void).

Las funciones o métodos son pequeños conjuntos de instrucciones que, de nuevo, podremos llamar desde otros puntos de la aplicación.

Por defecto, la función Start se ejecutará al arrancar la aplicación, de modo que todo lo que hagamos en ella se ejecutará sin más (inicializar contadores, escenas, etc.)

La función Update se ejecuta cada frame del juego , y es en la que añadiremos toda la lógica de actualización del juego (movimientos, detección de colisiones, etc.). No obstante, cuando actualice fuerzas físicas tales como movimientos o giros, es mejor utilizar FIxedUpdate, ya que se ejecutará 0, una o varias veces por frame en función de los frames de física del motor de Unity e irá más sincronizado.

Añade el siguiente código a tu script, si bien te recomiendo escribirlo tu mismo en vez de copiar y pegar, ya que cogerás destreza en evitar errores de sintaxis, algo muy común en programación:


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

public class JugadorController : MonoBehaviour {

//Declarlo la variable de tipo RigidBody que luego asociaremos a nuestro Jugador
private Rigidbody rb;

// Use this for initialization
void Start () {

//Capturo esa variable al iniciar el juego
rb = GetComponent<Rigidbody>();

}

// Para que se sincronice con los frames de física del motor
void FixedUpdate () {

//Estas variables nos capturan el movimiento en horizontal y vertical de nuestro teclado
float movimientoH = Input.GetAxis("Horizontal");
float movimientoV = Input.GetAxis("Vertical");

//Un vector 3 es un trío de posiciones en el espacio XYZ, en este caso el que corresponde al movimiento
Vector3 movimiento = new Vector3(movimientoH, 0.0f, movimientoV);

//Asigno ese movimiento o desplazamiento a mi RigidBody
rb.AddForce(movimiento);

}
}


Una vez hecho, guarda el script, vuelve a Unity y comprueba en la barra de estado inferior que no hay errores.

Para finalizar, debemos asignar el script a nuestro Jugador, algo tan simple como seleccionar el Jugador y arrastrar nuestro script desde la Project Window a la Inpsector window que contienen las propiedades del Jugador.

Si todo se ha hecho correctamente, al ejecutar el juego verás que el Jugador se muevo al presionar las flechas o WASD, aunque muy despacio.

Modifica el script para que incluya una variable que nos permita multiplicar el movimiento por una determinada cantidad o velocidad:


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

public class JugadorController : MonoBehaviour {

//Declarlo la variable de tipo RigidBody que luego asociaremos a nuestro Jugador
private Rigidbody rb;

//Declaro la variable pública velocidad para poder modificarla desde la Inspector window
public float velocidad;

// Use this for initialization
void Start () {

//Capturo esa variable al iniciar el juego
rb = GetComponent<Rigidbody>();

}

// Update is called once per frame
void Update () {

//Estas variables nos capturan el movimiento en horizontal y vertical de nuestro teclado o mouse
float movimientoH = Input.GetAxis("Horizontal");
float movimientoV = Input.GetAxis("Vertical");

//Un vector 3 es un trío de posiciones en el espacio XYZ, en este caso el que corresponde al movimiento
Vector3 movimiento = new Vector3(movimientoH, 0.0f, movimientoV);

//Asigno ese movimiento o desplazamiento a mi RigidBody, multiplicado por la velocidad que quiera darle
rb.AddForce(movimiento * velocidad);

}
}


Ahora verás que en la Inspector window, apartado Jugador Controller, tienes la posibilidad de modificar la velocidad del jugador. Prueba con diferentes valores.




La cámara

Una de las cosas que habrás podido apreciar es que la Main Camera no sigue al jugador, y además tampoco está muy bien posicionada.

Para empezar, selecciona Main Camera en la Hierarchy Window y, en la sección Transform de la Inspector window, ajusta la Position para que coincida con 0, 10, -10 y la Rotation para que coincida con 45, 0, 0. En la ventana Camera Preview deberías ahora ver el suelo y el jugador centrados.

Ahora, arrastra la Main Camera dentro del Jugador, de modo que se convierta en un GameObject hijo (Child). Has creado la típica configuración de juego en 3ª persona, en la cual al moverse o girar el jugador, la cámara siempre lo sigue a una determinada distancia, como observándolo. Si ahora movemos al jugador, veremos que la cámara se mueve con él.

No obstante, si ejecutamos el juego, vemos que dado que la cámara es hija del jugador, al rotar el jugador también rota la cámara, creando un efecto bastante descontrolado.

De este modo, la solución de que la cámara sea hija del jugador no nos vale, y lo que debemos hacer es crear un script que controle el movimiento de la cámara.

Vuelve a arrastrar la Main Camera de modo que ya no sea hija del Jugador y crea un nuevo c# script llamado CamaraController con el siguiente código (Pon atención a los comentarios autoexplicativos):


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

public class CamaraController : MonoBehaviour {

//Referencia a nuestro jugador
public GameObject jugador;

//Para registrar la diferencia entre la posición de la cámara y la del jugador
private Vector3 offset;

// Use this for initialization
void Start () {

//diferencia entre la posición de la cámara y la del jugador
offset = transform.position - jugador.transform.position;


}

// Se ejecuta cada frame, pero después de haber procesado todo. Es más exacto para la cámara
void LateUpdate () {

//Actualizo la posición de la cámara
transform.position = jugador.transform.position + offset;

}
}


Asocia el script recién creado a la cámara y arrastra el Jugador a la caja GameObject del apartado Camara Controller del Inspector window de Main Camera. El resultado debería ser similar a éste y si ejecutas el juego, verás que funciona correctamente.




El área de juego

El área de juego será tan simple como crear unas paredes en las que rebotar para evitar que el jugador se caiga y unos elementos que debe recoger para ganar puntos y completar el juego.

Para crear las paredes, crea un nuevo Empty GameObject llamado Paredes (y recuerda hacer Reset Position) donde organizaremos las paredes del juego.

Dentro de Paredes, 3D Object > Cube llamado Pared Oeste con Position: -10, 0, 0 y Scale 0.5, 2, 20.5.
Duplica Pared Oeste con cilc derecho > Duplicate, renómbralo a Pared Este y modifica Position a 10, 0, 0.
De igual manera, crea Pared Norte con Position: 0, 0, 10 y Scale: 20.5, 2, 0.5 y Pared Sur con Position: 0, 0, 1-0

Si ahora asignas el material creado anteriormente a las paredes y ejecutas el juego, verás que el Jugador rebota en las paredes. el resultado debe ser similar a este:




Los coleccionables

El objetivo del juego será recoger una serie de elementos que, al igual que en el caso del jugador, crearemos con formas básicas.

Para comenzar, crea un nuevo Game Object vacío con el nombre Coleccionables, y dentro de él un 3D Object > Cube llamado Coleccionable.

NOTA: Recuerda resetear la posición tanto de Coleccionables como de Coleccionable y, si lo prefieres, desactiva de momento al jugador en la escena para que no nos moleste haciendo clic en el tick superior del Inspector window correspondiente.

Modifica ahora las propiedades Transform del cubo para que sea Position 0, 0.5, 0, Scale 0.5, 0.5, 0.5 y Rotation 45, 45, 45.

A continuación crea un nuevo material llamado Oro consistente en un color Albedo Amarillo con un efecto Metalic de 0.500. Aplícaselo al Coleccionable.

Nuestro Coleccionable ya es bastante apetecible, pero lo sería aún más si girara. Para ello, vamos a crear un sencillo script llamado Rotador con el siguiente código (recuerda añadirlo al Cube cuando termines):


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

public class Rotador : MonoBehaviour {

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {

//Rota el elemento una cantidad diferente en cada dirección y enc ada intervalo de tiempo
transform.Rotate(new Vector3(15,30,45) * Time.deltaTime);

}
}


NOTA: En todo momento puedes consultar las propiedades de los diferentes objetos utilizados en C# en la Script Reference de Unity.

Si ahora ejecutas el juego, verás que rota en varias direcciones.

Puesto que nuestro Coleccionable ya tiene todo lo necesario, es el momento de convertirlo en un modelo, plantilla o Prefab, de modo que con todas sus características.

¿Y no puedo hacer directamente un duplicado? Si, pero si más adelante, por ejemplo, quiero modificar el color de todos los coleccionables o la velocidad a la que giran, tendría que hacerlo de uno en uno, mientras que los cambios en un Prefab se aplican a todas las instancias del mismo. Además ese Prefab lo podríamos luego utilizar en otros proyectos, algo que en proyectos más avanzados nos va a ser muy útil.

Crea una carpeta de Prefabs en tu Project window y dentro de ella arrastra nuestro Coleccionable, lo que hará que automáticamente se cree un nuevo Prefab de ese Coleccionable.

Lo siguiente que debemos hacer es colocar el Coleccionable en su ubicación, para después crear más duplicados de ese Prefab en diferentes ubicaciones. Para ello, nos aseguramos de que estamos en vista Global para que al mover el objeto respete el plano y ajustamos el Gizmo para que nos muestre una vista en planta (XZ). El resultado después de colocar 12 Coleccionables de forma parecida a las horas del reloj debería ser similar al siguiente (vista en planta y vista una vez probado el juego:




Recoger los coleccionables

Por defecto, todos los GameObjects que hemos creado presentan una serie de propiedades relacionadas con las colisiones entre objetos. Estas se encuentran en la sección Box Collider del Inspector Window de ese objeto. De hecho, si ahora ejecutamos el juego veremos que el jugador choca con los coleccionables, como hace con las paredes, cuando la idea es que los recoja, bien destruyéndolos al entrar en ellos o desactivándolos.

Para hacer que los objetos sean "traspasables" pero detecten la colisión, debemos marcar la opción IsTrigger de Box Collider. Podemos hacerlo directamente en el Prefab para que lo aplique a todos.

NOTA: Haciendo clic en libro azul a la derecha de Box Collider puedes accedera toda la información de ese componente: parámetros, opciones, eventos, etc.

Por otro lado, si queremos desactivar el objeto en vez de destruirlo (por ejemplo, para que vuelva a aparecer después de un tiempo), de alguna manera tenemos que identificarlo. Para esto, Unity permite añadir etiquetas o Tags a nuestros GameObjects.

Con el Prefab Coleccionable seleccionado, en la Inspector window haz clic en el desplegable Tag > Add tag y añade una nueva Tag llamada Coleccionable. Una vez hecho, selecciona de nuevo el Prefab y desde el desplegable Tag asígnale la recién creada etiqueta Coleccionable. Al haberla añadido al Prefab, actualmente se la añadirá a todas las instancias del mismo. Si, por ejemplo, quisiéramos que cada Coleccionable tuviera un valor distinto, podríamos asignarles diferentes etiquetas.



Con esto ya estaríamos listos para modificar nuestro script JugadorController de modo que detecte la colisión con un Coleccionable y lo desactive:


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

public class JugadorController : MonoBehaviour {

//Declarlo la variable de tipo RigidBody que luego asociaremos a nuestro Jugador
private Rigidbody rb;

//Declaro la variable pública velocidad para poder modificarla desde la Inspector window
public float velocidad;

// Use this for initialization
void Start () {

//Capturo esa variable al iniciar el juego
rb = GetComponent<Rigidbody>();

}

// Para que se sincronice con los frames de física del motor
void FixedUpdate () {

//Estas variables nos capturan el movimiento en horizontal y vertical de nuestro teclado
float movimientoH = Input.GetAxis("Horizontal");
float movimientoV = Input.GetAxis("Vertical");

//Un vector 3 es un trío de posiciones en el espacio XYZ, en este caso el que corresponde al movimiento
Vector3 movimiento = new Vector3(movimientoH, 0.0f, movimientoV);

//Asigno ese movimiento o desplazamiento a mi RigidBody, multiplicado por la velocidad que quiera darle
rb.AddForce(movimiento * velocidad);

}

//Se ejecuta al entrar a un objeto con la opción isTrigger seleccionada
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Coleccionable"))
{
other.gameObject.SetActive (false);
}
}
}


Si ahora ejecutas el juego, verás como puedes "recoger" los coleccionables, de modo que al pasar por encima de ellos, estos se desactivan y desaparecen de la escena.

NOTA: En este proyecto no es importante, pero para ver el "esqueleto" de un objeto y ajustar su forma de colisión, en el futuro haremos uso de la sección Mesh Renderer del Inspector Window. Si seleccionas cualquier objeto y desactivas la casilla de la izquierda de Mesh Renderer, podrás ver el esqueleto de dicho objeto, y en el futuro podrás modificarlo para que la detección de la colisión no coincida con el esqueleto.


Objetos estáticos y dinámicos

Antes de continuar, debemos corregir un error importante.

Por defecto, todos los objetos son considerados static o estáticos a no ser que tengan el componente Rigidbody, en cuyo caso se consideran dynamic o dinámicos.

El problema es que Unity "cachea" los movimientos de todos los objetos estáticos para mejorar la respuesta cuando se reproduce el juego, y como nuestros Coleccionables son estáticos pero están moviendose continuamente, esto obliga a Unity a estar cacheando las posiciones cada frame, lo cual es un consumo de recursos inútil.

Para resolverlo, simplemente selecciona el Prefab Coleccionable y añádele el componente Rigidbody. A continuación, desactiva la opción Use Gravity para que no se caigan, y activa la opción Is Kinematic para que el movimiento esté basado en modificaciones de Transform y no en fuerzas físicas.

De esta forma hemos optimizado de forma significativa el rendimiento de nuestro juego.


Contabilizar y mostrar la puntuación

Para contabilizar la cantidad de Coleccionables recogidos, modifica el script JugadorrController para que incluya lo siguiente:


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

public class JugadorController : MonoBehaviour {

//Declarlo la variable de tipo RigidBody que luego asociaremos a nuestro Jugador
private Rigidbody rb;
//Inicializo el contador de coleccionables recogidos
private int contador;

//Declaro la variable pública velocidad para poder modificarla desde la Inspector window
public float velocidad;

// Use this for initialization
void Start () {

//Capturo esa variable al iniciar el juego
rb = GetComponent<Rigidbody>();
//Inicio el contador a 0
contador = 0;

}

// Para que se sincronice con los frames de física del motor
void FixedUpdate () {

//Estas variables nos capturan el movimiento en horizontal y vertical de nuestro teclado
float movimientoH = Input.GetAxis("Horizontal");
float movimientoV = Input.GetAxis("Vertical");

//Un vector 3 es un trío de posiciones en el espacio XYZ, en este caso el que corresponde al movimiento
Vector3 movimiento = new Vector3(movimientoH, 0.0f, movimientoV);

//Asigno ese movimiento o desplazamiento a mi RigidBody, multiplicado por la velocidad que quiera darle
rb.AddForce(movimiento * velocidad);

}

//Se ejecuta al entrar a un objeto con la opción isTrigger seleccionada
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Coleccionable"))
{
//Desactivo el objeto
other.gameObject.SetActive (false);
//Incremento el contador en uno (también se peude hacer como contador++)
contador = contador + 1;
}
}
}


Ya tenemos implementado el contador, pero necesitamos mostrarlo en pantalla. Para ello, crea un nuevo GameObject UI > Text. Verás que se crea un Canvas o lienzo que lo contiene, así como un sistema de eventos o Event System, de los que hablaremos más adelante. Renombra la caja de texto como TextoContador. Resetea las posiciones y en la vista Game deberías ver algo como lo siguiente:



Modifica TextoContador de modo que el color de texto sea blanco y, para que aparezca siempre en la parte superior izquierda del juego, en su Inspector window, sección Rect Transform, haz clic para anclarla (anchor) arriba a la izquierda, presionando a la vez Alt + Shift de modo que se ancle también el Pivotaje (por si rota):




Para que no quede tan pegado a la esquina, puedes modificar las posiciones Pos X y Pos Y del Rect Transform para que coincidan con 10 y -10, respectivamente. De este modo, establecemos un pequeño padding a la caja de texto.

Por último, vamos a añadir otra caja de texto dentro del Canvas, llamada TextoGanar, con el color de texto en rojo y anclada justo debajo de la anterior. el resultado debería ser similar al siguiente:



Una vez hecho esto, ya podemos modificar el contenido de nuestro script JugadorController para que actualice el texto de las cajas:


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

public class JugadorController : MonoBehaviour {

//Declarlo la variable de tipo RigidBody que luego asociaremos a nuestro Jugador
private Rigidbody rb;
//Inicializo el contador de coleccionables recogidos
private int contador;
//Inicializo variables para los textos
public Text textoContador, textoGanar;


//Declaro la variable pública velocidad para poder modificarla desde la Inspector window
public float velocidad;

// Use this for initialization
void Start () {

//Capturo esa variable al iniciar el juego
rb = GetComponent<Rigidbody>();
//Inicio el contador a 0
contador = 0;
//Actualizo el texto del contador por pimera vez
setTextoContador();
//Inicio el texto de ganar a vacío
textoGanar.text = "";

}

// Para que se sincronice con los frames de física del motor
void FixedUpdate () {

//Estas variables nos capturan el movimiento en horizontal y vertical de nuestro teclado
float movimientoH = Input.GetAxis("Horizontal");
float movimientoV = Input.GetAxis("Vertical");

//Un vector 3 es un trío de posiciones en el espacio XYZ, en este caso el que corresponde al movimiento
Vector3 movimiento = new Vector3(movimientoH, 0.0f, movimientoV);

//Asigno ese movimiento o desplazamiento a mi RigidBody, multiplicado por la velocidad que quiera darle
rb.AddForce(movimiento * velocidad);

}

//Se ejecuta al entrar a un objeto con la opción isTrigger seleccionada
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Coleccionable"))
{
//Desactivo el objeto
other.gameObject.SetActive (false);
//Incremento el contador en uno (también se peude hacer como contador++)
contador = contador + 1;
//Actualizo elt exto del contador
setTextoContador();
}
}

//Actualizo el texto del contador (O muestro el de ganar si las ha cogido todas)
void setTextoContador(){

textoContador.text = "Contador: " + contador.ToString();
if (contador >= 12){
textoGanar.text = "¡Ganaste!";
}

}
}


Antes de ejecutar el juego, recuerda asociar las cajas de Texto creadas con las variables de nuestro JugadorController desde la Inspector Window. Una vez hecho, comprueba que todo funciona correctamente.

Compilar el juego

Hasta aquí da de si este primer juego, al que le harían falta muchísimas otras cosas que te invito a probar.

Para terminar, vamos a aprender como compilar el juego de modo que funcione como aplicación fuera de Unity. Lo primero que debemos hacer es salvar nuestra escena con File > Save Scenes.

Por algún motivo, al menos en la versión Unity 2018.1, es necesario reiniciar Unity para que coja las Tags al ahora de hacer el Build del juego, con lo que reinicia Unity antes de compilar el juego o comprobarás que no recoje los coleccionables correctamente.

A continuación, abre la ventana File > Build Settings... y, para este proyecto, clic Add Open Scenes para añadir nuestra escena, selecciona PC, Mac & Linux Standalone y haz clic en Build.



Crea una nueva carpeta llamada Builds en la raiz de tu proyecto y guarda el Build con el nombre Roll a Ball o el que tú quieras.



Una vez se haya completado, podrás ir a la carpeta Builds de tu proyecto y ejecutar el juego... o enviárselo a tus amigos :-)



Ejercicios propuestos

  • Modifica el proyecto anterior para que los cubos Coleccionables tengan forma de monedas
  • Modifica el proyecto anterior para que el escenario incluya obstáculos y barreras que dificulten la recolección
  • Modifica el proyecto anterior para que el texto de ganar salga en grande en mitad de la pantalla
  • Modifica el proyecto para que incluya dos escenarios diferentes comunicados por una pasarela o trampilla de modo que al recoger todas las monedas de uno de los escenarios, me permita acceder al siguiente.
  • Modifica el proyecto para que incluya un contador de tiempo transcurrido. Añade además a los textos que salen al ganar el tiempo transcurrido.

Fecha de publicación: 10/09/2019
Asignaturas: realización de proyectos multimedia interactivos
Temas: unity videojuegos 2d 3d
Utilizamos cookies propias y de terceros para mejorar su experiencia en la navegación. Al seguir navegando entendemos que acepta su uso.
Si lo desea, consulte nuestras políticas de privacidad y cookies
ENTENDIDO
[X] Cerrar

Contacta conmigo


[X] Cerrar

Acceso alumnos