[Unity 3D] Tutorial para novatos (3 – Programación)

Como andan malditos bastardos!? 😀 Espero que el blog sea de su agrado y sino ¬_¬ hay tabla. Bueno ya habiéndolos introducido con la interfaz y básicamente el manejo de objetos, no queda mas que empezar a toquetear el código para darle vida a nuestros queridos objetitos.

Sin código, nuestros bichos no harán prácticamente nada, a menos que se bajen de internet algunos prefabs o que utilicen algunos componentes ya existentes para manejar algunas de estas cosas sin necesitar conocer algo de programación. Pero la idea no es ello, sino poder realizar lo que nosotros queramos que hagan estos gameobjects a nuestro propio gusto.

Para esto entonces, Unity soporta 3 lenguajes, UnityScript, C# y Boo. UnityScript es una variación de Javascript y se encontrará como este último nombrado en el propio Unity por más que no sea puramente Javascript. Boo por otro lado, para los que no lo conocen, es un derivado de Python. Ahora bien, Javascript (lo llamaré así para evitar confusiones con el programa o con la mismísima página de Unity) es el lenguaje más utilizado por la vasta cantidad de tutoriales que hay en Internet, mientras que en la documentación oficial, se puede encontrar el código en los 3 lenguajes. Quiero aclarar que estos son los lenguajes soportados oficialmente, mientras que se pueden encontrar plugins para demás lenguajes como C/C++, Objective-C, LUA y tal vez alguno que otro más, pero preferiblemente es mejor trabajar con los que ya vienen para evitar errores de incompatibilidad o de portado a las diferentes plataformas.

En mi caso, yo he decidido optar por C# ya que me es mas familiar pues mi lenguaje materno (? es C++ por lo que aprenderlo no me costó nada. Y si bien tiene ciertas desventajas con respecto a los otros, lo prefiero por comodidad. Asi que este pequeño tutorial va a estar basado en dicho lenguaje.

Ya dicho lo referido al lenguaje, antes de comenzar (no termino mas con la intro :-/) hay que saber los que son los scripts (que representan la base de la programación en Unity). Los scripts son básicamente pequeños archivos que contiene órdenes que serán ejecutadas una vez llamado el script. Son una manera de modularizar las cosas y tiene su justificación en Unity el uso de scripts, pues hace que la programación sea mas sencilla y corta a la vez con código que puede ser reutilizable en otros proyectos, lo que permite que para cada objeto de la escena, se tengan cada una de las funciones en scripts separados que cumplen una única funcion, lo que hace más fácil el manejo interno de los componentes del objeto. Tal vez lo haya complicado un poco pero ya me entenderán.

Entonces, para seguir con el ejemplo anterior, en el cual teníamos un plano con un cubo (paralelepípedo) sobre él, una fuente de luz y una cámara, vamos a aplicarle un par de scripts para que hagan ciertas cosas.

En primer lugar, comenzaré por explicarles la creación de scripts y que se puede ver en ellos. Para esto, deberán ir al menú Assets -> Create -> C# Script (o cualquiera de los scripts de otros lenguajes).

Luego les aparecerá un script nuevo al cual le podrán cambiar el nombre en la ventana de Project, y en la ventana Inspector figurará el código que este asset tiene. Para ahora poder modificarlo le daremos click en el botón Open.. y se abrirá la ventana de MonoDevelop-Unity el editor de código por defecto que incluye Unity. En caso que a uno no le guste, se puede cambiar el editor con que se abrirán los scripts, pero en mi caso, me pareció un muy buen IDE que aparte de no tener ningún conflicto con Unity, posee herramientas de debug y autocompletado con todos las palabras reservadas para Unity.

Una vez abierto el MonoDevelop podremos ver lo siguiente:

Aquí podemos observar una especie de código ya escrito que viene por defecto en los scripts de C#. Básicamente hace inclusión de las librerías que requiere para ser ejecutado el código en las primeras 2 líneas. Con estas 2 librerías no haría falta agregar ninguna otra librería a menos que necesitemos de funciones muy específicas.
Además tiene la declaración de la clase que se corresponde con el script que hereda de la clase padre MonoBehaviour. Esta declaración es obligatoria para que se pueda ejecutar correctamente el mismo. Dentro de ella tenemos 2 funciones que son opcionales que hacen lo mismo que su comentario dice, y además poseemos otra más que se no se incluye pero sirve para los mismos fines:

  • void Start() : ejecutará todo el código que haya dentro de ella al inicializarse el objeto, es decir en el momento en que el objeto se activa.
  • void Update() : se ejecutará en cada frame de ejecución, es decir, constantemente.
  • void Awake() : se ejecuta al inicializarse el programa por mas que el objeto no esté activo.

Con esto aclarado, programaremos el movimiento del cubo de la escena inicial para que este se pueda desplazar sobre el plano según toquemos las flechitas del teclado.

