4. CLASE OBJECT (II)









FUNCIONES:

ToString:

function ToString () : String

Devuelve un string con el nombre del gameobject que hace la consulta.

GetInstanceID:

function GetInstanceID () : int

Unity asigna a cada objeto un identificador único. Esta función devuelve ese identificador.

Vamos a utilizar estas dos funciones en un mismo ejemplo. En el capítulo anterior teníamos vinculado nuestro script-para-todo a la cámara principal. Abrimos el editor de scripts, borramos todo y tecleamos lo siguiente:

var todoSobreMi: GameObject;
Debug.Log("El nombre de este objeto es " + todoSobreMi.ToString() + 
" y su id unica es " + todoSobreMi.GetInstanceID());

El script no merece mucha explicación. Asegurémonos de arrastrar el cubo a la variable todoSobreMi en el inspector. Al pulsar el play deberia mostrarse el nombre e id del cubo, tal como se muestra en la imagen (obviamente, la id no tiene por qué coincidir con la que os aparezca a vosotros)




FUNCIONES DE CLASE


operator bool, == y !=

Estas tres funciones méramente habilitan la posibilidad de establecer comparaciones de igualdad/desigualdad entre dos objetos o componentes, o (en el caso del operador bool)si existe dicho objeto componente y tiene un valor distinto de null.

Por ejemplo:

if (rigidbody) 
Debug.Log("Este gameobject tiene vinculado un Rigidbody");

Que sería lo mismo que haber escrito

if (rigidbody != null)
Debug.Log("Este gameobject tiene vinculado un Rigidbody");


Instantiate:

static function Instantiate (original : Object, position : Vector3, rotation : Quaternion) : Object

Esta función lo que hace es clonar el objeto que le pasamos como primer parámetro, y devolver ese clon del objeto original, ubicándolo en posición y rotación determinadas.

Observamos que el parámetro "position" es de tipo Vector3, que es una clase que no tardaremos mucho en estudiar. De hecho, posiblemente sea la próxima que tratemos, ya que aunque no pertenece a la jerarquía de herencia que hemos tomado como referencia para el orden de estudio, sí que va a aparecer el número suficiente de veces durante el tránsito por dicha jerarquía como para no ocuparnos de ella de primeras.

Un Vector3 es, en pocas palabras, un punto en el espacio tridimensional. Dicho punto viene dado por las coordenadas en el eje X (derecha-izquierda) Y (arriba-abajo) y Z (delante-detrás). Cada unidad se corresponde a una unidad en Unity (valga la redundancia), que a su vez equivale a un metro. Por lo tanto para que un objeto se desplace un metro a la derecha, escribiríamos en nuestro Vector3 (1,0,0).

Notemos que esto es ni más ni menos que lo que hace de manera más visual las tres variables position del transform que aparecen en el inspector.

El otro parámetro de la función, rotation, es de tipo Quaternion. Quien sepa lo que es, felicidades, yo estuve varios días peleándome con apuntes de matemáticas por la red y a lo sumo me hice una idea abstracta de que un cuaternión se compone de tres números reales y uno imaginario, el cálculo de los cuales establece la rotación de un objeto. Si os sirve de consuelo, y eso lo indica el propio manual de referencia oficial de Unity, es muy raro que trabajemos directamente con cuaterniones, sino que lo haremos con funciones que nos simplifiquen el trabajo. Yo personalmente me quedo solamente con la idea de que un cuaternión lo componen cuatro elementos y mide las rotaciones. Con eso es suficiente, creedme.

Bueno, pues dicho esto a ver si somos capaces de instanciar/clonar un cubo.

Nos vamos a Unity, y le quitamos a la cámara principal el script que le habíamos colocado anteriormente. Para hacer eso, con la cámara seleccionada en el inspector colocamos el ratón sobre el nombre del script, botón derecho=>Remove Component.

Ahora, para no andar vinculando scripts a gameobjects que nada tienen que ver con él (como hicimos no hace mucho con la cámara), vamos a crear un gameobject vacío cuya única utilidad sea contener nuestro script. Para ello nos vamos al menú superior, y le damos a GameObject=>Create empty. A la carpeta que nos aparecerá en la jerarquía la renombramos (F2) como PortaScripts.

Vale, ahora doble clic sobre nuestro script en la vista de Proyecto para abrir el editor de scipts, y escribimos:

var reproducete : GameObject;

Instantiate(reproducete, Vector3(2.0,0,0), Quaternion.identity);

