Formas de encontrar las referencias a los GameObjects en la escena en Unity

Introducción

En este artículo vamos a ver distintas formas de dar con las referencias de los objetos que se encuentra en la escena en Unity para usarlos dentro de un Script, esto es algo importante porque si podemos acceder al objeto, podemos manipularlo a él y a cualquiera de sus componentes como necesitemos.

Si quieres conocer con mayor profundidad sobre este tema tienes este artículo sobre qué es una referencia en programación y este otro sobre qué es una instancia en programación.


¿Cuál es nuestro Objetivo?

Estamos buscando encontrar la referencia de un GameObject que se encuentra en la jerarquía dentro de un Script e imprimir el nombre de este GameObject en consola para comprobar que se tuvo éxito. Para eso utilizaremos el Script que se observa en la figura 1, simplemente se define un dato tipo GameObject llamado «objectToFind» en la línea 8 y luego dentro de la función Start se imprime el nombre de este GameObject en consola (línea 13).

script para mostrar formas de encontrar las referencias de gameobjects en la escena de unity
Fig. 1: Script que vamos a utilizar para ver los distintos métodos.

La jerarquía de la escena que vamos a usar está compuesta por los GameObjects que se observan en la figura 2, el objeto «Script-GameObject» es el que tiene asignado el Script de la figura 1 y es el que se encargará de encontrar las referencias, en la figura 3 se ve el inspector de este GameObject y el Script.

El objeto «GDT (Object to Find)» será uno de los objetos que tenemos que encontrar, así que si tenemos éxito deberíamos ver ese nombre impreso en consola.

Fig. 2: Jerarquía de la escena que vamos a utilizar para encontrar las referencias.
Fig. 3: Inspector del GameObject que tiene asignado el Script para encontrar referencias.

Observación

Si en este momento entramos en el modo juego, en la consola tendremos un error de tipo «NullReferenceException», porque el objeto al que queremos leerle su nombre es un objeto no inicializado, es decir con estado nulo. En la figura 4 vemos un ejemplo del error que aparecería en este caso.

error nullreferenceexception que ocurre cuando se intenta acceder a un campo que es nulo, no hay referencia asignada
Fig. 4: Al entrar en el modo juego se obtiene el error «NullReferenceException» debido a que el campo es nulo.

Forma 1: Declaración del campo con visibilidad pública

Los campos y variables que se declaran dentro de un Script pueden tener tres tipos de visibilidad: «pública», «privada» y «protegida». Consideremos solo los casos de visibilidad privada y pública, en el primer caso el campo declarado como privado no será accesible desde contextos externos al propio Script en el que está definido, mientras que si es declarado con visibilidad pública si que se puede acceder a ese dato desde otros Scripts y en Unity además estos campos aparecerán visibles en el inspector.

En la figura 1 se declaró un campo de tipo GameObject llamado «objectToFind» sin indicarle su visibilidad, al hacer esto implícitamente se lo está declarando como privado, en la figura 5 en cambio le añadimos «public» delante para indicar que tiene visibilidad pública.

declaracion de un dato tipo gameobject en script en unity con visibilidad publica, esto permite asignar la referencia desde el inspector
Fig. 5: Declaración del campo con visibilidad pública.

Comparando las figuras 3 y 6 vemos que ahora el campo «objectToFind» aparece en el inspector, lo que significa que podemos asignar manualmente el GameObject que queramos que esté en ese campo, es decir podemos asignar manualmente la referencia del objeto. Esto puede hacerse de dos formas, una es tomando el GameObject de la jerarquía y arrastrándolo al campo, mientras que la otra forma es utilizando el ícono del círculo con el punto que se observa a la derecha del campo (en las figura 6 o 7), esto desplegará una ventana en la que podemos elegir el objeto que queremos asignar.

campo publico en el inspector en unity
Fig. 6: En el inspector vemos que aparece el campo declarado como público.
asignacion manual de referencia en unity
Fig. 7: Se ha asignado manualmente el objeto que se quería encontrar.

Al entrar en el modo juego vemos el mensaje en consola que muestra el nombre del objeto que fue asignado en el campo, esto nos confirma que tenemos la referencia del GameObject y podemos usarla dentro del Script.

mensaje que indica que se ha encontrado exitosamente la referencia de un objeto en unity
Fig. 8: Al entrar en el modo juego vemos el mensaje en consola con el nombre del objeto.