La idea entonces es, constantemente detectar si el usuario está presionando alguna tecla y dependiendo de que tecla presione el cubito se moverá.

A continuación muestro el código requerido para ejecutar esta acción:

Allí se puede ver la estructura inicial con la que se parte en un script. Además de ello, podemos observar la declaración de una variable entre la función Start y el comienzo de la clase (línea 6). Esta variable al estar declarada fuera de las funciones tiene la característica de que puede ser utilizada en cualquier función dentro del script. El hecho de que tenga la etiqueta public al principio quiere decir que cualquier otro script o incluso en el mismo entorno de Unity, podremos ver esta variable y la podemos modificar. También las variables se puede declarar private en el caso de que no sea necesario utilizarlas en otros scripts y no se quiera poder modificar en programa.

La variable speed entonces significará la velocidad a la que se moverá el cubo, mal dicho velocidad pues en realidad será el salto que pegará el cubito en cada cuadro de ejecución. Esta se encuentra pública pues por mas que no requiera su uso en otros scripts, simplemente servirá para poder cambiar el valor dentro del software a la hora de ejecutar el juego.

Luego, lo que deberemos hacer es conocer como obtener el input del usuario para poder realizar algún cambio en la escena. Para ello tenemos la clase Input que posee varios métodos para obtener diferentes tipos de inputs por parte del usuario. Dentro de sí, tenemos el método GetKey que devuelve un booleano que en caso que el código de tecla presionada se corresponda con el argumento (KeyCode.UpArrow por ejemplo, que vendría a ser el código de la flechita hacia arriba) que se le pasó  entonces retornará true y en caso contrario false. Entonces preguntamos dentro de la función Update del script si se presionó la tecla «flecha arriba» (línea 16) y si es correcto, entonces entrará al if, y realizará lo que allí dentro encuentre.

La línea 17, posee lo que hará en caso de que se haya presionado la tecla «flecha arriba». Esta línea lo que hace es:

  • this : en este objeto, el cual está llamando este script …
  • transform : modifica el componente Transform (que es el componente que posee la posición, rotación y escala del objeto) …
  • Translate : y aplica una traslación del objeto en las siguientes unidades …
  • (0f, 0f, speed * Time.deltatime, Space.World) : 0 unidades en X, 0 unidades en Y y (speed * Time.deltaTime) unidades en Z, y estas unidades se trasladará el objeto respecto de los ejes del espacio de la escena.

Time es una de las clases que controla el tiempo de las escenas, mientras que deltaTime es el tiempo transcurrido entre cada cuadro, por lo que el producto speed y Time.DeltaTime permite que la traslación del objeto sea lo mas suave posible pues los FPS que corre un juego en diferentes PCs suelen ser diferentes (en algunas PCs mas lentos y en otras mas rápido) y esto se solventa gracias al uso de deltaTime logrando que la traslación pueda ser dependiente del rendimiento del juego en cada PC en particular.

El cuarto término del Translate sirve en este caso para que el objeto no se mueva con respecto a sus propios ejes (pues se encuentra rotado con respecto a la cámara) sino que su movimiento sea relativo a los ejes de la escena en sí. Si se quiere que se mueva sobre sus propios ejes, solamente se deberá suprimir el cuarto término dejando únicamente las 3 coordenadas.

Terminando la explicación de lo que hace el código, se puede ver que además se encuentran programadas las otras 3 flechitas. Cada cual con su correspondiente traslación hacia la parte del eje que le corresponda. Por ejemplo para la «flecha abajo» la traslación será en el mismo eje Z pero en sentido opuesto y por ello es el signo «menos»  que se puede ver en el código. Para las flechitas derecha e izquierda, ahora habrá que realizar la traslación en el eje X (pues es el eje que horizontal que se puede ver respecto de la cámara que capta la escena) .

Ya con el código programado, bastará guardar los cambios y volver a Unity para poder observar los cambios. Para corroborar el funcionamiento de las flechas, entonces haremos lo siguiente, arrastraremos el script que acabamos de crear (que se puede encontrar en la ventana Project) al Inspector del objeto Cube o podemos presionar donde dice Add Component y buscar allí el script, o sino podemos estando con el objeto cubo seleccionado ir al menú Component -> Script -> (el script que acabamos de programar). Entonces ya tenemos el script cargado en nuestro objeto y ahora lo podemos ver dentro del Inspector.

Podemos ver en la imagen como se encuentra cargado en script dentro del objeto. Además se ve la variable que habíamos etiquetado como pública dentro del script y tocando en el número que aparece (por defecto 0), se puede modificar el valor.

No quedará otra ahora que probar el script. Para ello pulsamos el botón Play que se encuentra en el centro de la pantalla apenas abajo de la barra de menúes.

Cualquier flechita que pulsemos, debería movernos nuestra caja hacia ese sentido de la pantalla.

