Vous êtes sur la page 1sur 82

CURSO BSICO DE PROGRAMACIN

EN UNITY CON JAVASCRIPT




NDICE
1. Variables
1.1 Tipos de Variables
2. Funciones
2.1 Function Start
2.2 Function Update
2.3 Function OnTrigger
2.4 Function OnGUI
2.5 Function OnMouseDown
3. Sintaxis
4. Nuetro primer cdigo
5. Vectores
6. Rayos
7. GUI
7.1 Texturas y textos
7.2 Box y buttons
7.3 Posicionamiento
7.4 Montando un men
8. Empezemos nuestro juego!
8.1 Controller simple
8.2 Vida y energa
8.3 Peligros!
8.4 Items
8.5 Plataformas mbiles
8.6 Muerte
8.7 Mens
8.8 Terminando
9. Produciendo nuestro juego
9.1 Build
9.2 Listo para entregar!


Presentacin:

Antes de empezar con el curso me gustara decir que
voy a intentar hacer este curso lo ms simple y
entendible posible, as que este curso es apto incluso
para aquellos que no saben nada de programacin. Si
ya tienes conocimientos previos te aconsejo pasar
directamente al apartado 4 (Nuestro primer cdigo),
aunque deberas hechar un vistazo al apartado 2:
Funciones, para aprender las funciones bsicas de
Unity.

Gracias por leerlo y espero que os sea til este curso.

____________________________________________
_______

1. Variables

En ocasiones el concepto de variables puede ser difcil de entender, as
que en mi opinin dejemonos de conceptos y explicaciones tcnicas y
vamos a explicar que son las variables de una forma ms sencilla.

Una variable simplemente es un dato, puede ser un nmero, como la
municin que tienes en un juego de disparos, o puede ser una textura,
como la de una pared de ladrillos, puede ser un objeto del juego, como
una caja, una casa, etc. Una variable no es ms que una cosa del juego
que se incluye en un script, puede ser un sonido, un objeto, una textura,
un valor...

Creo que esto ha sido una explicacin bastante sencilla pero si no te ha
quedado claro ahora explicar los tipos de variables.

1.1 Tipos de variables

1 - Int

Una variable Int (Integer) es simplemente un valor entero, es decir,
nmero sin decimales.

Ej: -3, -2, -1, 0, 1, 2, 3, 4

Para qu se usa? Pues su uso puede ser muy diverso, pero lo ms
comn suele ser para valores del juego como la municin, el dinero, etc.

Por qu estos valores sn numeros sin decimales?

Bueno, porque no puedes tener 30.74 balas para disparar, ni 21.36
monedas para gastar. Hay valores en el juego que es mejor gastar
nmeros enteros, se podran gastar igualmente nmeros con decimales,
pero si no quieres correr el riesgo de que a un jugador le aparezcan 2.3
balas, mejor una int.



2 - Float

Bueno, con esta terminar rpido dado que es lo mismo que la anterior
pero con decimales. Ej: -1.243, 0.535, 7.368



3 - Boolean

Una boolean es una variable que solo puede tener dos valores, llmalos
como quieras: 0 y 1 / verdadero o falso / esto o aquello

En la programacin se escribe que es true o false. (verdadero o falso)

Se suelen usar para poner condiciones. Ejemplo, en un juego de disparos
quieres disparar solo si tienes balas (lgico), si no tienes balas no. Pues
creas una variable BOOLEAN que se llame... "poder_disparar".

Primero: si "poder_disparar" es verdad ------ disparas

Luego: si "municin" es mayor que 0 -------- "poder_disparar" es verdad
si "municin" es 0 o menos ------------- "poder_disparar" es mentira

Te lo dejo en script si no te ha quedado claro:



4 - Double

Estas no las gastaremos. Las double son como las int pero aceptan
valores ms grandes, explico: las int, solo llegan hasta 32767.

Las int van de -32767 a 32767:


-32767 ------------------------------ 0 ------------------------------ 32767

si a una variable int con valor 32767 (valor mximo) le sumas +1 se va al
otro extremo, es decir, vuelve a -32767.

Por eso las variables double sirven para valores muy grandes, pero no
creo que las usemos.

VARIABLES DE UNITY

A partir de aqu nombraremos algunas de las variables ms usadas de la
librera de unity (eso quiere decir que estas variables solo sirven si
programas en unity)

1 - GameObject

Pues esto es simplemente un objeto, cualquier cosa que tengas en la
escena: un cubo, una esfera, la cmara, el player, un modelo, un sonido,
etc.

Puede ser un objeto de la escena o bien un prefab que tengas en project.

Normalmente se asignan en el inspector, pero algunas veces puedes
asignarlas desde el script.



2 Vector

De estos ya hablaremos ms tarde que son ms complicados.

var posi : Vector3

3 Texture2D

Son como el GameObject pero este es una Textura, no un objeto.



Y bueno, aunque hay ms estas son las que vamos a usar
principalmente. Si me dejo alguna ya la explicar ms tarde.


2. FUNCIONES

Las funciones son los bloques dentro de los cuales estn los comandos.
Todo efecto que hace un script (que un objeto se mueva, que te baje la
vida, etc) debe estar escrito dentro de un bloque, estos bloques son las
funciones.

Hay varios tipos de funciones, y cada una funciona de una manera
distinta, que ahora vamos a explicar.


2.2 Tipos de funciones



Function Start:

La funcin start se ejecuta cuando empieza el nivel en el que ests. Cada
vez que entras en una pantalla se ejecuta el comando (el script) que haya
dentro.





Function Update



La funcin Update se ejecuta todo el tiempo, a cada momento del juego.
Est es la funcin ms usada, aunque su cdigo suele llevar condiciones,
ejemplo:



solo si pulsas el botn espacio saltas, solo si tienes balas disparas...



Por qu? Muy sencillo, si en Update escribes un cdigo que sirva para
disparar, por ejemplo, y no le pones la condicin de que eso pase cuando
le das al botn izquierdo del ratn, estaras siempre disparando, sin
pulsar nada dispararas siempre.



Aun as, algunas cosas como las asignaciones de valores se hacen sin
condiciones, por ejemplo, si tienes en la esquina inferior izquierda un
medidor de vida (100 HP) quieres que ese 100 cambie si te baja la vida,
si te hacen dao y tu vida baja a 56, quieres que en pantalla tambin
ponga 56, pues pondras un cdigo sin condiciones, en el que dices que
en cada momento del juego el valor que te pone en pantalla sea igual a
la variable vida.


Para entenderlo mejor te dejo el cdigo:



El segundo cdigo lo que hace es que un texto que aparece en pantalla
represente la vida. Es un texto que si la vida es 100, muestra 100, si es
50, muestra 50. Esto ya lo explicar en el apartado del GUI (Apartado 7)

Esto tiene que ser cierto durante todo el juego, es decir, si te baja la vida
de 100 a 72, el texto en la pantalla tiene que cambiar de 100 a 72. El
texto tiene que ser en todo momento igual a la vida. Para eso debes
incluirlo en Update.

Si lo incluyeras en Start, el valor no cambiara.

Creo que esto es fcil de entender no? Quizs me excedo con la
explicacin pero es que no quiero que luego aparezca el tpico que dice
"no me he enterado de nada!" ... Continuemos!


Function OnTrigger

Esta es una funcin muy interesante. Esta se ejecuta cuando un objeto
entra dentro de otro. Este script lo debes asignar al objeto en el cul se
entra.

Por ejemplo, sabes cuando en los juegos vas caminando tan
tranquilamente, y de golpe te sale un vdeo, o un texto, o un dilogo o lo
que sea, al entrar en una habitacin, o simplemente caminando? Pues
esto, en la mayora de los casos suele ser un cubo invisible (una caja
enorme que no puedes ver) y que cuando entras en ella se ejecuta el
script.

Metes el cubo en la entrada a una sala, lo haces invisible, haces que sea
atravesable (en el inspector, en el Box Collider le das a IsTrigger) y luego
le metes un script con Function OnTrigger.

Pero hay varios tipos de OnTrigger:

OnTriggerEnter: Cunado entras en el objeto.

OnTriggerStay: Mientras ests en el objeto.

OnTriggerExit: Cuando sales del objeto.

Si te fijas el OnTriggerEnter / Exit sera como la funcin Start, solo se
ejecuta una vez, mientras que OnTriggerStay sera como Update, se
ejecuta todo el rato (que ests dentro del objeto)

Un aviso: si quieres que el script se ejecute cuando el jugador entra
dentro del cubo, eso debes especificarlo, porque el script se ejecuta
cuando detecta que algo entra en el cubo, pero en el cubo puede entrar
cualquier cosa: un enemigo o simplemente un trozo de la pared, o el
suelo. Por eso dentro de la funcin debes poner como condicin que sea
el player el que entra. Te dejo el ejemplo:



Habrs visto que esta vez entre los parntesis pone algo (other :
Collider), other es el objeto que choca con el que contiene el script. Si te
da igual qu objeto choque no hace falta que pongas nada, pero como en
este caso quieres especificar que sea el jugador el que entre en el cubo,
debes ponerlo.

As ves como luego ponemos como condicin que el nombre del otro
(other.name) sea "First Person Controller", eso en caso de que uses el
First Person Controller, sino aqu ira el nombre que le pongas al player.

IMPORTANTE: para que esta funcin funcione correctamente, ambos
objetos deben tener un collider, y como mnimo uno de los dos debe
tener un rigidbody puesto, si no, no detecta la collisin.

Function OnGUI



