#2 Encontrar objetos de la jerarquía. FindGameObject. [Serie Fundamental de Unity]

ACTUALIZACIÓN IMPORTANTE

Este artícu­lo pertenece a una serie de vídeos antigu­os, actual­mente hay disponible una NUEVA SERIE que abor­da con may­or pro­fun­di­dad el tema de encon­trar cualquier GameOb­ject o Com­po­nentes de la esce­na des­de un Script. 

🟢 INTRODUCCIÓN a la serie sobre encon­trar las ref­er­en­cias de los GameOb­jects y com­po­nentes de la esce­na en Uni­ty
 

VER LISTA COMPLETA SOBRE ENCONTRAR REFERENCIAS EN UNITY

MIRA ESTE DESCABELLADO EXPERIMENTO

A partir de aquí sigue el artículo antiguo

Introducción

En este artícu­lo vamos a estu­di­ar dis­tin­tas for­mas de encon­trar, des­de un Script, los GameOb­jects (obje­tos) que se encuen­tran en la jer­ar­quía. Entre las for­mas ten­emos asig­nar direc­ta­mente los obje­tos des­de el inspec­tor o encon­trar­los a través de méto­dos como "Find­GameOb­ject".

Página principal del proyecto

Antes de empezar te invi­to a ver el sigu­iente video en el que se resuelve este problema: 

🟢 INTRODUCCIÓN a la serie sobre encon­trar las ref­er­en­cias de los GameOb­jects y com­po­nentes de la esce­na en Uni­ty
 

Procedimiento

Vamos a tra­ba­jar con la estación Find GameOb­jects, que con­siste en 5 obje­tos sobre una mesa. La fun­ción de esta estación es regre­sar al esta­do de reposo a los obje­tos que son perturbados. 

El prob­le­ma es que ini­cial­mente no ten­emos las ref­er­en­cias de los obje­tos, así que la fun­ción no se puede lle­var a cabo.

5 modelos 3d similares a trofeos sobre una mesa
Fig. 1: Estación para encon­trar obje­tos en esta­do de reposo.
modelo 3d volcado sobre una mesa, partículas alrededor
Fig. 2: Estación para encon­trar obje­tos per­tur­ba­da. Luego de unos segun­dos los obje­tos desaparecen.

3 modelos 3d colocados sobre una mesa, partículas alrededor
Fig. 3: Estación para encon­trar obje­tos volvien­do al esta­do de reposo. Luego de unos segun­dos los obje­tos rea­pare­cen en su posi­ción inicial.

Den­tro del Script "Find­GameOb­ject" ten­emos algo de códi­go ya escrito.

Fig. 4: Script Find­GameOb­ject. Defini­ción de los obje­tos a encontrar.

Los 5 obje­tos están declar­a­dos como pri­va­dos y están seri­al­iza­dos, por eso apare­cen en el inspec­tor (como se obser­va en la sigu­iente figura).

Fig. 5: Estación para encon­trar obje­tos en esta­do de reposo.

En el méto­do Start se hace la lla­ma­da a 5 méto­dos que se encar­garán de encon­trar las referencias.

Fig. 6: Lla­ma­da a los méto­dos que se encar­gan de encon­trar las ref­er­en­cias de los objetos.

Los méto­dos se encuen­tran incom­ple­tos. Nue­stro obje­ti­vo es com­ple­tar­los y des­cubrir dis­tin­tas for­mas de encon­trar las referencias.

Fig. 7: Méto­dos que se encar­gan de encon­trar las ref­er­en­cias de los obje­tos.

Forma #1: Asignar los objetos directamente en el inspector a un campo serializado.

Como se obser­va en la figu­ra 4, todos los obje­tos están definidos como pri­va­dos y están seri­al­iza­dos, pero esto es más que nada para que veamos en el inspec­tor, cómo al ini­ciar el juego encon­tramos la referencia.

Para la for­ma 1, tomamos el obje­to de la jer­ar­quía y lo arras­tramos al cam­po en el inspec­tor. Como se ilus­tra a continuación.

Fig. 8: Asi­gnación de GameOb­ject a cam­po en la jerarquía.

Con esto ya le dec­i­mos a nue­stro Script qué obje­to de la jer­ar­quía es el GameOb­ject definido con el nom­bre "Object1a".

Forma #2: Asignar los objetos directamente en el inspector a un campo público.

Esta for­ma es prác­ti­ca­mente igual que la ante­ri­or, sólo que aho­ra el GameOb­ject lo defin­i­mos como público.

Fig. 9: Defini­ción de un GameOb­ject con vis­i­bil­i­dad pública.

Definir un cam­po como públi­co hace que sea acce­si­ble des­de cualquier con­tex­to y por lo tan­to tam­bién aparece en el inspector. 

Como en la for­ma ante­ri­or, tomamos el GameOb­ject de la jer­ar­quía y lo arras­tramos al cam­po en el inspector.

Forma #3: Etiquetas. Método FindGameObjectWithTag de la clase GameObject.