Recordar que si se desea desactivar el script (el componente) para que no se ejecute, simplemente habrá que destildar la casilla que se encuentra, dentro del objeto en su Inspector, y se corresponde con el script.

Ya finalizado el tutorial, y por no querer dejarlo con tan pocas líneas de programación, pondré algunas líneas de código que me han resultado útiles para realizar algunas cosillas:

Una/s de las líneas claves para manejar a un objeto en el espacio es:

  • this.transform.Translate(0f,1f,0f);
    this.transform.position = new Vector3(0f,1f,10f);
    this.transform.Rotate(0f,90f,0f);

El translate como ya hemos mostrado sirve para trasladar el objeto en X,Y,Z unidades. El position, sirve para modificar la posición del objeto y al hacer esta asignación, el objeto pasará a estar en dicha posición. El rotate por otro lado, sirve para rotar el objeto, en este caso 90 grados respecto al eje Y. Entonces podemos ver que modificanco algunas cosillas del componente transform podemos mover el objeto, rotarlo o incluso modificar su escala con el método localScale.

La siguiente línea, sirve para tener un objeto ya existente en la escena a mano. Basta con declarar una variable de tipo GameObject y asignarle a la misma el la búsqueda de el objeto que estamos deseando, GameObject.Find(«X_objeto»)

  • GameObject objeto = GameObject.Find("Objeto2");

Esta otra línea, sirve para modificar u obtener datos de otros componentes/scripts que posea el objeto el cual está ejecutando el script. Para ello, utilizamos el método GetComponent<componente_deseado>().metodo_variable y en donde dice componente_deseado iría el nombre del script o del componente que estamos deseando obtener algún dato o cambiarlo, mientras que donde dice metodo_variable se correspondería la variable que buscamos obtener o algún método que busquemos llamar. El caso que se presenta a continuación, lo que hace es activar la ejecución de ComponenteX, o sea, tildar el check box del componente (como unas líneas mas arriba lo he mostrado)

  • this.GetComponent<ComponenteX>().enabled = true;

La línea que viene, sirve para crear nuevos objetos en tiempo de ejecución. Es útil por ejemplo para dibujar una escena de manera programada, o para crear las balas de una pistola, etc. Para ello entonces utilizaremos la función Instantiate a la cual se  le pasan como argumentos, el objeto que va a clonar, la posición donde se originará el clon, y la rotación que este posea. El Instantiate devuelve un objeto de tipo Object y por ello lo casteo con (GameObject) Instantiate … para entonces poder trabajarlo como tal, debido a las limitaciones de los Object.

  • GameObject nuevoObjeto = (GameObject)Instantiate(objeto, new Vector3(0f,1f,2f),Quaternion.identity);

Esta última línea sirve para cargar un nuevo nivel por ejemplo, o una pantalla de carga, o un menú, etc. Es tan simple como escribir Application.LoadLevel y pasarle como argumento el nombre de la escena a cargar.

  • Application.LoadLevel("Scene2");

Documentación transform:
http://docs.unity3d.com/Documentation/ScriptReference/Transform.html

Documentación GameObject.Find:
http://docs.unity3d.com/Documentation/ScriptReference/GameObject.Find.html

Documentación GameObject.GetComponent:
http://docs.unity3d.com/Documentation/ScriptReference/GameObject.GetComponent.html

Documentación Instantiate:
http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html

Y aquí, un pequeño tutorial, un poco mas profundo sobre el scripting en Unity:
http://unity3d.com/learn/tutorials/modules/beginner/scripting/scripts-as-behaviour-components

Cualquier duda, dejen sus comentarios aquí abajo.

Próxima parte del tutorial de Unity “Colisiones”:
https://alittlebigof.wordpress.com/2013/04/16/unity-3d-tutorial-para-novatos-4-colisiones/

Saludos!

9 comentarios en “[Unity 3D] Tutorial para novatos (3 – Programación)

  1. gonzalo dijo:

    La verdad sos un capo! te agradezco lo que haces porque me da esperanza de poder seguir en esto ya que no encontraba ninguna tutorial de tan buen nivel como esta.

  2. miguelangelperezsanchez18 dijo:

    Hola,queria preguntarte una cosa, en caso de que yo quisiera que mi objeto se moviera solo sin que yo pulse ninguna tecla cual seria la script??

    • Miguel, cuando generás el script, dentro de la función void Update() deberás escribir la siguiente línea: this.transform.Translate (new Vector3 (x, y, z));

      this -> hace referencia al objeto que tiene el script
      transform -> hace referencia al componente del objeto que posee las características de posición, escala y rotación
      Translate -> es la función que se encarga de trasladar el objeto en tantas unidades en x,y,z que le dispongas.
      x, y, z deberás reemplazarlo por los valores que querés que se desplace tu objeto.

      Saludos.

Deja un comentario