Est funcin, al igual que Update, se ejecuta durante todo el juego, pero
sta solo sirve para scripts que utilizen comandos del GUI, como GUI.Box
(que crea un recuadro en pantalla, o GUI.Button (crea un botn).



Todo lo que sea GUI debe incluirse dentro de function OnGUI, si lo
incluyes en Update no funcionar. Ah va el ejemplo.







Function OnMouseDown

Es una funcin muy til. sta se ejecuta cuando pulsas encima del objeto
que lleve este script. En caso de que sea un objeto (un modelo) debe
llevar un Collider, si no lo lleva esta funcin no hace efecto, pero tambin
se puede dar el caso de que sea un GUI Texture, es decir, que con esta
funcin puedes crear botones, puedes poner en pantalla una imagen que
si le das se ejecuta un Script. Tambin existe el OnMouseUp, que es
cuando pulsas en algo, al levantar el dedo del click, de la tecla del ratn.




3.Sintaxis

Pues bien, dado que ya conoces las variables y las funciones, antes de
empezar a escribir un cdigo te explicar las normas de ortografa que
son bastante bsicas y puede que ya las conozcas. Empecemos:

1 - Declarar una variable.

A la hora de declarar una variable lo primero es escribir la palabra
clave var, seguida de el nombre de la variable (el que tu quieras), pero
recuerda que no puedes incluir espacios y que en programacin la
diferencia entre maysculas y minsculas existe. A continuacin debes
detallar el tipo de variable, con dos puntos seguido del tipo de variable:

var Nombre : int;

2 - Comentarios

En los scripts puedes incluir comentarios, que salen en color verde,
puedes ver que he incluido unos cuntos en los ejemplos anteriores de
cdigo. Los comentarios son partes omitidas del cdigo que el compilador
ignora, en pocas palabras: que no sirven para nada.

Pero lo comentarios pueden servir muchas veces, si quieres probar como
funciona un script sin una parte del cdigo (alomejor porque esa parte te
da error, o porque no te gusta...) sera muy molesto tener que borrar esa
parte del script, probarlo, y luego volverla a escribir.
Es ms fcil utilizar los comentarios para dejar una parte del script
apartada por si la quieres usar luego.

Hay dos formas de incluir comentarios:

o Con dos barras // : esto convertir la lnia en la que estas en un
comentario, desde las barras hacia deltante.
o Con /* : todo lo que se encuentre entre /* y */ es un comentario,
puedes hacer comentarios de varias lnias, o solo un trozo.

Ejemplo a continuacin.



3 - Puntualizacin

Todas las lnias que contengan un comando o una declaracin deben
terminar en punto y coma (;):

declaracin: var TROF : boolean;

comando: Destroy (this.gameObject);

Todas las aperturas de funcin o condicin deben abrirse y cerrarse con {
}

if (condicin) {
}
function Update() {
}

No te olvides cuando empiezas una funcin de incluir los parentesis de los
parmetros: function Update ( ) y tampoco te olvides en la function
OnTrigger de incluir en los parametros el Collider:
function OnTriggerEnter (other:Collider)

4 - Asignacin

Esto es un fallo muy comn cuando empiezas a programar. Si en una
funcin asignas un valor a otro, Ej: municion = 30; solo se emplea un
igual, pero dentro de una condicin debes emplear dos iguales:

if ( municion == 30)

Si solo pones un igual te dar error. Tambin debes tener cuidado de no
asignarle, por ejemplo, un valor decimal a una variable int. Si le asignas
23.45 a un integer te dar error, ya que es solo para nmeros enteros.


5 - Operadores lgicos

Esta puede ser la parte ms importante de este apartado. Los operadores
lgicos se usan en las condiciones, ahora vers:

o Igual == , se utiliza para preguntar si hay igualtad entre A y B if (A ==
B)
o No igual != , se utiliza para preguntar si A no es igual que B if (A != B)
o Mayor que >, se utiliza para preguntar si A es mayor que B if (A > B)
o Menor que <, se utiliza para preguntar si A es menor que B if (A < B)
o Mayor o igual >=, se utiliza para preguntar si A es mayor o igual que B if
(A >= B)
o Menor o igual <=, se utliza para preguntar si A es menor o igual que B if
(A <= B)
o Or ( || ), se usa para indiciar que la funcin se ejecute si se cumple una
de las dos condiciones: if ( A == B || A < C) solo uno de los dos tiene
que ser cierto, si A = B o A < C se ejecutar el cdigo. Para escribir || es
Alt derecho + 1
o And (&&), SHIFT + 6, se usa para indicar que la funcin se ejecuta si
ambas condiciones se cumplen: if( A==B && A > C) ahora ambas
condiciones deben cumplirse, A tiene que ser igual a B, y A tiene que ser
mayor que B.

4. Nuestro primer cdigo

Creo que despus de todo lo explicado ya es hora de que nos dejemos de
explicaciones y vayamos un poco a la accin. Vamos a empezar
escribiendo un cdigo sencillo. Te voy a ensear a hacer un script
bastante sencillo con el cul haremos que un objeto desaparezca al
pulsar un tecla, la que tu quieras.

Primero empieza abriendo Unity y abriendo una escena nueva (new
scene). Primero de todo crea una luz (GameObject > create other >
Directional Light), ahora crea un cubo, luego mueve la cmara (main
camera) delante del cubo, para que se vea mientras juegas. Dale al play
para comprobar que cuando juegas se ve el cubo delante de ti.

Si no lo ves bien iluminado rota un poco la directional light para enfocar
bien el cubo.

Ahora en Project, donde quieras, click derecho y "create javascript",
luego dale dos veces click izquierdo al nuevo archivo que has creado y te
se abrira el editor de scripts. Te saldr algo como esto:





Brralo todo menos la function Update. Ahora que tenemos la funcin
Update pregntate: Si queremos que el cubo desaparezca al darle a un
botn que es lo primero que debemos hacer?

Por supuesto: la condicin, antes de escribir ningn cdigo debemos
comprobar qu condiciones queremos que se cumplan, en este caso que
le demos al botn.

Vamos a poner esto a continuacin de function Update() {

if (Input.GetKeyDown (KeyCode.Space)){

Ahora te lo tengo que explicar. Input.GetKey es el comando que
significa pulsar la tecla. Hay 3 tipos o modos:

-Input.GetKeyDown: se ejecuta cuando pulsas la tecla.

-Input.GetKey: se ejecuta todo el tiempo que tienes la tecla pulsada.

-Input.GetKeyUp: se ejecuta cuando levantas el dedo de la tecla.

El GetKey se utiliza cuando queremos que un comando se ejecute
contnuamente mientras pulsamos la tecla, como caminar, que si dejas
pulsado W avanzas hacia delante, pero en este caso queremos que se
destruya el cubo, eso no es algo contnuo, si no algo que pasa solo una
vez, por eso utilizamos GetKeyDown.

Luego (KeyCode.Space) , KeyCode sirve para indicar que estas
mencionando una tecla, simplemente ponlo y listo, seguido de punto y el
nombre de la tecla.
Aqu yo he puesto "Space" (Espacio), si quieres cambiar la tecla solo pon
la que quieras. Ej: letra T ---> (KeyCode.T), flecha arriba ---->
(KeyCode.UpArrow)

Si quieres ver una lista de teclas vete a google y escribe: "Unity Script
Reference", esta pgina te ser muy til, ah tienes informacin sobre
toda la programacin en unity. Escribe KeyCode en la barra de buscar y
te saldr una lista de teclas.

Fcil, no? Bien, continuemos. Ya tenemos la condicin, ahora la accin.
Queremos que el cubo se destruya, pues a continuacin de la condicin
escribimos:

Destroy (this.gameObject);

Explico: Destroy es fcil, destruir, destruye el objeto que pongas entre
parntesis, y entre parntesis tenemos "this.gameObject", esto significa
simplemente (traduciendo a lo simple) "este objeto".

Destroy (this.gameObject); = Destruir este objeto.

Ahora para terminar cierra la condicin y la funcin con }



Ahora selecciona el cubo, luego arrastra el script hasta l. Primero
guarda, acurdate siempre de guardar el script, luego dale a Play y
empieza el juego. Dale a tu tecla (en mi caso espacio) y BOOM! El cubo
desaparece!

5.Vectores

Los vectores son muy importantes en la programacin sobre todo en un
entorno 3D. No sabes qu es un vector? Muy sencillo, un vector (de 3
dimensiones) consta de 3 valores: x,y, z. En caso de que fuera un vector
de 2 dimensiones tendra dos valores: x,y. Para hacerte ms fcil el
aprendizaje de los vectores yo he decido dividirlos en dos tipos: Vectores
de posicin y vectores de direccin.

-Vectores de posicin: a veces tendrs que utilizar los vectores para
indicar una posicin en el juego, un sitio de tu escena, un punto. Para
eso debers utilizar un vector con la posicin x, la posicin y, la posicin
z.

-Vectores de direccin: estos ya son ms difciles de entender. Estos se
usan cuando quieres indicar la direccin en la que se tiene que mover un
objeto. Si tu quieres que un objeto se mueva en el juego debes indicar
con un vector hacia que direccin. Pues no son coordenadas lo que tienes
que poner. En el vector de direccin solo se pone 1 o 0.

Explico: Vector (1,0,0) x = 1, y = 0, z = 0 , esto significa que se mueve
en direccin a la X. Dado que la direccin en vertical (Y) y en profundidad
(Z) es nula, se dirige a (X=1). Si no lo entiendes observa la siguiente
tabla:



En esta imagen he omitido el eje Y porque es todo el rato cero.

Como puedes ver, en el primer eje, solo X = 1, y la direccin es X.

En el segundo Z = 1, y la direccin es Z.

Y en el tercero que X = 1 y Z = 1, la direccin es entre ellos dos.

Si aun as no lo has entendido ahora hablar del uso de vecores.

USO DE VECTORES:

Para explicarlo usar el transform.position y el transform.Translate.

Transform.position es la posicin del objeto que contiene el script. Si
nosotros declaramos una variable tipo Vector: var posi : Vector3;

y luego le asignamos una posicin en el espacio a posi:
posi = Vector3(34.64, 54.32, 78.98);

Ahora ponemos en un script que la posicin del objeto es posi,
transform.position = posi;
El objeto se ir a esa posicin, a las coordenadas que le hemos puesto.

Pero ahora en cambio usaremos transform.Translate, este sirve para
mover un objeto, pero no a una posicin, sino en una direccin. Este
comando mueve un objeto hacia delante, atrs. Lados, arriba, abajo o la
direccin que tu le des.

En este caso declaramos la variable:

var direcc : Vector3;

Asignamos: direcc = Vector3(0,1,0);

Y luego escribimos: transform.Translate (direcc);

Esta vez el objeto estar contnuamente movindose en la direccin que
le hemos puesto (0,1,0), Sabes que direccin es? Hacia el lado? Hacia
arriba? Hacia atrs? Lo vas a comprobar porque vamos a hacer el script.

Vamos a hacer un script para una plataforma mbil, es decir, un objeto
que se mueve en una direccin. Si tienes el cubo de antes en la escena
quitale el script de destruir (si esa parte te la has saltado y no sabes de
qu te hablo crea una escena, con una luz y un cubo y pon la main
camera enfrente del cubo para que se vea al jugar) y crea un nuevo
script. Vamos a escribir.

Empieza poniendo la function Update. Dentro de esta vamos a poner la
condicin de que el objeto solo se mueva si nosotros pulsamos el botn.
En este caso usaremos los botones de flecha arriba y abajo.

Escribe esto:

if (Input.GetKey (KeyCode.UpArrow)){

A continuacin escribes lo que hemos nombrado antes:

transform.Translate ( Vector3(0,1,0) );

Ahora cierra solo la condicin, no el Update, con } , y pones a
continuacin otra condicin:

if ( Input.GetKey (KeyCode.DownArrow)){
transform.Translate ( -Vector3(0,1,0) )
}

Ves que delante de Vector3 he puesto un negativo (-), eso es para que al
pulsar la flecha abajo se meuva en la direccin contraria a si pulsas la
flecha arriba.

Y ya cierras todo, cierras la funcin, te quedara algo as:



Prueba a meterle el scritp al cubo y dale al play. Ahora pulsa las teclas de
flecha arriba y flecha abajo. El cubo efectivamente se mueve pero para
mi gusto un poco demasiado deprisa as que vamos a fijarle una
velocidad.

Esto se introduce dentro de transform.Translate:

transform.Translate ( Vector3(x,y,z) * AQUI );

Y vamos a poner esto:




Y pensars: Qu es eso de Time.deltaTime? Parece muy complicado
pero es muy sencillo. Time.deltaTime significa "por segundo".

Lo que quiere decir que ahora se mover a una unidad por segundo.
Prueba, guarda y dale al play. Puedes comprobar que se mueve ms
lento.

Y si quieres que vaya ms deprisa o ms lento? Pues entre el vector y el
Time pones multiplicar por un nmero:

Vector3(0,1,0) * 2 * Time.deltaTime //Ahora va el doble de rpido

Vector3(0,1,0) * 0,5 * Time.deltaTime //Ahora va la mitad de rpido

Una ltima cosa sobre los vectores antes de terminar. Unity ya tiene unos
vectores de direccin predeterminados:
Vector3.forward (hacia delante), Vector3.right / Vector3.left (hacia los
lados), Vector3.up / Vector3.down (arriba y abajo).

Si quieres puedes probar el script anterior cambiando Vector3(0,1,0) por
Vector3.up


6. Rayos

Los rayos son tambin una herramienta muy til, por ejemplo, los juegos
de disparos para disparar utilizan un rayo. Del arma hacia delante hay un
rayo invisible que por supuesto los jugadores no pueden ver, pero est.

Ese rayo va del arma, del punto donde disparas, hacia delante hasta que
topa con algo, as que cuando disparas es el que detecta si en disparas a
otro jugador o a una pared o lo que sea.

Pero no solo eso, sabes esos juegos de estrategia sobre construir
ciudades? Te habrs fijado que en algunos sitios te permiten construir
edificios y en otros no. Hay varias formas de hacerlo, pero una es
creando un rayo desde el ratn hacia delante, y detecta si puedes o no
construir.

Bueno, estos son solo unos ejemplos, las utilidades que le puedes dar a
los rayos son infinitas, lo que te se ocurra. Qu te parece si hacemos un
script en el cul si pasas el ratn por encima del cubo se destruye?
Creando un rayo que detecte lo que ests tocando con el ratn, y si el
objeto que tocas es el cubo lo destruye.

Para crear un rayo primero debes crear la variable var rayo :
RaycastHit, y aqu tienes un nuevo tipo de variable: RaycastHit. Ahora
que esa variable est creada solo tienes que poner la condicin:

if (Physics.Raycast ( punto_de salida, direccin, rayo, distancia))

Eso que he puesto entre parntesis son los parmetros, es decir los datos
que tienes que dar para crear la condicin.

Si algo no te queda claro espera que luego pongo la imagen del cdigo y
lo vers ms claro.

1 Punto de salida y direccin

Aqu deberiamos poner primero el objeto o punto desde donde sale el
rayo, y luego un vector de direccin que diga si el rayo sale hacia
delante, hacia atrs, hacia los lados, etc.

Nosotros en vez de poner punto de salida y direccin pondremos un ray,
un ray es un tipo de variable, que ya indica punto de salida y direccin.
Igual que un vector indica x, y, z, un rayo indica punto y direccin. Total,
que creamos otra variable as:
var rayo_camara : ray =
Camera.main.ScreenPointToRay(Input.mousePosition);

2 Rayo. Aqu va el nombre de la variable que hemos creado (var rayo :
RaycastHit). Nombre: rayo.

3 Esto es la distancia que tiene el rayo, es decir, el rayo puede llegar
hasta 10 unidades de lejos, 100, 1000... Si quieres que el rayo sea infinito
escribesMathf.Infinity.

Por tanto quedara as:




Habrs visto que las variables estn DENTRO de Update, no fuera. Eso
sinceramente da igual, la nica diferencia es que si est fuera se puede
usar en cualquier funcin: en Update, en Start, en OnTrigger... Pero si la
variable se declara dentro de Update, solo se puede usar en Update. Si
intentas utilizarla en otra funcin te dir que la variable no existe.

Esta condicin que hemos puesto quiere decir que el cdigo se ejecutar
si detecta colisin. Pero no nos basta con eso, nosotros queremos que el
cubo se destruya si le pasamos el ratn por encima, as que ahora
tenemos que poner como condicin que la colisin sea con el cubo.

As que ahora, dentro de la condicin ponemos esto:

if ( rayo.transform.name == this.gameObject.name)

Traduzco.
rayo.transform.name significa: "el nombre del objeto que tocamos"
this.gameObject.name significa: "el nombre de este objeto"

Por tanto la condicin es:

Si el nombre del objeto que tocamos = al nombre de este objeto....

(El nombre de este objeto es el que lleva el script, si el script se lo pones
al cubo,this.gameObject.name ser igual a "cube")

Y luego dentro de esta condicin pones el Destroy:

Destroy (this.gameObject);

Y quedar algo como esto:



Ponle el script al cubo, dale a Play y prueba de pasar el ratn por encima
el cubo.

Y terminamos con el apartado de los rayos! Pero antes quiero hacer una
traduccin del cdigo que acabamos de hacer por si ayuda a entenderlo:

si (el rayo choca con algo)
si (y este algo es este objeto (el cubo) )
Destruye (este objeto)
}


7. GUI

La GUI es la interfaz, todo lo que sale en pantalla como imagen 2D, y que
no es un objeto del espacio 3D.

7.1 Texturas y Textos

Esta parte la dedicar a los GUITexture y GUIText que como ya sabes
puedes crearlos desde Unity (GameObject > Create other > GUI Texture
/ GUI Text).

Dado que estos son fciles de crear y configurar desde Unity me limitar
a explicar algunas aplicaciones en la programacin.

Ponindole un script a un GUI Texture o Text puedes cambiar cosas como
el tamao, color, posicin en pantalla... Primero de todo te ensear
como crear un script para cambiar cualquier propiedad de la Textura /
Texto.

Dentro de la funcin Update debes incluir esto:

Para GUI Texture: this.guiTexture + .propiedad
Para GUI Text: this.guiText + .propiedad

Con "propiedad" me refiero al parmetro de la textura o texto que
quieras cambiar, algunos parmetros de una textura son el color, el
tamao o la posicin en pantalla.

Pero el que usaremos nosotros, el ms til y ms comn ser el
pixelInset:

this.guiTexture.pixelInset

Te permite cambiar 4 parmetros: anchura, altura, posicin horizontal y
posicin vertical. Para ello lo igualamos a esto:

= Rect ( posicin X, posicin Y, ancho, alto);

As de simple, con el siguiente cdigo puedes cambiar la posicin y
grandaria de una imagen:


Ahora prueba a hacerlo, crea este script y pnselo a un GUI Texture,
luego cambia la X, Y por un nmero. Eso ser la posicin en pantalla. Ten
en cuenta que el punto 0, 0 es la esquina inferior izquierda de la pantalla,
a partir de ah cuanto mayor sea la X ms a la derecha estar. Y cuanto
mayor sea la Y ms arriba estar.

Luego en el apartado de posicionamiento te ensear como poner un GUI
en posiciones concretas de la pantalla.

Ahora te enseo sobre el GUI Text. Un GUI Text lo puedes posicionar
igual que la GUI Texture, solo que en vez de pixelInset es pixelOffset,
y en vez de Rect esVector2:



Como puedes ver esto es bastante fcil. Y ahora te enseo como cambiar
el texto de un GUI Text desde script, puede que te preguntes Para qu?,
si el texto ya lo puedes cambiar desde el inspector.

Pues hay variables, como la vida, la energa o la muncin que van
cambiando a lo largo del juego, entonces si creas un GUI Text para que
te lo muestre en pantalla (EJ: 100 HP), la vida no ser siempre 100, si te
baja la vida el texto tambin tiene que cambiar. Para esto en la funcin
Update escribes que el texto = HP, por tanto todo el rato, durante todo el
juego, el texto ser igual a la variable de la vida. Si la vida es 100, el text
ser 100, si la vida es 56, el text ser 56. Si ya lo tienes claro procedo a
explicarte el cdigo:

this.guiText.text // usas .text para seleccionar el texto del guiText.

= variable.ToString();

Igualarlo al nombre de la variable + .ToString()

.ToString() lo que hace es pasar el valor de numrico a texto, es decir,
HP (la variable de la vida) puede ser int o puede ser float, pero en todo
caso es un valor numrico, y tu ests intentando meter un valor numrico
en un texto, eso te dara error.

Al usar .ToString despues del nombre de la variable pasas el valor
numrico a carcteres (texto). Por tanto:

this.guiText.text = HP.ToString();
este texto = La variable HP

Prueba este script, supongo que a estas alturas ya sabr lo que hacer,
pero te lo explico. Adems de hacer que el texto que lleva este script
indique la variable HP, luego si pulsas espacio le resta 10 de vida.

Aprobecho para explicar que si quieres restar o sumar a una variable es:

variable += o -= cantidad -----------> HP += 20 (Vida + 20)

Le pones el script anterior a un GUI Text y compruebas que el texto de
convierte todo el rato en la variable HP, y si pulsas espacio la variable
cambia y el texto tambin.

7.2 Box y Buttons

Pues ahora entramos en el tema de los recuadros y los botones de Unity.

Como ya explique en el apartado 2, la funcin OnGUI sirve solo para
crear las imgenes de pantalla que tiene Unity, como son la GUI.Box o los
botones.

La GUI.Box es simplemente un recuadro. En muchos juegos cuando abres
el men te sale un recuadro en pantalla con varias opciones (continuar,
salir, video, sonido...). Pues la GUI.Box es un recuadro como ese. La
forma de crear un GUI.Box es esta:

(Esto dentro de la funcin OnGUI, no Update)

GUI.Box (Rect ( X, Y, ancho, alto), "Ttulo del recuadro");

Lo de "Ttulo" es lo que te sale escrito arriba-centro del recuadro, pero
esto es opcional, si no quieres que salga nada deja las comillas y no
pongas nada: ""

Y ahora los botones. Lo botones se crean como si fueran una condicin:

if (GUI.Button (Rect (X,Y,ancho,alto), "botn")){
//Lo que pasa si pulsas el botn.
}

Los botones son un cuadro, que hace un pequeo efecto si lo pulsas,
como muchos botones, y que dentro puede tener texto o una imagen:

if (GUI.Button (Rect (X,Y,ancho,alto), "texto"))

if (GUI.Button (Rect (X,Y,ancho,alto), imagen))

La imagen tiene que ser una variable tipo texture que hayas declarado
anteriormente:var imagen : Texture; y asignada en el inspector.

7.3 Posicionamiento

Pues ahora que ya sabes crear imgenes y textos en pantalla, recuadros
y botones, te voy a ensear como colocarlos adecuadamente en pantalla,
es decir, el medidor de la salud quieres que est siempre abajo en la
esquina.

Cuando pones una imagen en pantalla, si indicas las coordenadas con
nmeros (X = 200, Y = 150) te encontrars con un problema, y es que al
cambiar la resolucin de la pantalla el icono se habr movido o ni siquiera
saldr en pantalla.

Por tanto, para posicionar una imagen en la pantalla y que siempre se
encuentre en un punto determinado de la pantalla (como es la esquina
inferior derecha) gastaremos siempre que sea
posible Screen.width y Screen.height (Ancho de pantalla y Alto de
pantalla).

Por ejemplo, creas una GUI Texture, y le pones un script para que en
todo momento esa imagen est en el centro de la pantalla. Como quieres
que est en el centro exacto de la pantalla, mi pregunta es (e intenta
pensarlo) cules sern las coordenadas X, Y?

X = Screen.width / 2 es decir: X = al ancho de la pantalla / 2
Y = Screen.height / 2 es decir: Y = al alto de la pantalla / 2

Creo que esto es fcil de entender, si divides todo lo ancho que hace tu
pantalla por la mitad, te quedas justo en el medio de la pantalla (el
centro).


Puedes probar de crear un GUI Texture, y ponerle este script para
comprobar que la textura est siempre en el centro de la pantalla. Pero
una cosa muy importante: el OBJETO del GUI Texture debes ponerlo en
la posicin (0, 0, 0) desde el inspector. X = 0, Y = 0, Z = 0.

Si quieres experimentar, prueba de partir el ancho y alto de pantalla por
ms, entre cuatro, o entre diez, o entre quince, etc.

A partir de aqu tu puedes ir pensando como posicionar las imgenes en
la pantalla, te dejo algunos ejemplos para que vayas guindote.





1 Centro de la pantalla, ya lo hemos explicado:

Screen.width/2 = X , Screen.height/2 = Y

2 Esquina mxima inferior izquierda de la pantalla. Este es el punto 0,
0. Ah es donde empieza la pantalla, el punto origen (0,0).

3 Este es igual que el 2 solo que tiene toda la pantalla de alto, es decir,
se ha movido verticalmente, pero no horizonalmente. Sera:

X = 0 , Y = Screen.height

4 Este es el contrario del 3, toda la pantalla de ancho, pero nada de
alto:

X = Screen.width Y = 0

5 Este lo tiene todo, est al mximo de altura y ancho:

X = Screen.width Y = Screen.height

6, 7, 8, 9 Estas son esquinas visibles, es decir, no en la esquina exacta
de la pantalla, sino tocando, cerca de la esquina, pero lo que nosotros
entendemos por la esquina, que se acerca al borde de la pantalla pero no
toca. Aqu es donde pondramos los marcadores de vida, municin, etc.

Para entender lo que vamos a hacer debes entender una cosa: como ya
hemos hablado, si divides el ancho de la pantalla por la mitad, nos
quedamos en el medio de la pantalla. Y si lo dividimos entre tres? Pues
se queda a un poco menos de la mitad. Y entre 4? Pues se queda a un
cuarto (1/4) de la pantalla. Mralo aqu:


Como ves, cuanto ms divides el ancho de la pantalla, ms se acerca al
borde izquierdo de la pantalla, aunque cada vez la diferencia es ms
pequea.

Por tanto si quieres que un GUI est en la esquina izquierda, podras
dividir el ancho de pantalla entre... yo que s, diez! Prueba con 10. Y
para la altura es lo mismo, cuanto ms dividas ms se acerca al suelo, al
borde de abajo. Si quieres que est en la esquina inferior dividelo por
diez tambin, y si quieres que est en el borde superior dividelo por un
nmero entre 1 y 2, como 1.5.

Recuerdo que para que la imagen te salga en pantalla el objeto de la
escena debe estar en las coordenadas tridimensionales (0, 0, 0). Sino es
posible que la imagen no te salga en el sitio correcto o ni siquiera te salga
en pantalla.

Pues bueno, creo que si aun no te ha quedado claro algn detalle ahora
lo terminars de entender porque vamos a montar un men.

7.4 Montando un men

Pues ahora vamos a montar un pequeo men, algo simple. Vamos a
montar un recuadro GUI.Box con 3 botones dentro. Para los botones usa
la imagen que viene junto a este tutorial en la carpeta Assets > GUI >
Button.png

Empecemos. Abre un nuevo script javascript. Primero de todo crearemos
dos funciontes: function Update y function OnGUI.
Primero de todo vamos a declarar una variable boolean (true or false)
que nos diga si el men est en pantalla o no.

var activado : boolean = false;

La igualamos a false, para que cuando empieze el juego sea falso, es
decir, no hay men en pantalla. Ahora tanto dentro de la funcin Update
como OnGUI debemos poner como condicin, que el men aparezca si
esta activado:

if (activado == true) {

// Men

}

Hasta ahora tenemos esto:






Bien, ahora vamos a crear el recuadro, como ya sabes el GUI.Box debe ir
dentro de la funcin OnGUI, as que dentro de la condicin que hemos
puesto dentro de OnGUI, creamos un recuadro con estos parmetros:

GUI.Box (Rect ( Screen.width/2 - 100, Screen.height/2 - 150,
200, 300), "");

Te habrs fijado que a las posiciones (X,Y) les he restado
respectivamente 100 y 150. Les resto a la X la mitad del ancho (200 / 2 =
100 , 300 / 2 = 150), y mira ests imagenes para entender porque lo
hago:


El recuadro tiene su punto origen 0,0 en la esquina superior izquierda, es
decir, el recuadro empieza a crearse desde la esquina superior izquierda y
se va expandiendo, por tanto si no le restara la mitad del ancho y alto a
las coordenadas pasara lo que pasa en la imagen de la izquierda, que el
recuadro EMPIEZA en el centro de la pantalla, pero NO est en el centro
de la pantalla.

Para que est en el centro de la pantalla, debe moverse hacia la izquierda
justo la mitad de su ancho y hacia arriba la mitad de su altura, y
entonces queda como en la imagen de la derecha. La verdad me ha
costado bastante explicar esto porque no tena ni idea de como hacerlo,
as que si todava no lo has entendido solo acepta que cuando haces un
recuadro, para centrarlo debes restarle a las coordenadas X, Y las
mitades de su tamao.

Ahora procedemos a crear los botones, para eso primero crea en la
escena una GUI Texture, desde GameObject > Create other > GUI
Texture, y asgnale desde el inspector la textura que te he dicho antes, la
que viene con el tutorial en la carpeta Assets > GUI > Button.png.

A continuacin, en Project crea un "prefab" y ponle al prefab este GUI
Texture con Button.png. Una vez ya tengas el prefab borra la GUI
Texture de la escena.

Explicado en pasos:

1 Crea un GUI Texture.

2 Asgnale el Button.png.

3 Crea un prefab.

4 Mete la GUI Texture dentro del prefab.

5 Borra la GUI Texture.

Bien ahora volvamos al script. Creamos una nueva variable tipo
GameObject.

var boton : GameObject;

A esta variable le tienes que asignar desde el inspector el prefab que
acabas de crear.
De momento voy a hacer que el men se abra con la tecla Z y se cierre
con X, luego ya haremos que pase con el mismo botn. As que en la
funcin Update, DEBAJO de la condicin anterior creamos estas dos:

if (Input.GetKeyDown (KeyCode.Z)){
}
if (Input.GetKeyDown (KeyCode.X)){
}

Si te pierdes tranquilo que luego pongo la imagen del cdigo. Ahora
pensemos, qu pasa si pulsas Z? Que aparece el men. Qu pasa si
pulsas X? Que desaparece el men.

Empecemos con la Z. Si pulsas la Z:

1 la boolean activado = true;

2 Se crean los botones, para eso usaremos el comando Instantiate.
Creo que es la primera vez que te hablo de este comando. Sirve para
crear cualquier objeto, se usa as:

Instantiate ( variable , posicin , rotacin);
En "variable" va una variable tipo GameObject, la que hemos creado
antes.

En "posicin" la posicin donde aparecer el objeto. Recuerdo que ya dije
antes que en el caso de las GUI.Textures, si queremos que salgan
correctamente en pantalla debemos ponerlas en las coordenadas 0, 0, 0.
Que es lo mismo que Vector3.zero.

En rotacin la rotacin del objeto, pero al ser una imagen 2D esto nos da
igual, as que lo dejamos en transform.rotation (esto quiere decir que
tendr la misma rotacin que el objeto que lleva el script.

Nos queda as:

Instantiate ( boton , Vector3.zero, transform.position);

Y como queremos 3 botones lo pondremos 3 veces, quedando as:


Lo resumo: en OnGUI, si activado = true aparece el recuadro en pantalla.
En Update si pulsas Z, activado = true (y por tanto aparece el recuadro)
y se crean 3 botones.

Puedes probarlo si quieres, pnselo a cualquier objeto y asigna en el
inspector las variables. Lo pruebas y eso es todo lo que hace.

Ahora debes declarar tres variabls ms:

var boton1 : GameObject;
var boton2 : GameObject;
var boton3 : GameObject;

Y los igualas cada uno a un instantiate (se lo pones delante):

boton1 = Instantiate (boton, Vector3.zero, transform.position);
boton2 = Instantiate (boton, Vector3.zero, transform.position);
boton3 = Instantiate (boton, Vector3.zero, transform.position);

Cuando igualas un GameObject a un Instantiate, lo que ests diciendo es
que ese GameObject es el que se crea con Instantiate. En este caso ests
diciendo que el Boton1 es el que sea crea con Instantiate (boton,
Vector3.zero, transform.position);

Esto lo hacemos porque si luego queremos hacer referencia a esos tres
botones, por ejemplo queremos destruirlos para que desaparezcan de la
pantalla al cerrar el men, cmo los llamamos?

Destroy (???);

Qu pondramos aqu? Antes no podamos hacerlo, una vez creados no
podamos hacerles cambios porque no tenan nombre, ahora s, ahora
pondramos:

Destroy (boton1.gameObject);

Y eso es lo que vamos a hacer ahora. Dentro de la condicin de si pulsas
X, ponemos lo contrario a la Z. En la Z ponamos que activado = true, y
se creaban boton1, boton2 y boton3. Pues ahora en la X activado = false
y destruimos los botones:

activado = false;
Destroy (boton1.gameObject);
Destroy (boton1.gameObject);
Destroy (boton1.gameObject);

Alomejor te preguntas: por qu ponemos Destroy
(boton1.gameObject) y noDestroy (boton1) simplemente??

Muy fcil, si pones Destroy(boton1); lo que ests destruyendo es la
variable, y si pones Destroy(boton1.gameObject); lo que destruyes es el
OBJETO que lleva la variable.

El objeto que lleva la variable (que es la GUI Texture) la puedes borrar
tantas veces como quieras, pero la variable no la borres que la liamos!
Cada vez que pulsamos Z necesitamos la variable, pero si al cerrar el
men (pulsar X) borras la variable, luego cuando quieras volver a abrir el
men (pulses Z) te dar error porque la variable ya no existe. Entiendes,
no?



Con esto ya hacemos que el men aparezca al pulsar Z y que
desaparezca al pulsar X. Pero ahora falta poner los botones en buena
posicin.

Esto lo haremos dentro de la condicin de Update de si activado = true.


Dentro de esto pondremos:

Boton1.guiTexture.pixelInset = Rect( X, Y, ancho, alto);

Con esto seleccionamos la GUI Texture que hay en Boton1. Y le vamos a
cambiar la posicin y el tamao.

Cuando tenemos que crear, por ejemplo un botn que va dentro de un
recuadro, como es el caso, porque estos 3 botones que hemos creado
van dentro del recuadro del GUI Box, tenemos que poner su posicin
(x,y) en referencia a la del recuadro, porque si no lo que nos puede pasar
es que al cambiar la resolucin de la pantalla, el botn se salga de dentro
del recuadro.

La posicin X del recuadro es Screen.width/2 100.
Pues empezamos poniendole al boton la misma posicin.
X del botn = Screen.width/2 100

Ahora queremos que el boton est en este sitio:



As que lo debemos mover un poco a la derecha. Sabemos que el
recuadro tiene 200 de ancho y al botn vamos a ponerle de ancho....
150, por ejemplo. Piensa que el botn tiene que tener menos ancho que
el recuadro.

Si queremos centrarlo, tiene que sobrarle el mismo trozo por la izquierda
que por la derecha. Pensemos (que esto es ms que nada pensar). Si el
recuadro hace 200, y el boton 150, nos quedan libres 50. Si el boton
tiene que tener el mismo trozo por la izquierda que por la derecha son 25
a cada lado:



El que te dijo que las matemticas no eran necesarias para programar te
enga.

Como ves en la imagen, el recuadro tiene 200 de ancho, el boton 150, y
le sobra 25 por cada lado.

La conclusin que sacamos de esto es que el boton debe avanzar 25
unidades.

Por tanto la posicin X del boton ser la misma del recuadro + 25

X = Screen.width/2 100 + 25

Y ahora para la vertical lo mismo, solo que ahora debemos tener en
cuenta, que en el recuadro tienen que caber 3 botones, y que entre ellos
debe haber un espacio.

Por tanto, si el recuadro hace 300 de altura, hay 3 botones sera 100 de
altura cada uno, pero como debemos contar los espacios entre ellos un
poco menos de 100. Probemos con 75. Cada boton tendr 75 de altura.

75 x 3 = 225. 300-225 = Nos quedan libres 75. Cuntos espacios hay?
Uno del borde superior al primer boton, otro del pimer al segundo boton,
otro del segundo al tercer boton y otro del tercer boton al borde inferior,
eso son 4.
75 / 4 = 18,75. Cada espacio debe tener 18.75. Qu lo, no?

As que vamos ya a terminar con esto del men. De X todos los botones
deben tenerrecuadro + 25 -----> Screen.width/2 100 + 25

Y de posicin Y deben tener:

boton 1: altura recuadro + 18,75

boton 2: altura recuadro + 18,75 + boton1 + 18,75

boton 3: altura recuadro + 18,75 + boton1 + 18,75 + boton 2 + 18,75






Como resultado final quedar esto:

Boton1.guiTexture.pixelInset = Rect( Screen.width - 75, Screen.height/2
141,25 , 150, 75);

X = Screen.width/2 -100 + 25 = Screen.width/2 -75

Y = Recuadro 18,75 = Screen.height/2 150 + 18,75

Boton2.guiTexture.pixelInset = Rect( Screen.width - 75, Screen.height/2
47.5 , 150, 75);

Boton3.guiTexture.pixelInset = Rect( Screen.width - 75, Screen.height/2
+ 46.25 , 150, 75);

Como ves lo nico que cambia es la Y, porque los botones estn siempre
en el mismo sitio solo que cada botn ms arriba o abajo que los otros.

Bien ahora te enseo el script final, lo pruebas, y ya podemos empezar a
hacer nustro juego!



Pon este script donde quieras, asgnale las variables necesarias (la de
"boton" en la cul debes poner el prefab) y dale al play. Pulsa Z para ver
como aparece el men y X para ver como desaparece.

Aun me quedaran muchas cosas para explicar como hacer aparecer y
desaparecer el men con el mismo botn, hacer que pase algo al pulsar
los botones, o el hecho de que si pulsas varias veces Z se crea muchas
veces el men... pero para no liar ms las cosas explicar todo esto
cuando hagamos el men del juego. De momento lo bsico que es crear
GUI y posicionarlos ya lo sabes.



8. Empezemos nuestro juego!



8.1 Controller Simple



Pues empezemos! Despus de todo lo que te he explicado espero que
puedas seguir la creacin de nuestro juego e intentar explicarlo lo mejor
y ms simple que pueda aunque reconozco que hay cosas que me cuesta
explicar.



Vamos a hacer un juego sencillo de una nave que tu vas a controlar y
que debe esquivar meteoritos y disparar a los enemigos. Yo solo te voy a
ensear a hacer un nivel, el sistema del juego y el men, es decir, no
vamos aqu a montar todos los niveles del juego y dejarlo listo para
entrega, eso ya luego si tu quieres hacer terminas el juego y le aades
todo lo que tu quieras.



Primero de todo necesitaremos el modelo de una nave, puedes usar el
que quieras, yo me he descargado este:

http://thefree3dmodels.com/stuff/aircraft/shuttle/15-1-0-3353


Una vez tengas todo inicias un nuevo proyecto, o si ya tenas uno
empezado te sitas en ese. Creas una nueva escena. Siempre que crees
una nueva escena, antes de empezar te aconsejo asegurarte de varias
cosas:

1 La luz: GameObject > Create other > Directional Light

2 El Skybox: Edit > Render Settings y en el inspector, en Skybox,
seleccionas un skybox.

Para los que no sepan lo que es el Skybox es simplemente el cielo. El
cielo en nuestra pantalla. Del cuadro que te saldr busca algun cielo azul
normal, ve probando.

3 Mapa: en este caso no crearemos mapa porque las naves se mueven
en el espacio pero si quisieras un terreno: Terrain > create terrain. Y a
continuacin deberas aplicarle al mapa la grandaria deseada (en Terrain
> set resolution) y la textura que quieras para el mapa (en el inspector).

Y ya que vamos a hacer un juego del espacio te recomiendo usar este
Skybox:
https://www.assetstore.unity3d.com/#/content/3392
Lo puedes descargar gratuitamente desde la asset store de Unity, solo
debes estar registrado en la pgina, que es gratis tambin. Lo descargas
desde Unity y le das a import.
Ahora desde Edit > Render Settings, seleccionas Skybox y el asset
importado lleva el nombre de "DSGWP", lo seleccionas en el cuadro de
los skybox.

Bien! Si ya tienes una escena con luz y cielo vamos a importar la nave.
Importa el modelo de la nave en una carpeta tuya propia en Project y
metela en la escena. Te aconsejo poner la nave en la escena, asignarle la
textura y el tamao deseado, y entonces crear un prefab, as metes la
nave ya preparada dentro del prefab y cada vez que quieras situar una
nave en la escena no tendrs que volver a seguir todos los pasos, valdr
con arrastrar.

Si ya tienes el skybox puesto y la nave en su sitio deberas tener algo
como esto:



















Ahora procederemos a hacer que la cmara siga a la nave de un modo
muy sencillo y sin necesidad de programar: en hierachy arrastra la
cmara (Main Camera) hasta la nave, de manera que la camara sea un
sub-objeto de nave.

Al hacer esto la posicin de la cmara ser relativa a la de la nave, es
decir, que si tu en el inspector, en position, en X pones 50, la cmara
estar horizontalmente a una distancia de 50 unidades de la nave, eso
significa que la nave es el punto origen, el centro de la cmara, el punto
(0,0,0). Ahora nosotros queremos que la cmara est justo detrs de la
nave, para que nos la muestre en todo momento del juego desde atrs.
Para ello, una vez la cmara es un sub-objeto de la nave, la
seleccionamos (la cmara) y en el inspector, en position ponemos 0 para
la X, 0 para la Y, 0 para la Z, es decir la situamos en el (0,0,0).

Normalmente al hacer esto la cmara se situar en el mismo sitio que la
nave, es decir tendrs la cmara DENTRO de la nave. Esto no es siempre
as, depende del modelo que uses, pero normalmente si situas un sub-
objeto en el punto (0,0,0) se sita dentro del propio objeto.

Ahora bien, no queremos la cmara dentro de la nave, sino detrs, as
que simplemente seleccionas la cmara y la mueves hacia atrs, y luego
la rotas un poco hacia abajo para sealar la nave. Te aseguras que en la
pantalla del juego se vea la nave por atrs, as:



















De este modo tan simple, si la nave se mueve, la cmara tambin se
mover con ella, porque al estar la cmara dentro del objeto "nave" se
les aplican las mismas transformaciones, esto significa que si mueves
nave, mueves cmara, si haces ms grande la nave, haces ms grande la
cmara, si borras la nave, borras la cmara, etc.

Posiblemente, hechara la cmara un poco ms atrs, la he puesto
demasiado cerca, eso ya a tu gusto.

Pues ahora s que llega la hora de programar. Ya teniendo nuestro nivel y
nuestro player creado lo que necesitamos es que se mueva! Bien,
haremos que la nave por si sola se mueva hacia delante constantemente,
nosotros lo que hacemos es dirigirla de lado a lado y de arriba abajo.



Antes de empezar a programar quiero recordar que cualquier duda que
tengas sobre los comandos en Unity los puedes consultar en cualquier
momento en Unity Script Reference, el diccionario de la librera de Unity:
http://docs.unity3d.com/Documentation/ScriptReference/

Primero de todo creamos un nuevo script. En este script ponemos la
funcion Update:

function Update() {
}

Y ahora dentro de esta funcin ponemos el comando que mueva la nave
hacia delante. El comando para mover es este:

(objeto).transform.Translate (Vector3 * Time.deltaTime);

Objeto es el objeto que se tiene que mover, si es el propio objeto que
lleva el script el que tenemos que mover no es necesario poner nada.
Dentro de los parmetros de transform.Transalte debemos poner
el Vector, es decir, la direccin en que se mueve.

Un ejemplo sera: Vector3(1, 0, 0), es decir, solo se movera en el eje X,
horizontalmente. Y si pones Vector3(0, 1, 0) en el eje Y verticalmente.
Por suerte Unity ya viene con unos vectores predeterminados, hacia
delante es:

Vector3.forward

Y luego lo de Time.deltaTime significa a velocidad de uno por segundo:

Time.deltaTime = 1 por segundo 2*Time.deltaTime = 2 por segundo

3*Time.deltaTime = 3 por segundo 4*Time.deltaTime = 4 por segundo

Entonces la traduccin literal sera:

transform.Translate (Vector3.forward * Time.deltaTime);

= mover objeto hacia delante a una velocidad de 1 por segundo.


El problema que he tenido yo es que a uno por segundo no se nota el
movimiento porque va muy lento, as que yo lo he puesto a 200 por
segundo, de tal forma que quedara as:

transform.Translate (Vector3.forward * 200 *Time.deltaTime);

Si ya lo tienes as, guarda el script y arrstralo hasta la nave. Ahora dale
a jugar.
Lo que te puede pasar es que tu no veas moverse la nave, Por qu?
Porque la nave es el nico objeto en la escena: nosotros notamos el
movimiento de un objeto en referencia a los dems objetos de su
alrededor, es decir, notamos cuando algo se mueve porque todo lo
dems est quieto, pero es que no hay nada en la escena, nada a lo que
la nave se acerce o se aleje. As que para que veas como se mueve la
nave vamos a meter otros objetos en la escena. Ya que ms tarde
tendramos que poner meteoritos, los ponemos ahora. Yo he usado este
modelo:
http://www.turbosquid.com/3d-models/asteroid-space-planet-3ds-
free/616773

Turbosquid es una buena pgina para encontrar modelos para tus juegos
gratis, te la recomiendo. Pero debes registrarte para descargar cualquier
cosa.

Bien, voy a situar unos cuntos meteoritos alrededor de la nave:





















Si, como yo te ha pasado que no te aparecan los meteoritos en pantalla
hasta que te acercaban, es que tienes que agrandar el rango de la
cmara, la seleccionas, y en el inspector > Far, lo aumentas. Yo lo tengo
en 10.000

Y ahora pasaremos a algo importante, que la nave choque con el
meteorito. Cuando importas modelos querrs que la mayora de ellos
puedan chocar con la resta de objetos, y que su colisin tenga su misma
forma, para ello le debes poner al modelo recin importado un mesh
collider. Pero atiende, lee bien esto que es IMPORTANTE.

Muchas veces cuando importas modelos y los metes en la escena, lo que
tu tienes (lo puedes ver en la pestaa hierachy) es un objeto principal
con otros objetos dentro. Hay modelos que te vienen de una sola pieza,
pero en cambio hay otros que vienen a partes. Por ejemplo, te descargas
un modelo de Supermn, lo pones en Unity, y luego en Hierachy tu tienes
un objeto llamado "Supermn", pero dentro de este tienes otro llamado
"Cabeza", y es la parte de la cabeza. Otro llamado "Brazos", y son los
brazos, etc.

Cuando tu le pones un Mesh Collider a un modelo importado, se lo debes
poner siempre y solamente a los sub objetos, es decir, a "cabeza", a
"brazos", pero no a Supermn, del contrario no funcionar.

Pero vamos a aplicarlo a nuestro juego y lo entenders mejor. Si ests
usando la misma nave que yo, por ejemplo, cuando sito la nave en la
escena tengo un objeto llamado "Shuttle", y dentro de este tengo otro
objeto llamado "LOD0".

"LOD0" es el modelo, es la "malla", por lo tanto es a este al que le tienes
que aplicar el Mesh Collider, no al primer objeto, Shuttle.

Pues vamos a hacerlo, seleccionalos LOD0 y luego a Component >
Physics > Mesh Collider.

Luego abra que hacer lo mismo con el meteorito, pero lo he comprobado
y no s porque el Mesh Collider del meteorito no funciona bien, la nave lo
atraviesa, no importa. Como el meteorito tiene una forma ms o menos
circular podemos usar un Sphere Collider, as que seleccionamos el
meteorito y Component > Physics > Sphere Collider.

Y si ya has puesto collider tanto a la nave como al meteorito ahora
deberan chocar, vamos a comprobarlo. Mueve uno de los meteoritos y
ponlo en la trayectoria de la nave:


















Pues volvamos a la programacin. Ahora deberamos hacer que puedas
esquivar las rocas. Para ello debers poder moverte de arriba abajo y de
lado a lado. Vamos al script que habamos hecho anteriormente. Debajo
de lo que tenamos antes: transform.Translate, vamos a escribir que si
pulsas las teclas correctas la nave se mueve. Empezemos con ir hacia
arriba, debemos escribir esto: "si tecleas W o flecha arriba, la nave se
mueve". Vamos a ello. Primero la condicin:

if (Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.UpArrow)){
}


A ver, el Input.GetKey ya est explicado anteriormente. Si lo quieres
revisar est en el apartado 4: Nuestro primer cdigo, el operador ||
tambin est explicado, significa "o":

Si pulsas W O pulsas flecha arriba = la nave se mueve.

Ahora dentro de esa condicin ponemos el comando de movimiento:

transform.Translate (Vector3.up * 200 * Time.deltaTime);

Luego solo tienes que copiar tres veces ms este cdigo cambiando el
"arriba" por "abajo", por "izquierda", y por "derecha". As quedara:

if(Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.UpArrow)){
transform.Translate(Vector3.up * 200 * Time.deltaTime);
}
if(Input.GetKey (KeyCode.S) || Input.GetKey (KeyCode.DownArrow)){
transform.Translate(Vector3.down * 200 * Time.deltaTime);
}
if(Input.GetKey (KeyCode.A) || Input.GetKey (KeyCode.LeftArrow)){
transform.Translate(Vector3.left * 200 * Time.deltaTime);
}
if(Input.GetKey (KeyCode.D) || Input.GetKey (KeyCode.RightArrow)){
transform.Translate(Vector3.right * 200 * Time.deltaTime);
}