Alternativa: Declarar el campo como privado pero serializado

Si se desea mantener la visibilidad privada hay una alternativa para que el campo aparezca en el inspector, es añadir «[SerializeField]» antes de la declaración, como se observa en la figura 9.

definicion de un campo privado serializado en script en Unity, esto hace que aparezca en el inspector pero otros scripts no lo puedan acceder
Fig. 9: Alternativa a definir el campo con visibilidad pública.

Forma 2: Encontrar la referencia de un GameObject de la escena por su nombre

Si conocemos el nombre del GameObject en la escena que queremos acceder podemos usar esa información para dar con la referencia en nuestro Script. Para eso utilizamos el método «Find» dentro de la clase GameObject y le pasamos como parámetro el nombre del objeto que se quiere encontrar, como se observa en la figura 10.

Instrucción para encontrar la referencia de un GameObject de la escena por su nombre en Unity
Fig. 10: Instrucción para encontrar la referencia de un GameObject de la escena por su nombre.

Cuando se ejecute esa instrucción, Unity recorrerá toda la jerarquía en busca de un GameObject con ese nombre, si lo encuentra lo devuelve y la referencia nos queda en la variable «objectToFind», pero si no lo encuentra esta variable tendrá valor null y nos dará el error de «NullReferenceException» si intentamos accederla.

Para tener en cuenta, si tenemos más de un objeto que tiene exactamente el mismo nombre, Unity nos devolverá el primero de ellos que encuentre en su registro, esto puede dar lugar a ambigüedades, es decir podríamos obtener la referencia de un objeto distinto al que estamos buscando.

Para evitar incrustar datos directamente dentro de las funciones lo que se puede hacer es definir un String con el nombre del objeto que se quiere encontrar y luego ejecutar la función «Find» pasando como parámetro el String, de esa manera evitamos hacer Hard-Coding, como se observa en la figura 11.

Fig. 11: Se declara un string con el nombre del objeto a encontrar y con esto se evita hacer Hard-Coding.

Forma 3: Encontrar la referencia de un GameObject de la escena por su Tag

Uno de los elementos que tiene todo GameObject en Unity es un Tag o etiqueta, se encuentra en la cabecera del inspector, como vemos en la figura 12. Podemos usar esta etiqueta para encontrar la referencia del GameObject de la escena en nuestro Script.

Por defecto los GameObjects tendrán asignado el Tag «Untagged», pero podemos asignar uno de los Tags que vienen predefinidos o crear nuevos Tags, en las figuras 12 y 13 muestro cómo crear un nuevo Tag en Unity.

Fig. 12: Pestaña para crear un nuevo Tag en Unity.
Fig. 13: Se introduce un nombre para el Tag y se guardan los cambios.

Una vez que hemos creado el Tag tenemos que asignarlo al objeto, volvemos a seleccionar el GameObject en el inspector desplegamos la ventana del Tag y lo elegimos, como se observa en la figura 14.

asignación de tag a un gameobject en unity para encontrar la referencia desde un script
Fig. 14: Se asigna el Tag creado al objeto que se quiere encontrar la referencia en el Script.

Ahora estamos en condiciones de encontrar ese GameObject utilizando el Tag, para ello ejecutamos el método «FindGameObjectWithTag» de la clase GameObject y pasamos como parámetro el nombre del Tag que se quiere buscar. En la figura 15 vemos esta instrucción en la línea 16, noten que el nombre del Tag se ha definido en un String en la línea 11 y luego en la línea 16 pasamos como parámetro la variable.

Instrucción para encontrar la referencia de un GameObject de la escena a través de su Tag en Unity
Fig. 15: Instrucción para encontrar la referencia de un GameObject de la escena a través de su Tag.

Cuando se ejecute esta instrucción, Unity revisará todos los objetos de la jerarquía hasta que se encuentre con un GameObject que tenga ese tag asignado, en ese punto devuelve el objeto y nos queda almacenado en el campo «objectToFind». Si no hay ningún objeto que tenga ese Tag, el campo «objectToFind» tendrá valor null.

Para tener en cuenta, si tenemos más de un GameObject que tiene el mismo Tag asignado, Unity nos devolverá el primero de ellos que encuentre en su registro, en este caso pueden surgir ambigüedades, podríamos obtener la referencia de un objeto distinto al que queremos.

