Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Juego en 60 Minutos Unity 3D
Juego en 60 Minutos Unity 3D
Taller Unity3D
Contenido
1.
Concepto .............................................................................................................................................. 3
2.
3.
4.
Escenario ............................................................................................................................................. 6
4.1.
4.2.
Iluminacin .................................................................................................................................. 8
5.
Jugador ................................................................................................................................................ 9
6.
6.2.
7.
8.
Scripting ............................................................................................................................................. 14
8.1.
8.2.
Disparando ................................................................................................................................ 15
8.3.
8.4.
8.5.
8.6.
8.7.
9.
9.2.
9.3.
9.4.
Toque final................................................................................................................................. 24
9.5.
10.
11.
12.
1. Concepto
Qu juego vamos a hacer? Cules van a ser nuestros personajes? Y nuestro argumento? Y la
jugabilidad? Y las mecnicas?
Debido a la filosofa del taller; aprender lo mximo posible de Unity en un tiempo muy limitado, no nos
podemos extender demasiado en esta parte esencial en la creacin de todo videojuego.
Lo que vamos a hacer va a ser un FPS/Plataformas muy bsico, en el que nuestro objetivo ser llegar a
una determinada parte del mapa sorteando diversas esferas que caen sobre nosotros.
La esencia del concepto se define con el siguiente dibujo:
Esto importar algunos recursos (assets) estndar proporcionados por el equipo de Unity, que nos sern
muy tiles a la hora de ahorrarnos trabajo realizando nuestro juego.
En los equipos del laboratorio, nicamente el directorio C:\hlocal tiene permisos de escritura. Por
ello, aquellos que no tengan equipo propio estn obligados a crear su proyecto en dicha ruta.
Es importante descomprimir dentro de la ruta C:\hlocal\[proyecto]\Assets el archivo
Material.zip suministrado antes del taller. Se crearn las carpetas Sounds e Images.
Una vez hecho esto, estamos listos para comenzar.
3. Creacin de escenas
Unity funciona mediante escenas. Una escena es un nivel de nuestro juego. Todos sus elementos son
privados, y no se pueden usar fuera de ella. En un juego cualquiera hecho en Unity, podramos tener una
escena para el men principal, otra para un tutorial, otra para cada nivel, y una ltima para el vdeo final
de juego.
Cuando se carga una escena, se llevan a memoria todos sus elementos. Al ser descargada, se desaloja
de memoria todo aquello que la escena estaba utilizando. Existen mecanismos para hacer desalojos
selectivos, de manera que las escenas puedan comunicarse entre ellas.
En nuestro caso slo necesitaremos una escena. Para crearla, bastar con guardar la escena actual
(vaca):
-
Ahora debemos aadir la escena a los Build Settings del proyecto para poder ser referenciada desde
cdigo (es decir, para que el proyecto sepa que la escena existe):
-
Ruta: File Build Settings Add Current (debido a que queremos aadir la escena actual)
4. Escenario
4.1.
Plataformas y objetivo
Es hora de construir el ncleo de nuestro juego. Tal y como se puede ver en la ilustracin del concepto, el
escenario contar con 4 bloques flotantes que harn de suelo y uno situado sobre el ms alejado del
jugador, que ser el que se tendr que alcanzar para finalizar el juego. Cada uno de los bloques ser un
GameObject con sus propios componentes Mesh Filter, Box Collider y Mesh
Renderer, que se configurn por defecto.
Numeraremos los bloques como se ve en la siguiente captura:
Para crearlos, utilizaremos cubos re-escalados. Para aadir un cubo a la escena bastar con desplegar la
opcin GameObject Create Other Cube de la barra de herramientas:
Podis ir alternando las perspectivas haciendo click en las diferentes flechas del siguiente icono. Aparte,
podis mover el punto de vista con Click Central y rotarlo con Alt + Click Izquierdo:
A cada bloque lo llamaremos BloqueX, donde X ser el nmero que le corresponda. El bloque nmero
5 se llamar Objetivo. A continuacin se muestran la matriz de transformacin que tendr que tener
cada bloque para conseguir el escenario de la Ilustracin 7.
Nombre
Matriz de Transformacin
Bloque1
Bloque2
Bloque3
Bloque4
Objetivo
Para poder mover y rotar nuestro escenario como un solo bloque, bastar con crear un GameObject
vaco mediante: GameObject CreateEmpty al cual llamaremos Escenario y arrastrar dentro de l
todos nuestros objetos. Antes de hacerlo, tenemos que estar seguros de que nuestro objeto vaco se
encuentra en la posicin (0, 0, 0) y no tiene aplicada ninguna rotacin, ya que sus hijos lo tomarn
como origen de coordenadas. Para que un bloque sea hijo de nuestro objeto Escenario, dentro de la
jerarqua de nuestra escena (Hierarchy) hacemos click en un bloque cualquiera y sin soltar lo arrastramos
encima del nombre de nuestro GameObject vaco. En la siguiente captura se puede ver el momento
inmediatamente anterior de hacer a Bloque1 hijo de Escenario.
Ahora podremos mover el objeto Escenario, y veremos cmo se mueven todos los bloques. Si
queremos duplicar nuestra estructura, bastar con pulsar Botn Derecho Duplicate. Se crear otro
objeto Escenario, cuyos hijos sern los mismos que los del objeto original.
4.2.
Iluminacin
Para iluminar la escena crearemos una luz direccional. Este tipo de luces iluminan en una direccin dada
de forma uniforme. De esta forma, no importa en qu posicin la pongamos.
-
Si el usuario quiere, podr incorporar el foco de luz al GameObject Escenario para tener ms
organizada su escena.
5. Jugador
Llega el momento del movimiento! Una vez tenemos nuestro escenario creado nos hace falta un jugador
a quin controlar. Este personaje jugable ser tambin un GameObject pre-configurado por el equipo de
Unity. Sus componentes configuran la funcionalidad completa de un PJ en primera persona.
Para aadirlo a nuestra escena bastar con que arrastremos a nuestra ventana de Editor desde nuestro
Monitor de Recursos, aqul situado en la ruta: Standard Assets Character Controllers First Person
Controller
All donde lo hayamos arrastrado aparecer una cpsula (nosotros mismos). Aparte, en la jerarqua de
nuestra escena, se mostrar el GameObject con el nombre First Person Controller en azul,
lo renombramos a Player.
Graphics
Main Camera
Ilustracin 15. Nuestro First Person Controller est enlazado con su prefab
Si realizamos algn cambio, sabremos que se est perdiendo la conexin con el objeto raz debido a que
aparece el siguiente dilogo:
6.1.
A continuacin vamos a crear un prefab que ser la municin que podremos disparar posteriormente.
Para ello, seguimos los siguientes pasos:
-
En este punto podemos borrar el cubo de nuestra escena. (Si lo situis un poco por delante
del jugador y dais al
, veris como el cubo cae, siendo afectado por la
gravedad).
6.2.
De igual forma que con el prefab anterior, ahora crearemos uno que ser nuestro enemigo mortal (^_^).
Para ello seguimos los siguientes pasos:
-
7. Etiquetado de objetos
Ahora que ya tenemos los objetos principales de nuestro juego creados, tenemos que organizarlos. Si
queremos acceder a un GameObject desde cdigo, podemos buscarlo mediante su nombre, o mediante
su etiqueta. Nosotros utilizaremos etiquetas, ya que es ms cmodo debido al nmero de enemigos que
tendremos.
Unity cuenta con un sistema de etiquetado que el usuario puede configurar a su antojo. A continuacin
vamos a establecer y a asignar los nombres de las etiquetas que usaremos en nuestro humilde AAA.
En primer lugar, accedemos al Tag Manager desde Edit Project Settings - Tags. Para ver las etiquetas
de nuestro proyecto necesitamos desplegar el campo Tags. Tendremos que aadir las etiquetas de la
siguiente ilustracin:
Para asignarla, tendremos que tener el objeto seleccionado, y bastar con elegirla en la lista desplegable
que se encuentra justo encima de la matriz de la transformacin del mismo:
8. Scripting
En este apartado vamos a insuflar vida a nuestro juego.
Unity funciona con Mono, una implementacin OpenSource del Framework .NET. Por ello, podemos
escribir nuestro cdigo en Javascript, C# o Boo. En el taller vamos a utilizar Javascript debido a que es
algo ms inmediato que los otros dos.
8.1.
Lo primero que vamos a hacer ser que nuestro jugador muera al caer al vaco. Para ello tendremos que
crear un script que implemente esa funcionalidad, y aadrselo como componente a nuestro objeto
jugador.
-
El cdigo simplemente reinicia el nivel cuando la posicin vertical del jugador es igual o inferior a -30, es
decir, cuando el jugador ha cado al vaco.
El mtodo Update() se ejecuta una vez por frame, en l incluimos la funcionalidad. Con
transform.position.y, nos referimos a la posicin en el eje vertical de nuestro objeto. Al ser el
script un componente de nuestro jugador, la propia semntica de Unity permite referirse a sus otros
componentes con palabras clave.
En la funcin Dead(), la cual hemos creado nosotros mismos (no es reservada por Unity), simplemente
cargamos el nivel llamado game. Para que sto pueda hacerse en tiempo de ejecucin es necesario
haber aadido el nivel en las Build Settings del proyecto (ver Apartado 3: Creacin de escenas). El
resultado es un reinicio inmediato del nivel, lo cual elimina cualquier progresin que pudiramos haber
hecho.
Probad la cada!
8.2.
Disparando
Por fin algo interesante! Vamos a hacer que nuestro hroe dispare cubos extra-resistentes-antienemigos.
Para ello, tendremos que aadir un script a nuestro jugador que implemente dicha funcionalidad. Dicho
script ser un componente ms de nuestro GameObject Player:
-
Cdigo 2. Disparo
Este cdigo instancia el objeto bullet en la posicin y rotacin del GameObject del cual forma parte, y
le imprime una velocidad inicial con valor speed en la direccin Z (hacia delante) local.
bullet y speed son variables pblicas, lo cual significa que son visibles desde la jerarqua de
componentes del objeto, y por tanto se les puede dar un valor sin tocar cdigo:
A disparar!
8.3.
Spawn de enemigos
ste es quiz el punto ms importante de nuestro juego. Cundo, cmo y dnde generamos a nuestros
enemigos? Dentro de nuestro escenario, crearemos un GameObject vaco al cual aadiremos un script.
Dicho script tomar la posicin del GameObject y con algunos sencillos clculos instanciar los enemigos
con una frecuencia establecida por el usuario, en posicin (tanto horizontal como vertical) variable, y con
una velocidad inicial (slo vertical) que tambin ser diferente en cada uno de ellos.
Para ello:
-
transform.position.y+offsetY,
transform.position.z+offsetZ);
var instantiatedProjectile : Rigidbody =
Instantiate(enemy, position, transform.rotation);
instantiatedProjectile.velocity =
transform.TransformDirection(Vector3(0,-speed,0));
}
}
Podemos ver que este cdigo es bastante similar al de la instanciacin de las balas disparadas por
nuestro personaje (ver Apartado 8.2: Disparando). La principal diferencia es la posicin en la cual se
crean nuestros enemigos. Para dar un comportamiento emergente a nuestro juego, hacemos que dicha
posicin vare dentro de unos lmites respecto a la posicin de nuestro GameObject SpawnEnemies.
En nuestro caso (-3, 3) para la posicin vertical, y (-4,4) para la posicin vertical.
Aparte de esto, controlamos la frecuencia de instanciacin de los enemigos con la variable tick. Dicha
variable, que inicialmente es cero, va almacenando el sumatorio del tiempo de ejecucin del frame N-1
(Time.deltaTime). De esta forma, podemos llevar la cuenta del tiempo transcurrido en un
determinado momento del juego, independientemente de la mquina que tengamos (ms o menos
potente). Controlando el lmite superior al que puede llegar tick mediante la variable pblica paso, el
usuario puede configurar desde fuera cuntos segundos tienen que transcurrir entre la aparicin de los
diferentes enemigos. En la Ilustracin 26 se muestra un valor ajustado de la variable paso.
Avalancha!
8.4.
Liberar memoria
Es importante no cargar la escena de demasiadas instancias de un objeto. Para ello, podemos configurar
stos para se destruyan automticamente despus de X segundos.
Para ello, tendremos que crear un nuevo script y aadirlo como componente al prefab de nuestros objetos
(bullet y enemy):
-
bullet
enemy
Tabla 3. Valores en segundos para la autodestruccin de objetos
Este script es sencillo. Simplemente se llama a Destroy sobre nosotros mismos, con un retardo de
waitSeconds segundos. Una vez transcurrido ese tiempo, el objeto se destruye.
Es importante observar que esta vez no incluimos nuestra funcionalidad en el mtodo Update, sino que lo
hacemos en el mtodo Start() perteneciente al API de Unity, y cuyo contenido se ejecuta al ser
instanciado el GameObject que tiene el componente script aadido.
8.5.
Un toque mata
En esta seccin vamos a complicar la lgica del juego. Lo que queremos conseguir es que el jugador
muera cada vez que sea golpeado por un enemigo. Aparte, para facilitarte un poco la tarea, tambin
realizaremos un pequeo script que destruya una esfera al entrar en contacto con uno de nuestros
mortferos proyectiles.
Primero, aadimos la amenaza enemiga:
-
Este cdigo funciona de manera similar al anterior. Para todas las colisiones de nuestros bullet, se
busca aquellas que ocurran contra gameObjects cuyo tag sea enemy (ver Apartado 7: Etiquetado de
Objetos), en cuyo caso el objeto destino es destruido. Con una variable pblica
destroyOnCollision podemos establecer si queremos que nuestro bullet se destruya al
entrar en contacto con algn objeto (no slo enemigos) o no.
8.6.
Llegando a la meta
Ya era hora de ponerle fin al juego! En este apartado controlaremos cundo el jugador toca el
GameObject Objetivo, y finalizaremos nuestro breve periplo.
Para ello en primer lugar crearemos una imagen que ser mostrada sobre la pantalla cuando ocurra la
colisin entre nuestro jugador y el Objetivo:
-
Los atributos arriba descritos son aplicables a la imagen finish.png (suministrada junto a este tutorial). Es
importante que el componente GUITexture est desactivado de inicio (marcado en verde) para que no
sea visible e interfiera con la jugabilidad.
Ahora tendremos que crear el script con el cual mostraremos la imagen una vez hayamos llegado al final
del nivel. Tambin permitiremos reiniciarlo pulsado una determinada tecla:
-
En primer lugar, tenemos una variable pblica correspondiente al componente GUITexture de nuestro
objeto Finish. Gracias a dicha variable, podremos hacer visible la imagen cuando nuestro
CharacterController colisione con el GameObject Objetivo. Para ello, usamos la funcin
OnControllerColliderHit y gestionamos el caso en el que la colisin sucede contra un objeto
cuyo tag es target. En ese caso ponemos a true un flag finished, activamos nuestra imagen, y
paramos el tiempo. Dentro del mtodo Update, controlamos que cuando el flag finished est
activado y el jugador pulsa la tecla escape, el nivel se reinicie.
El mtodo Start() desactiva la visibilidad de la imagen y reconfigura el tiempo a su velocidad normal.
Esto se realiza por seguridad, para que en ningn caso se muestre la imagen cuando comience el juego
ni el tiempo est parado.
Ya me lo he pasao
8.7.
Bonus Track!
A continuacin se muestra el cdigo de un script que permite al jugador parar el tiempo pulsando la tecla
P. Hay que tener en cuenta que si se para el tiempo, tambin el jugador deja de moverse . Tambin se
muestra una re-implementacin de la funcin Shoot, que emula el funcionamiento de una metralleta,
cuya cadencia se puede controlar mediante una variable pblica y que ofrece la posibilidad de disparar
proyectiles con una velocidad inicial aleatoria. Por ltimo, con una simple lnea de cdigo, podemos hacer
un GameObject rote sobre un eje vertical
function Update () {
if (Input.GetKeyDown (KeyCode.P)) {
Time.timeScale = 1.0-Time.timeScale;
Time.fixedDeltaTime = 0.02 * Time.timeScale;
}
}
Cdigo 8. Parar el tiempo
Cdigo 9. RepeatedShoot
9.1.
Mirando al horizonte
Para configurar nuestro cielo bastar con hacerlo en la configuracin de Renderizado del proyecto:
-
9.2.
Para poder configurar el Normalmap tal y como se ve en la Ilustracin 29, debemos generarlo antes en
nuestra jerarqua de proyecto:
-
Una vez hecho esto, bastar con arrastrar nuestro material directamente a los objetos de nuestra escena
que queramos que lo usen. Es indiferente hacerlo en la jerarqua de la escena, o en la representacin
grfica de los mismos. Ahora deberamos tener ms o menos el siguiente resultado:
9.3.
De igual forma que con el suelo, crearemos una textura para los enemigos. En este caso ser algo ms
simple:
-
Socorro, Sandas!
9.4.
Toque final
9.5.
Bonus track!
Entre el material extra que se ha suministrado hay una imagen llamada orange-bumpmap.png, la cual
se puede utilizar para crear un Material de tipo BumpedDiffuse, con MainColor naranja, y
posteriormente aplicrselo al prefab enemy, consiguiendo as la textura de una naranja. Se deja a
eleccin del usuario el implementar esta asombrosa funcionalidad. . Tambin est disponible una
textura llamada dominoPiece.png, por si alguien quiere modificar las dimensiones de su prefab
bullet y aplicarle esta textura, de manera que dispare fichas de domin-asesinas. (Quizs podra
combinarse con el Script de rotacin del Bonus Track de Scripting).
10.
Msica Maestro!
En este ltimo punto vamos a aadir una meloda de fondo que vaya incrementando su volumen segn
nos acerquemos a la fuente del sonido.
Para ello:
-
Tenemos que tener una carpeta Sounds con el track: BSO_GrimFandango.mp3 dentro
(ver Apartado 2: Creacin de un proyecto nuevo)
Arrastramos el track a nuestro GameObject Objetivo. Se crear un componente
AudioSource.
function Start() {
audio.Play();
}
Cdigo 11. Activando msica
11.
Build Multiplataforma
Hacer el Build es el ltimo paso de nuestro juego. Con ello, construimos un ejecutable que puede correr
en cualquier mquina para la que haya sido realizado.
El proceso es bastante simple:
-
En el caso
Con la versin gratuita de Unity slo podremos realizar Builds para Navegador Web, Windows y MAC.
Para el caso de un Build para navegador, se crea un archivo con extensin *.unity3d, y un
*.html que lleva embebido con el cdigo HTML necesario para la visualizacin web de nuestro juego.
Bastar con abrir el HTML en una mquina que tenga instalo el plugin de visualizacin correspondiente
(Unity Web Browser Plugin) y
A jugar!
12.