El problema que tenemos ahora es que si tu pulsas mucho rato hacia
arriba, por ejemplo, te vas, te vas, te vas, y te apartas de la pantalla.
Quiero decir, no vas a llenar toda la escena de meteoritos, no terminaras
nunca... Por eso, creamos solo un "conducto", un recorrido que hace la
nave, de modo lineal. Entonces no nos interesa que el jugador se vaya
demasiado hacia arriba, hacia abajo o hacia los lados, queremos que la
nave se mantenga dentro del espacio.

Esto lo podemos conseguir de una forma muy sencilla. Creamos dos
variables (hori y vert) tipo float, y que al inicio son 0:

var hori : float = 0; var vert : float = 0;

Digamos que la posicin central de la pantalla para la nave es 0, puedes
subir hasta 5 o bajar hasta -5. Para ello vamos a la condicin de pulsar W
y ponemos dentro otra condicin que sea:

if (vert < 5)

Y en la condicin de pulsar S:

if(vert > -5)

quedando as:

if(Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.UpArrow)){
if (vert < 5){
transform.Translate(Vector3.up * 200 * Time.deltaTime);
}
}
if(Input.GetKey (KeyCode.S) || Input.GetKey (KeyCode.DownArrow)){
if (vert > -5){
transform.Translate(Vector3.down * 200 * Time.deltaTime);
}
}