La clase GameOb­ject cuen­ta con un méto­do que per­mite encon­trar un GameOb­ject en la jer­ar­quía uti­lizan­do las etiquetas.

Fig. 10: Menú desple­gable Tag pre­sente en todo GameOb­ject de la jerarquía.
Fig. 11: Ven­tana que aparece al hac­er clic en "Add Tag" (figu­ra 10) y luego en el signo "+".

Luego pro­cedemos a escribir el códi­go nece­sario para encon­trar el GameOb­ject des­de el Script. Vamos a escribir­lo den­tro del méto­do "findGameObject2" que se ve en la figu­ra 7. 

La línea de códi­go es la siguiente:

object2=GameObject.FindGameObjectWithTag("Object2");

Vamos a analizarla por partes, al escribir "object2=" esta­mos dicien­do que el cam­po object2 va a valer lo que sea que colo­que­mos luego del sig­no "=". Como se obser­va en la figu­ra 9, object2 es de tipo GameOb­ject, por lo tan­to lo que colo­que­mos luego del sig­no "=" ten­drá que devolver un obje­to de tipo GameObject.

Al escribir "GameOb­ject." (GameOb­ject pun­to), esta­mos indi­can­do que quer­e­mos acced­er a los atrib­u­tos y méto­dos que están definidos en la clase GameObject.

Eje­cu­ta­mos un méto­do que se lla­ma Find­GameOb­jectWith­Tag" (tra­duci­do sig­nifi­ca: "encon­trar GameOb­ject con eti­que­ta"), este méto­do nece­si­ta que le ingre­se­mos (den­tro de los parén­te­sis) el String con la etiqueta.

Leer esto e inter­pre­tar­lo es algo com­pli­ca­do, pero de a poco va cobran­do sen­ti­do con­forme vamos aprendiendo. 

En el video obser­va­mos que al eje­cu­tar el juego, logramos encon­trar la ref­er­en­cia de object2.

En el lengua­je C# se dis­tinguen mayús­cu­las y minús­cu­las, por lo tan­to hay que respetarlas.

Forma #4: Nombre. Método Find de la clase GameObject.

Como se obser­va en la figu­ra 10 arri­ba del menú desple­gable Tag, hay un espa­cio con el tex­to "Object2", esto es el nom­bre que tiene asig­na­do el GameOb­ject y con ese nom­bre aparece lis­ta­do en la jerarquía.

Uti­lizan­do el méto­do Find de la clase GameOb­ject podemos encon­trar un GameOb­ject por su nom­bre, de la sigu­iente forma:

object3=GameObject.Find("Object3");

Con esta instruc­ción, Uni­ty revis­ará la jer­ar­quía, encon­trará el obje­to lla­ma­do "Object3" (si es que hay uno) y lo asig­nará al cam­po object3.

Si no hay ningún GameOb­ject lla­ma­do "Object3" en la jer­ar­quía, el cam­po object3 ten­drá el val­or null. Si hay más de un obje­to que tiene el mis­mo nom­bre, no podemos estar seguros de que vamos a encon­trar el que queremos.

Forma #5: Componente única. Método FindObjectOfType<T>.

La últi­ma for­ma que vamos a ver es un poco más complicada. 

La clase GameOb­ject nos per­mite encon­trar la ref­er­en­cia a una com­po­nente que esté pre­sente en la jer­ar­quía, por ejem­p­lo la com­po­nente Trans­form, Col­lid­er, Rigid­Body, etc.

Por supuesto, prác­ti­ca­mente todos los GameOb­jects tienen la com­po­nente Trans­form, entonces en prin­ci­pio no sería muy útil. Pero ¿Qué pasaría si la com­po­nente que nos intere­sa es úni­ca en la jer­ar­quía? Es decir, sabe­mos que hay un solo GameOb­ject en la jer­ar­quía que la tiene. Esto podría servirnos, porque encon­trar esa com­po­nente úni­ca es equiv­a­lente a encon­trar ese GameObject.

Podría ser cualquier com­po­nente siem­pre que sea úni­ca, en este caso creamos un nue­vo Script con el nom­bre: "Object4Script" y se la asig­namos al GameOb­ject de la jer­ar­quía lla­ma­do "Object4".

Luego escribi­mos el sigu­iente códi­go en el méto­do "findGameObject4" (ver figu­ra 7).

object4=GameObject.FindObjectOfType<Object4Script>().transform.gameObject;

Primero encon­tramos la ref­er­en­cia del obje­to tipo Object4Script con el méto­do FindObjectOfType<T> de la clase GameOb­ject, luego accedemos a su com­po­nente trans­form por medio del oper­ador pun­to y luego a la com­po­nente gameOb­ject. El resul­ta­do de esto lo asig­namos a object4.

De esta for­ma logramos encon­trar el GameOb­ject a par­tir de una de sus com­po­nentes. Por supuesto, si hay otro GameOb­ject que tam­bién tiene ese com­po­nente, podríamos encon­trar el GameOb­ject equivocado.