Aquí lo que hemos hecho meramente es dejar una variable global "expuesta" (que pueda ser accesible desde el inspector) y llamar a la función instantiate, de tal manera que clonará el Gameobject que le arrastremos y lo situará dos unidades/metros a la derecha del objeto original. Quaternion.identity meramente significa que el objeto clonado tendrá rotación cero, esto es, su transform rotation estará a 0,0,0 (salvo que el objeto clonado dependa a su vez de otro objeto, en cuyo caso tendrá la misma rotación que el objeto padre, pero esto ya lo explicaremos cuando toque.

Salvamos el script y lo arrastramos hasta nuestro PortaScripts en la jerarquía. Vemos que en el inspector, con PortaScripts seleccionado, aparece el script y la variable expuesta que llamamos reproducete. Arrastramos el cubo hasta ella y ya podemos darle al play. Debería aparecernos un segundo cubo, tal que así:



Podemos observar alguna cosa más. En la jerarquía aparece -mientras se está reproduciendo la escena- un segundo cubo, el cual Unity nos indica expresamente que es un clon del original. Si lo seleccionamos, podemos ver en su transform en el inspector que la variable x (el eje derecha/izquierda) no está en el cero, sino en el dos, tal como le habíamos indicado.

Probemos otra cosa. Detenemos la reproducción de la escena. Seleccionamos el cubo original, y le damos a los ejes X e Y de transform rotation los valores 25 y 65 respectivamente.El cubo girará sobre dichos ejes. Démosle al play.

Podemos observar que el cubo clonado se muestra alineado con la cuadrícula global, y no con el cubo original. Esto es lo que conseguimos con Quaternion.identity.

La función instantiate es muy usada para crear proyectiles, partículas en explosiones e incluso AI (inteligencia artificial) para enemigos.

Cabe una segunda forma distinta para la función Instantiate, que es esta:

static function Instantiate (original : Object) : Object

Como podemos observar, aquí meramente estamos duplicando el objeto, se tal suerte que el clonado se ubicará en el mismo lugar y con la misma rotación que el original. Podemos probarlo en nuestro script meramente eliminando el segundo y tercer parámetro. Al darle al play, sabemos que ha aparecido un clon porque así lo indica la jerarquía, pero no podemos distinguirlo porque está justo en el mismo sitio que el original y se están solapando.


Destroy:

static function Destroy (obj : Object, t : float = 0.0F) : void

Como su nombre indica, esta función borra del juego un gameobject, un componente o un asset. Tiene dos parámetros, siendo el primero el elemento a borrar y el segundo el tiempo en segundos que tardará en borrarlo desde que se llame a la función (si no se indica lo contrario, por defecto el parámetro indica cero segundos, esto es, la destrucción del objeto es automática).

Hay una cuestión que igual ahora no se entiende muy bien, pero la dejo apuntada para tratarla más en profundidad en otro momento: si en el parámetro obt colocamos un Componente, la función sólo eliminará ese componente, haciéndolo desaparecer del Gameobject al que pertenezca. Pero si en cambio lo que le pasamos a la función es un gameobject, se destruirá tanto el gameobject como todos los hijos de ese gameobject (esto es, todos los objetos y componentes e inclusive otros gameobjects que dependan del eliminado en una relación de parentesco). Para tener un acercamiento intuitivo a esta relación de dependencia, pensemos en un gameobject coche que tiene, entre otros, cuatro componentes rueda y un gameobject conductor que hemos vinculado al gameobject coche para que allá donde se desplace el coche vaya el conductor. Si un misil destruye un componente rueda usando la función destroy, sólo se destruirá la rueda. Si en cambio lo que destruye es el gameobject coche, se destruirá tanto el vehículo como las ruedas como el conductor.

Vamos a probar la función Destroy. Para empezar devolvamos a nuestro cubo original a su rotación original (0,0,0). Vamos a rehacer ahora nuestro sufrido script, que tenemos vinculado al cubo. En el editor de scripts modificamos nuestro código así:

var reproducete : GameObject;
var nasioPaMorir : GameObject;

nasioPaMorir = Instantiate(reproducete, Vector3(2.0,0,0), Quaternion.identity);
Destroy (nasioPaMorir, 10.0); 

Creo que es bastante fácil de entender. Lo que hemos hecho es añadir una segunda variable de tipo GameObject, que no vamos a inicializar desde el inspector, porque lo que hará será almacenar el cubo clonado que devuelve la función Instantiate. Inmediatamente es llamada la función Destroy, que borrará el elemento clonado que hemos almacenado en nasioPaMorir pasados diez segundos.

Salvamos, le damos al play, contamos diez, y adiós clon.


DestroyImmediate:

static function DestroyImmediate (obj : Object, allowDestroyingAssets : boolean = false) : void

Esta función destruye inmediatamente un objeto, igual que la función anterior. Desde el manual de Unity se nos dice, no obstante, que es preferible usar Destroy en lugar de esta función, ya que puede borrar más de lo que deseamos.

Por lo tanto, olvidémonos de DestroyImmediate.

Mañana acabamos con las tres funciones de clase que nos faltan.

Bye.

POSTED BY UnityScripts
POSTED IN
DISCUSSION 2 Comments

2 Responses to : 4. CLASE OBJECT (II)

  1. Asi quedaría escrito en C#

    using UnityEngine;
    using System.Collections;

    public class ClonarCubo : MonoBehaviour
    {
    public GameObject clonando;
    GameObject objClonado1;
    GameObject objClonado2;

    void Start ()
    {
    objClonado1 = (GameObject)Instantiate (clonando , new Vector3(2.0f, 0, 0), Quaternion.identity);
    objClonado2 = (GameObject)Instantiate (clonando);
    Destroy (objClonado1, 3.0f);
    Destroy (objClonado2);
    }

    void Update () {}
    }

    Saludos y muy buen material ;)

  2. Anónimo says:

    Hola, quiero saber cómo se puede borrar cualquier objeto al salirse de un área (cubo) con un script.
    Una vez que lo tenga, ¿tendría que añadirlo a la cámara?
    Gracias de Antemano.

Leave a Reply

Con la tecnología de Blogger.