Tambin puedes combinar los dos if de la seguiente forma:


if( (Input.GetKey (KeyCode.S) || Input.GetKey (KeyCode.DownArrow))
&& vert > -5)

Traduccin: si ( (pulsas S o Abajo) Y (vert es mayor que -5) )



Y haces lo mismo con las condiciones de los movimientos laterales. Luego
pondr una imagen del script cuando lo terminemos.

Ahora debemos hacer que si vas hacia arriba, la variable vert aumente,
para que cuando llegue a 5 no te deje subir ms. Porque hemos puesto la
condicin de que para poder moverte hacia arriba, vert tiene que ser
menor que 5.

Entonces vert ir aumentando a medida que subimos hasta llegar a 5, y
no te dejar subir ms. Dentro de lo que pasa si pulsas W tenemos:

transform.Translate(Vector3.up * 200 * Time.deltaTime);

Pues debajo de esto pones otra lnia que ponga:

vert += Time.deltaTime;

Con esto le sumas a vert 1 unidad por segundo. Eso significa que si
pulsas W durante un segundo, vert = 1, si pulsas durante 2 segundos,
vert = 2, si pulsas durante 1.5 seg, vert = 1.5 seg.

Y en el resto pones:

hacia abajo: vert -= Time.deltaTime;

hacia izquierda: hori -= Time.deltaTime;

