Encontrar componentes en Unity es la base para que tus scripts se comuniquen entre sí sin convertir tu proyecto en un espagueti de código. Aquí aprendes a usar GetComponent, GetComponentInParent y GetComponentInChildren para acceder a otros scripts y Game Objects desde tu jerarquía.
¿Qué hace GetComponent en Unity?
Cuando un Game Object tiene varios componentes, como un Rigidbody y un script propio, necesitas una forma de que esos componentes se hablen entre sí. Ahí entra GetComponent, un método genérico que busca un componente dentro del mismo Game Object que es dueño del script.
Por ejemplo, si tu script vive en un objeto con Rigidbody, basta con escribir GetComponent<Rigidbody>() para acceder a la física de ese objeto [02:10].
¿Qué es GetComponent en Unity? Es un método genérico que devuelve una instancia de un componente que vive en el mismo Game Object que el script. Si el componente no existe, retorna null.
¿Cómo buscar componentes en padres e hijos?
No siempre el componente que necesitas vive en el mismo objeto. A veces está arriba o abajo en la jerarquía, y para eso Unity ofrece dos variantes muy útiles.
GetComponentInParent y GetComponentInChildren
- GetComponentInParent busca recursivamente hacia arriba: padre, abuelo, tatarabuelo. Útil cuando un hijo necesita identificar a su raíz.
- GetComponentInChildren hace lo contrario: busca en hijos, nietos, bisnietos. Si tu objeto tiene 100 hijos y cada uno tiene otros 100, la operación se vuelve costosa [03:25].
- Versiones en plural: añadiendo una s (
GetComponents, GetComponentsInParent, GetComponentsInChildren) obtienes un array con todos los componentes que coincidan, no solo el primero.
Por eso ninguno de estos métodos debería ir dentro de Update. Recuerda que Update se ejecuta hasta 60 veces por segundo, y multiplicar eso por una jerarquía profunda mata el rendimiento.
¿Cuándo usar FindObjectOfType?
Existe un método aún más amplio llamado FindObjectOfType, que busca en todos los Game Objects de la escena. Es la opción más cara de todas, así que úsalo solo en momentos puntuales como un Start o un evento, nunca en el ciclo de actualización.
Los scripts en Unity heredan de MonoBehaviour, así que lo que estos métodos retornan son instancias de esas clases, listas para que las uses como cualquier otro objeto.
¿Cómo destruir un Game Object al colisionar?
Para aterrizar la teoría, imagina una escena con varios carros y un bate que debe destruirlos al tocarlos. El script BateDestructor usa el método OnTriggerEnter, que recibe un Collider como parámetro [05:40].
El bate necesita tres cosas para que la colisión funcione:
- Un Capsule Collider marcado como trigger.
- Un Rigidbody en modo kinemático.
- El script BateDestructor asignado.
Dentro de OnTriggerEnter, el método Destroy elimina componentes o Game Objects. Si solo escribes Destroy(c), destruyes únicamente el Collider. Para borrar el objeto completo, necesitas Destroy(c.gameObject).
¿Por qué Destroy(c) no elimina todo el objeto? Porque c es solo el componente Collider. Para destruir el objeto entero debes acceder a su gameObject con c.gameObject.
El problema de los hijos con Collider
Al probar el bate, los carros se destruyen por partes. ¿Por qué? Porque cada carro está compuesto por varios hijos y cada hijo tiene su propio Collider. El Collider que recibe OnTriggerEnter pertenece al hijo, no a la raíz del carro.
Una solución ingenua sería usar transform.parent o incluso transform.parent.parent. Pero si el modelador del equipo reorganiza la jerarquía mañana —por ejemplo, agrupando las llantas dentro de un objeto Llantas— tu código se rompe. Y si subes demasiado, podrías borrar también al chofer que va sentado en el carro.
¿Cómo identificar un objeto con un script propio?
La solución elegante es marcar la raíz del carro con un script vacío llamado Carro. Ese script funciona como una etiqueta inteligente que sobrevive a cambios en la jerarquía.
Dentro de OnTriggerEnter, escribes:
csharp
Carro encontrado = c.GetComponentInParent<Carro>();
if (encontrado == null) return;
Destroy(encontrado.gameObject);
Lo que hace este bloque es subir por la jerarquía hasta encontrar un componente Carro. Si no lo encuentra, retorna null y el método sale sin destruir nada. Si lo encuentra, llama a Destroy(encontrado.gameObject) para borrar el carro completo, incluido el chofer [10:55].
Los símbolos < y > indican que estamos usando un método genérico o template: le pasas el tipo del componente que buscas y Unity te devuelve una referencia tipada.
¿Por qué usar un script vacío como Carro? Porque te permite identificar objetos sin depender de nombres, tags o posiciones en la jerarquía. Si el equipo reorganiza el prefab, tu código sigue funcionando.
Esta técnica te da una forma robusta de localizar al Game Object correcto, sin importar cuántos niveles de hijos o padres haya entre el Collider y la raíz. ¿Has tenido este problema con jerarquías profundas en tus proyectos? Cuéntalo en los comentarios.