Forma 4: Referirse al mismo GameObject al cual el Script está asignado

Si el GameObject que queremos utilizar dentro de nuestro Script es precisamente el mismo GameObject al cual el Script está asignado la referencia ya está definida dentro de un campo interno de la clase MonoBehaviour, el campo se llama «gameObject» (primera letra con minúscula), este nombre hace referencia al mismo objeto al cual el Script está asignado.

Fig. 16: Instrucción que asigna la referencia del GameObject al cual el propio script está añadido.

En este caso no sería necesario definir el campo «objectToFind», sin embargo vamos a inicializarlo como venimos haciendo hasta ahora. En la línea 17 vemos que asignamos «gameObject» a «objectToFind».

Al entrar en el modo juego vemos en el inspector (figura 17) que el objeto que está en el campo «Object To Find» es el mismo objeto que tiene asignado el Script.

Fig. 17: Al entrar en el modo juego la referencia que se asigna es la del GameObject que tiene el Script.

Forma 5: Encontrar la referencia de un GameObject que está como hijo de otro GameObject

Tal vez nos interesa obtener la referencia de un GameObject que sabemos que está como hijo de otro GameObject del que si tenemos la referencia, por ejemplo en la figura 18 vemos que el objeto ha encontrar está como hijo del GameObject que tiene asignado el script, esto lo podemos lograr porque contamos con la referencia del objeto padre y en consecuencia podemos accederlo y aplicar distintas acciones sobre él.

Fig. 18: El objeto que queremos encontrar está como hijo del objeto que tiene asignado el Script.

Así como el campo «gameObject», el campo «transform» es otra variable que viene definida en todo MonoBehaviour y hace referencia al componente Transform del GameObject al cual el Script está asignado.

Podemos usar la Transformación para acceder a los hijos que tenga ese GameObject, utilizando el método GetChild() con parámetro 0 de la clase Transform, esto dá como resultado la transformación del primer hijo que tenga el GameObject al cual este Script está asignado, pero como nos interesa obtener la referencia del GameObject no de su Transformación, utilizamos el operador punto y el campo «gameObject».

La instrucción queda como se observa en la línea 18 de la figura 19.

Instrucción para encontrar la referencia de un GameObject que se encuentra como hijo de otro GameObject en Unity
Fig. 19: Instrucción para encontrar la referencia de un GameObject que se encuentra como hijo de otro GameObject.

Forma 6: Encontrar la referencia de un GameObject que tiene una componente específica

Si sabemos que el GameObject que nos interesa encontrar tiene asignada una componente específica, como por ejemplo un componente «Camera», «Rigidbody», «AudioSource» o un Script que nostros mismo hayamos creado, podemos usar eso para dar con la referencia del GameObject.

Voy a crear un Script llamado «SomeScript» y lo voy a asignar al GameObject que queremos encontrar, como se observa en las figuras 20 y 21.

Fig. 20: Creación de un nuevo Script llamado «SomeScript».
Fig. 21: El Script se asigna al objeto que se quiere encontrar.

Utilizando la instrucción «FindObjectOfType<T>()», donde T es el tipo de objeto que estamos buscando (en nuestro caso es de tipo «SomeScript»), podemos encontrar la referencia de la instancia «SomeScript» que está asignada a ese GameObject, luego usando el operador punto podemos acceder al GameObject al cual ese Script está asignado.

La instrucción que hace todo esto la vemos en la línea 20 de la figura 22.

Instrucción para encontrar la referencia del objeto tipo
Fig. 22: Instrucción para encontrar la referencia del objeto tipo «SomeScript» y luego obtener el GameObject al cual está asignado.

Cuando se ejecute esta instrucción, Unity revisará todos los objetos de la jerarquía y cada una de sus componentes hasta dar con el objeto de tipo «SomeScript», cuando lo encuentra lo devuelve como resultado, pero como nos interesa el GameObject al cual está asignado ese Script, utilizamos el punto y accedemos al campo «gameObject». Si no hay ningún objeto que tenga asignada la componente «SomeScript» tendremos un error de referencia nula.

Para tener en cuenta, si tenemos más de un GameObject que tiene asignada la componente que estamos buscando, Unity nos devolverá la primer componente que encuentre en su registro, en este caso pueden surgir ambigüedades, podríamos obtener la referencia de un objeto distinto al que queremos.

Scroll al inicio
Secured By miniOrange