hacia derecha: hori += Time.deltaTime;

Importante: para poder sumarle a una variable uno por segundo (+=
Time.deltaTime) la variable debe ser tipo float, no integuer, porque
sumarle uno por segundo significa que si mantienes la tecla pulsada
durante 0.372 seg, le sumas a la variable 0.372. No es que cada segundo
le suma uno, sino que le suma CONTNUAMENTE mientas pulsas, y eso
incluye decimales. Lo digo porque si alguna vez te da error asegrate de
que no pusiste tipo int.

Pues aqu dejo la imagen del script final:
























Lo que pasa es que cinco segundo es demasiado, yo he decidido
cambiarlo a 2. Esto ya depende de lo ancho y alto que tenga el recorrido
que hace la nave.

Pues creo que ya va siendo hora de terminar con el apartado del
Controller, ya podemos controlar nuestra nave. Solo una ltima cosa.

En la velocidad a la que se mueve la nave yo tengo puesto 200. En vez
de usar un nmero vamos a cambiarlo por una variable.

Crea otra variable llamada "velo" tipo float o int como quieras, si la haces
float podrs ajustar con ms exactitud la velocidad. Pero solo creala, no
le asignes ningn valor.

Ahora cambia todos los 200 por velo. Si seleccionas la nave en la escena,
ahora en el inspector, en el script te sale la variable velo, y le puedes
poner el valor que quieras. Ponle un poco ms rpido, yo le pondr 500.
La ventaja de usar una variable para la velocidad es que luego puedes
crear objetos que aumenten la velocidad de la nave, o que cuanto ms
avanzas ms rpido se mueve la nave. Por eso se llama "variable",
porque puedes variar su valor a lo largo del juego como te interese.

8.2 Vida y energa

Este apartado ser largo. Aqu te ensear a ponerle vida y energa a tu nave, a mostrarlo en pantalla, con
barras y tambin con nmeros. Y adems como la energa se tiene que gastar de alguna forma, haremos que
la nave dispare.

Primero de todo creamos un script que se llame como tu quieras, yo lo llamar... HP. En Hp crearemos dos
variables: vida y energa, tipo float que en inicio sern 100.

var vida : float = 100; var energa : float = 100;

Ahora deberamos hacer que nos salga en pantalla. Hay varias formas de hacerlo, la que he usado yo es la
siguiente. Con estas texturas:










Esto funciona as: las barras llenas van encima de las vacas. La longitud de las llenas depende de la salud y la
energa. Si la vida baja, la barra roja se empieza a hacer ms estrecha y se ver como resultado el blanco de
abajo, haciendo el efecto de una barra de vida que se agota, ya vers.

Puedes cogerlas con guardar como. Lo que he hecho es crear 4 GUI Textures con estas texturas. Las he
puesto todas dentro de un objeto vaco, llmalo como quieras EJ: "GUI Bars". Y le he aplicado a este objeto
vaco, un script que te voy a explicar ahora.

En primer lugar debemos hacer que estas barras se coloquen en la posicin que queremos con el tamao que
queremos. Si has creado las GUI textures te deberan salir en pantalla, para que no te molesten simplemente
el objeto vaco (GUI Bars) muevelo hacia un lado y las texturas desaparecern de la pantalla. Tranquilo que en
el juego te saldrn en pantalla, pero mientras no hace falta.

As que creamos un nuevo script, ponle un nombre. Debemos crear las variables de las barras, as que crea
cuatro variables tipo GameObject:

HPbar : GameObject;
HPback : GameObject;
SPbar : GameObject;
SPback : GameObject;

Luego en el inspector le asignas en HPbar la barra roja entera desde Hierarchy, y en HPback la barra roja con
el espacio blanco. Lo mismo con SP y la barra azul.

Ahora nos vamos a la funcin Update y usamos el siguiente comando:

HPbar.guiTexture.pixelInset = Rect( x, y, ancho, alto);

A ver, lo primero es el nombre del objeto al que te refieres. HPbar es la barra de la salud, la variable que
hemos creado anteriormente. Si te quisieras referir al propio objeto que lleva el script sera this.gameObject.
Luego, con guiTexture nos referimos a la guiTexture que contiene ese objeto. Nosotros hemos asignado al
objeto HPbar el objeto que hemos creado, y dentro de ese objeto hay una GUI Texture, donde se encuentra la
textura, la imagen de la barra. A continuacin, con pixelInset hablamos de las coordenadas y tamao de la
textura. La traduccin sera:

el tamao y posicin de la textura que contiene este objeto es =

Y ahora le asignamos una posicin y tamao. X, Y son las coordenadas de la pantalla. Qu coordenadas? Esto
siempre, cuando vayas a hacer cualquier juego debes pensarlo segn la lgica. Considera que el punto origen,
las coordenadas (0,0) estn en la esquina inferior izquierda. Yo, en mi caso, he colocado las barras arriba a la
izquierda, esquina superior izquierda. Para eso, primero vamos a la X. La barra no tiene que estar tocando al
borde de la pantalla, no la queremos tocando el margen, sino que la queremos un poco separada. Creo que de
esto ya expliqu un poco en el apartado de los GUI. En resumen, si queremos que la barra este cerca del
borde izquierdo, pero no tocando, basta con ponerle un cierta distancia. Por ejemplo, 50. Ahora en la Y, si le
pusieramos 50 estara cerca de la base, de la parte inferior de la pantalla, y hemos dicho que queremos la
barra arriba. Entonces hacemos lo siguiente: la colocamos en: altura de la pantalla 50. Esto se escribe as:

Screen.height 50 es decir, a 50 unidades de la parte superior.

Y las coordenadas estn listas, ahora vamos con el tamao, esto lo puedes modificar a tu gusto. Yo le he
puesto ancho 200, alto 25. Tal que queda as:

HPbar.guiTexture.pixelInset = Rect (50, Screen.height -50, 200, 25);

Bien, con esto hemos configurado el tamao y posicin de la imagen, pero no del objeto que la contiene, el
HPbar que tenemos en Hierarchy, el que has arrastrado al script. Para que la imagen se vea en pantalla ese
objeto debe estar colocado en X=0 y Y=0. Si te acuerdas antes te he hecho moverlo, para que no saliera la
textura en pantalla y no moleste. Ahora, con el script, vamos a hacer que mientras juegas, aparezca en esa
posicin, no tienes que moverlo. Para ello, vamos a crear otra lnia con esto:

HPbar.transform.position = Vector3(0,0,1);

Con esto indicamos que la posicion del objeto HPbar es 0,0,1. Por qu ese 1? Muy sencillo, en cuestin de
texturas, si alguna vez tienes que poner una textura encima de otra, dos texturas en la misma posicin pero
una debe estar por encima de otra, como lo indicas? Con la Z. La posicin Z indica que imgenes estn por
delante de otras. Una textura con Z = 2 est en una capa superior a otra con Z = 1.

En este caso le he puesto Z = 1 porque la HPback la estar en la misma posicin que HPbar, pero quiero que
HPbar est por encima. Y ahora estas mismas lnias que acabamos de hacer, las copiamos y cambiamos HPbar
por HPback. As tendremos en la misma posicin las dos barras rojas. Pero cmbiale en el Vector3 en 1 por 0:
Vector3 (0,0,0) que es lo mismo que poner Vector3.zero.

Con SPbar y SPback lo mismo, copia las lnias, solo que debemos desplazarlos horizontalmente, para que estn
un poco ms a la derecha. Si queremos que haya entre las dos barras un espacio de por ejemplo, 50
unidades, la posicin X que debemos poner es: los 50 que le pusimos a la otra barra, + el ancho de la barra +
otros 50 de espacio entre las dos barras. Te hago un apao grfico, para que lo veas:

|
| 50 200 50
|-------HPbarrabarrabarrabarra-------SPbarrabarrabarrabarra
|
As que seran 50 + 200 + 50 = 300;

En la X se las barras SP le pones 300;

Te debera quedar as:

HPback.transform.position = Vector3.zero;
HPback.guiTexture.pixelInset = Rect (50, Screen.height -50, 200, 25);
HPbar.transform.position = Vector3(0,0,1);
HPbar.guiTexture.pixelInset = Rect (50, Screen.height -50, 200, 25);
SPback.transform.position = Vector3.zero;
SPback.guiTexture.pixelInset = Rect (300, Screen.height -50, 200, 25);
SPbar.transform.position = Vector3(0,0,1);
SPbar.guiTexture.pixelInset = Rect (300, Screen.height -50, 200, 25);


Y una vez situada la barra tendremos que empezar con que las barras muestren la vida y la energa.

Bien primero accedemos al otro script, en el cul estn las variable vida y energa, y pondremos delante de
"var" la palabra "static" de manera que quede as:

static var vida : float = 100;

Con esto haremos que podamos acceder a la variable desde otros scripts. As que volvemos al script de las
barras, y cambiaremos el ancho de HPbar y SPbar por " 2 * HP.vida".

Ves que para referirme a la variable "vida", que se encuentra en otro script (HP) basta con poner el nombre
del script + punto + nombre variable: HP.vida.

Y lo de multiplicarlo por 2, muy sencillo: vida es una variable que vale 100, mximo 100. Pero en canvio, la
barra de la vida mide 200. Haces una simple regla de tres:

100 = x Donde X es la vida que tengas en cualquier momento.
200 = y Y es la longitud de la barra en ese momento.

100y = 200x ----> y = 2x longitud es igual a vida por dos.

Creo que esto es fcil. Pues ya est, si cambias el 200 de HPbar por 2*HP.vida tendra que funcionar. Lo que
pasa es que tu no notars la diferencia porque como la vida no vara. Vamos a hacer que la vida baje cinco
unidades por segundo, para verlo. En el script HP donde tienes las variables de vida y energa inicia la funcin
Update y en ella escribe:

vida -= 5 * Time.deltaTime; // vida 5 por segundo.

Aqu no hace falta que escribas delante el nombre del script (HP.vida) porque ya ests en el propio script que
las contiene. Ahora si guardamos y le damos al play deberamos ver como la vida baja, viendo como la barra
va bajando. Pero si te esperas vers que la vida llega a 0, y la barra sigue bajando, y bajando y se sale de la
propia barra, eso es porque no le has puesto lmite, y cuando llega la vida a 0, sigue bajando, a -5, -10, -15...

Puedes solucionar esto de varias formas:

Poniendo una condicin que solo baje la vida si es mayor que 0:

if (vida > 0){
vida -= 5*Time.deltaTime;
}

Indicando que la vida = 0 si es menor que 0:

if (vida <= 0){
vida = 0;
}

As en el momento que se convierta en menor que 0 o menor (-0.00001) al instante se convertir en 0 y no lo
dejar bajar.

Bueno eso ya es cosa tuya que vayas jugando con los valores.

Ahora vamos a quitar lo de bajar la vida, qutalo, y vamos a hacer que cuando disparas la energa baje.

Crea un nuevo script llamado disparar. Ms tarde haremos que la nave dispare un proyectil, pero de momento
solo vamos a hacer que la energa baje si pulsas la tecla de disparar.

Iniciamos la funcin Update y dentro creamos una condicion: si pulsas espacio la energa baja:

if (Input.GetKeyDown (KeyCode.space)){
HP.energa -= 5;
}

Guarda y sal. Si lo pruebas debera funcionar, pero otra vez si pulsas demasiado espacio la energa baja ms
de lo que debera tener permitido. Puedes cambiarlo o bien creando en el script HP que si energa <= 0,
energa = 0, as no bajar nunca, o en este condicin, aadir que energa debe ser mayor que 0, pero prefiero
la primera forma.

Dirgete al script HP y pon esto tanto para vida como para energa:

if ( vida <=0){
vida =0;
}
if( vida >= 100){
vida = 100;
}

Haz lo mismo con vida y otra vez cambiando vida por energa. Con esto nos aseguramos que vida y energa
nunca bajen ms de 0 ni superen 100. Ahora si pruebas el juego y disaparas debera funcionar correctamente.
Vamos a hacer ahora que la energa se recupere.

En HP pon esta lnia: energa += 3*Time.deltaTime;

Guarda, prueba el juego y vers que la energa sube, despus de gastarla. Si quieres que suba ms rpida o
ms lenta eso ya es cosa tuya, solo cambia el 3 por otro valor. Ahora vamos a crear un proyectil que salga de
la nave disparado hacia delante. Recuerdo que el proyectil luego tu puedes mejorarlo personalmente o hacer
otro distinto, yo crear uno bsico.

Crea en Project un nuevo prefab, llmalo como quieras, luego crea una esfera. La esfera por s es muy poca
cosa. Casi no se ver y tampoco es muy impresionante. En nuestro caso vamos a mejorarlo simplemente
poniendo una luz. Creamos un point light, que podemos encontrar en GameObject > Create other > point
light. Sitas en hierarchy, la luz creada dentro de la esfera, como un sub objeto.

Ahora asegrate que la luz est en su posicin 0, 0, 0, es decir, en el centro de la esfera. Ahora ya es opcin
tuya hacer que la esfera se vea o no. Puedes hacer que el proyectil se vea como una esfera luminosa o como
un luz sin ms. En mi caso he hecho que la esfera no se vea, pero est ah. Para eso basta con seleccionar la
esfera y en el inspector desactivar la opcin de "Mesh Renderer".

Tras hacerlo queda algo como esto:




Bien, una ltima cosa, selecciona la esfera y en el inspector activa la condicin de "Is Trigger". Esto es para
que la esfera sea atravesable.

En un principio intent hacer el proyectil sin activar esa opcin y lo que me pas es que al disparar el proyectil,
como este sale desde la nave, colisionaba con ella. Adems ms tarde necesitaremos tener activada la opcin
para detectar la entrada de las rocas, ya lo veremos.

Una vez activada la opcin, mete el conjunto de esfera + luz en el prefab. Ahora vamos a hacer que la nave
dispare. Esto hazlo dentro del mismo script que controla la nave, el que hicimos (en mi caso se llama
"contnave"). Dentro de la funcin Update, y dentro de sta, ponemos como condicin pulsar la tecla de
disparar, yo he elegido espacio. La condicin sera as:

if (Input.GetKeyDown (KeyCode.space)){

Y si quieres por ejemplo el botn izquierdo del ratn:

if (Input.GetKeyDown (KeyCode.Mouse0){

Puedes encontrar una lista de teclas aqu:

http://docs.unity3d.com/Documentation/ScriptReference/KeyCode.html

Dentro de esta condicin crearemos el comando de Instanciar (crear) la bala:

Instantiate = (bala_prefab, transform.position, transform.rotation);

Claramente para esto debes crear, antes de la funcin Update, una variable tipo GameObject, llamada
"bala_prefab":

var bala_prefab : GameObject;

Adems, queremos que cuando dispares te baje la energa, no? Pues debajo del Instantiate ponemos que la
variable "energa" en el script HP baje:

HP.energia -= 20;

La cantidad es cosa tuya, elije cunto quieres que baje la energa por disparo.

Y arrastras, desde Project, el prefab que hemos creado hasta la variable en el inspector. Quedando todo as:

var bala_prefab : GameObject;

function Update(){
// Controllador de la nave
if (Input.GetKeyDown (KeyCode.space)){
Instantiate (bala_prefab, transform.position, transform.rotation);
HP.energia -= 20;
}
}

Y listo, con esto disparas, pero... la bala no se mueve, porque no hemos hecho que se mueva. Crea otro
script, llmalo... "mov_bala". En el haremos dos cosas: que la bala se mueva hacia delante, y que si en X
tiempo no choca con nada se destruya. Para ello, iniciamos la funcin Update, y le ponemos el mismo
comando que a la nave:

transform.Transalte (Vector3.forward * X * Time.deltaTime);

En X ira la velocidad de la bala hacia delante. Aqu tienes que pensar un poco: no puedes hacer que la bala
vaya ms lenta que la nave, porque entonces disparas y la bala se quedar atrs. No puedes hacer que la bala
vaya a la misma velocidad que la nave, porque entonces la bala no llegar a los objetos que tienes en frente,
sino que se mover con la nave. As que la velocidad tiene que ser mayor.

Aunque tambin podras hacer algo: es posible que a lo largo del juego nos interese variar la velocidad de la
nave, en ese caso tambin debera variar la velocidad de la bala, lgico. Pues para eso podras convertir la
variable velo de la nave en "static var", porque as puedes acceder a ella desde el nuevo script: "mov_bala".
Recuerdo que cuando conviertes una variable a static puedes acceder a ella desde otros script.

Y en la X colocas esa variable velo + una cierta cantidad:

transform.Transalte(Vector3.forward * (contnave.velo+300) * Time.deltaTime);

Pero ahora surge otro problema, esto no te lo he explicado. Cuando conviertes una variable a static var hay el
problema de que ya no te sale esa variable en el inspector. Anteriormente, para definir la velocidad que
queramos que tuviese la nave te dirigas al inspector, variable velo, y le asignabas un valor, lo escribas. Pues
ahora no es tan fcil, cuando conviertes una variable en static ya no aparece en el inspector, y por tanto ya no
le puedes asignar la velocidad. Como solucionamos esto? De una forma muy sencilla. En el mismo script
donde se encuentra velo, creas otra variable que no sea static, del mismo tipo, que se llame por ejemplo
"local_velo":

static var velo : float;
var local_velo : float;

Y en la funcin Update indicas que (velo = local_velo). Como local_velo no es static s que aparece en el
inspector, y si le puedes asignar manualmente un valor. Te recuerdo que la funcin Update sucede
continuamente a lo largo de toda la pantalla. Por tanto, velo, que es static, ser todo el rato igual a local_velo.

Si le ponemos 500 a local_velo, velo es tambin 500. De esta forma, le asignamos a una variable static el valor
que queremos desde el inspector. Entonces lo nico que tienes que escribir es:

velo = local_velo;

Y todo listo. Guarda, ejecuta, y al pulsar espacio debera aparecer una bala disparada hacia delante. El script
"mov_bala" resultante sera as:




gl_velo es la variable velo, solo que yo la llamo as.

Este script debes ponrselo al prefab de la bala, del proyectil que hayas hecho. Y en el script de disparar que
es el mismo controlador de la nave, en el inspector, debes arrastrar el prefab del proyectil hasta la variable
bala_prefab.

Bueno que con esto terminamos este apartado. Ya tenemos una nave con vida y energa que se gasta al
disparar, ahora vamos a por los peligros!


8.3 Peligros

A ver, esto es muy sencillo. Tenamos unos cuantos meteoritos en la escena verdad? Pues ahora vamos a
hacer que si chocas con ellos te quitan vida. As de momento el juego consistir en una nave que avanza
automticamente sin cesar y que debe esquivar las rocas para sobrevivir.

Creo que ya tenas unas rocas en la escena. Bien, escoge una y borra todas las dems. Ahora con la roca que
tienes, que llevaba un spherer collider que le pusimos anteriormente. Activa el trigger (seleccionas la roca >
inspector > Sphere Collider > Trigger).

Ahora con esto, la nave atraviesa las rocas, y vamos a hacer que si colisionas con una roca, la vida te baja.
Para esto creamos un script, muy sencillo que diga simplemente esto: si colisionas con una roca te quita vida.
Algo como esto:

function OnTriggerEnter(other:Collider){

if(other.name == "Sphere01"){
HP.vida -= 10;
}
}

En donde pone "Sphere01", t tienes que poner el nombre del meteorito, es decir, el objeto que lleva el
collider. En caso de que tengas el mismo meteorito que yo, el que yo puse en este mismo tutorial, el nombre
ser ese "Sphere01", si tuvieras otro modelo de roca pon el que sea.

Este script debe llevarlo el objeto de la nave que tiene el collider. No podemos poner este cdigo con el
controller, porque el controller est en el objeto que contiene la nave + la cmara, para que cuando se mueve
la nave, la cmara se mueva con ella. Por eso, este script, debe ir solamente a la nave, y ms especficamente
al objeto que tenga el collider. (Por si la nave est formada por varios objetos)

Ahora tambin podramos hacer que, ya que puedes disparar, si disparas a un roca la destruyes. Eso lo
podemos hacer muy fcilmente. Necesitamos que cuando la bala colisione con la roca, esta desaparezca,
puedes ver el mtodo a continuacin, pero me gustara que intentases hacerlo t antes por ti mismo.

En mi caso lo hago as: en el script "mov_bala", el que haca que la bala se moviese (hay una imagen de ese
script ms arriba) debajo de la funcin Update pongo una funcin OnTrigger Enter:

function OnTriggerEnter(other:Collider){
if(other.name == "Sphere01"){
destroy(other.gameObject);
}
}

De esta forma si la bala detecta que ha entrado en un meteorito, lo destruye. Tambin puedes crear un efecto
para cuando se destruyan las rocas. En mi caso he creado un particle system, poca cosa, unas particulas que
salen disparadas cuando le das a un meteorito. Y lo haces aparecer con el comando Instantiate justo debajo
de Destroy. Pero eso ya es cosa tuya.

Bien, a ver! Los meteoritos ya estn puestos, pon este meteorito que acabas de crear, con el collider, y todo
en un prefab. Ahora podras hacer algo muy sencillo y divertido que hice yo. Tienes un meteorito, lo
seleccionas y lo duplicas, luego lo mueves y lo situas a una distancia del otro. Ahora tienes dos, los
seleccionas, duplicas y tienes cuatro. Luego los seleccionas y los vuelves a duplicar, ya tienes 8, luego 16, 32,
64... As los vas repartiendo por la escena.

Te recuerdo que la nave siempre se mueve hacia delante, independientemente de los botones que pulses t. Y
que adems, hicimos que solo se pueda mover verticalmente y horizontalmente una cierta cantidad, por lo que
la nave se movers linealmente a travs de un recorrido, circuito o como quieras llamarlo:




Cuadrado azul: la nave / Puntos rojos: meteoritos

Con esto quiero decir que repartas los meteoritos por dentro de este circuito, no hay necesidad de ponerlos
por fuera, en todo caso como decoracin, pero eso ya es cosa tuya...

Pues con los meteoritos ya he terminado. Pero eso son pocos peligros. Que tal unos drones (androides) que te
ataquen, te disparen. Suena bien. Yo voy a usar este modelo que he encontrado:

http://www.turbosquid.com/3d-models/free-tech-drone/725298

Primero de todo lo situamos en la escena, le aplicamos la textura y pensamos en lo que va a hacer ese drone.
Pues se me ocurre que el drone estar fijo en un sitio, siempre mirndote (a la nave), y te va disparando. Si
una bala te toca te quita vida, y tu puedes naturalmente destruirlos.

Pues empezemos creando un script, yo lo llamo drone. Primero haremos eso de que te mire siempre. Para
esto hay un comando en Unity llamado LookAt:

transform.LookAt (transform)

Donde pone transform va el transform de la nave. Por tanto, necesitamos el transform de la nave en una
variable. Para esto, lo que he hecho yo es ir al script del collider de la nave, el que deca que si chocamos con
una roca nos quitaba vida, ese. Y aqu creo una nueva variable static para poder acceder a ella desde el otro
script:

static var posnave : Transform;

Y luego en funcin Update, especifico que esa variable tipo transform es el de la nave:

posnave = this.transform;

Aunque no es necesario poner "this.", automticamente el compilador ya sabria que te refieres al transform
de ese objeto si no pones nada:

posnave = transform;

Ahora volviendo al script del drone, lo nico que tenemos que hacer es escribir en Update esta lnia:

transform.LookAt (naColl.posnave);

El script que yo tengo en la nave se llama naColl. Y si quieres probarlo, guarda y dale al Play. El drone debera
estar siempre mirando a la nave.

Siguiente tarea, disparar. Para disparar no hace falta que crees otro proyectil, puedes gastar el mismo que
usabamos para la nave. Solo que, luego haremos que si detecta colisin con el proyectil, te quita vida. Claro,
el problema que podramos tener es que al disparar t con la nave, te hicieras dao con tu propio proyectil.
Pues haremos simplemente que al disparar, el nombre de la bala cambia, ahora vers.

En el mismo script del Drone, justo debajo de LookAt, haremos que el drone dispare. No queremos que
dispare contnuamente, sino una bala cada cierto tiempo, me explico, queremos que dispare ms bien como
una pistola, no como una metralleta, as que haremos que dispare una bala cada segundo.

Para esto, creamos una variable que se llame temp (o como quieras), tipo float, y en Update hacemos que
aumente uno por segundo:

temp += time.DeltaTime;

Ahora escribimos una condicin: si temp es ms de un segundo, dispara:

if (temp > 1){

bala = Instantiate (bala_prefab, transform.position, transform.rotation);

Para esto claramente tienes que crear la variable "bala_prefab", y "bala" tipo GameObject anteriormente. Y
como hemos dicho antes, para que no se confunda esta bala con la de la nave le cambiamos el nombre. A
continuacin, dentro de la condicin:

bala.name = "Bala_Drone"

As, cambiamos el nombre de la bala a "Bala Drone".

Y por ltimo reseteamos el temporizador a 0. Porque si la condicin es que el drone dispare cuando haya
pasado un segundo, al disparar el temporizador vuelve a 0, vuelve a crecer hasta 1, y vuelve a disparar. Para
esto a continuacin de bala.name ponemos lo siguiente:

temp = 0;

Y cerramos condicin. Hecho! Pero aun nos queda un problema. El drone nos dispara en todo momento, es
decir, est bien que si lo tenemos delante nos dispare, pero lo mejor sera que si est muuuy lejos no lo haga.
Para eso deberamos indicarle que si la nave se acerca, empieze a disparar.

Lo que yo he hecho es ponerle al Drone un Sphere Collider (Component > Physics > Sphere Collider), luego
activar el Trigger, y ponerle a la esfera del collider un radio bastante grande, es decir, la esfera, el collider del
drone es mucho ms grande que l. As ahora en el script ponemos que si la nave entra en el collider, empieze
a disparar, y cuando salga del collider, pare de disparar.

Para esto, creamos una variable tipo boolean que se llame disp, y la aadimos a la condicin para disparar,
esa condicin de "if(temp>1)", ahora ponemos "if(temp>1 && disp == true), y luego fuera de la funcin
Update escribimos:

function OnTriggerEnter(other:Collider){
if(other.name == "LOD0"){
disp = true;
}
}

function OnTriggerExit(other:Collider){
if(other.name == "LOD0"){
disp = false;
}
}

Es decir: Si detecta algo entrando, y eso es "LOD0" (la nave), disp se activa, = true, y puede disparar. Si
detecta la nave saliendo, disp = false, y ya no dispara.

Recuerdo que en la condicin (disp == true), no es necesario poner == true, solo con poner if(disp) es
suficiente. En caso de que se quisiera hacer la condicin (disp==false), sera lo mismo que (!disp).

Bueno, todo el script quedara as:




Y ahora solo falta hacer que si la bala toca la nave, nos quite vida. En el script del collider de la nave, en mi
caso se llama naColl.js, tenamos esto:

function OnTriggerEnter(other:Collider){
if(other.name == "Sphere01"){
HP.vida -= 10;
}
}

Pues a la condicn aadimos la roca:

function OnTriggerEnter(other:Collider){

if(other.name == "Sphere01" || other.name == "Bala_Drone"){
HP.vida -= 10;
}
}


Y listo! Terminamos as tambin este apartado. Ya tenemos rocas que nos hacen dao y enemigos que nos
disparan, esto empieza a coger forma.

Vous aimerez peut-être aussi