GameObject.Find() / GetComponent<T>()
| Since: | C# 1.0(2002) |
|---|
How to use GameObject.Find() to search for a GameObject in the scene by name, and GetComponent<T>() to retrieve an attached component.
Syntax
using UnityEngine; // Searches for a GameObject by name in the scene (returns null if not found). GameObject obj = GameObject.Find(string name); // Searches for a GameObject by tag. GameObject obj = GameObject.FindWithTag(string tag); // Gets all GameObjects that match a tag. GameObject[] objs = GameObject.FindGameObjectsWithTag(string tag); // Gets a component attached to this GameObject. T comp = GetComponent<T>(); // Searches this GameObject and its children. T comp = GetComponentInChildren<T>(); // Searches this GameObject and its parents. T comp = GetComponentInParent<T>(); // Adds a component to the GameObject. T comp = gameObject.AddComponent<T>();
Method List
| Method | Description |
|---|---|
| GameObject.Find(name) | Searches all active GameObjects in the scene by name. Inactive objects are not included. |
| GameObject.FindWithTag(tag) | Returns one GameObject with the specified tag. If there are multiple, any one of them is returned. |
| GameObject.FindGameObjectsWithTag(tag) | Returns all GameObjects with the specified tag as an array. |
| GetComponent<T>() | Returns the component of type T attached to this GameObject. Returns null if not found. |
| TryGetComponent<T>(out T component) | Attempts to get the component. Returns true if found, false otherwise (Unity 2019.2 and later). |
| GetComponentInChildren<T>() | Searches this GameObject and its children (depth-first) for a component of type T. |
| gameObject.AddComponent<T>() | Adds and returns a component of type T to this GameObject. |
Sample Code
A sample combining Inspector assignment, tag-based search, and GetComponent.
FindSample.cs
using UnityEngine;
public class FindSample : MonoBehaviour
{
// Assigning directly from the Inspector is the most efficient approach.
[SerializeField] private GameObject player;
[SerializeField] private Rigidbody2D myRigidbody;
void Start()
{
// Searches for a GameObject by name (use in Start, not Update).
GameObject enemy = GameObject.Find("Enemy");
if (enemy != null)
{
Debug.Log($"Enemy found: {enemy.transform.position}");
}
// FindWithTag() is faster than Find() for tag-based searches.
GameObject mainCamera = GameObject.FindWithTag("MainCamera");
if (mainCamera != null)
{
Debug.Log($"Main camera: {mainCamera.name}");
}
// Gets a component with GetComponent<>().
Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null)
{
rb.AddForce(Vector3.up * 10f);
}
// TryGetComponent combines component retrieval and null check.
if (TryGetComponent<Animator>(out Animator anim))
{
anim.SetTrigger("Jump");
}
// Searches children for a component with GetComponentInChildren.
AudioSource sfx = GetComponentInChildren<AudioSource>();
if (sfx != null)
{
sfx.Play();
}
// Gets multiple GameObjects by tag.
GameObject[] coins = GameObject.FindGameObjectsWithTag("Coin");
Debug.Log($"Coins: {coins.Length}");
}
}
Practical Pattern: Caching References
Find-family methods scan the entire scene and are expensive. The recommended pattern is to call them once in Awake() or Start() and store the result in a field.
CachedReference.cs
using UnityEngine;
public class CachedReference : MonoBehaviour
{
// Fields for caching.
private Rigidbody _rb;
private Animator _anim;
private AudioSource _audio;
private GameObject _uiRoot;
void Awake()
{
// Retrieve and cache components once in Awake().
_rb = GetComponent<Rigidbody>();
_anim = GetComponent<Animator>();
_audio = GetComponentInChildren<AudioSource>();
_uiRoot = GameObject.FindWithTag("UIRoot"); // Find-family: Awake/Start only
}
void Update()
{
// NG: Calling GetComponent in Update() scans every frame.
// GetComponent<Rigidbody>().AddForce(Vector3.up);
// OK: Use the cached field.
if (_rb != null)
_rb.AddForce(Vector3.up * 0.1f);
if (Input.GetKeyDown(KeyCode.Space) && _anim != null)
_anim.SetTrigger("Jump");
}
}
Practical Pattern: Dynamic Component Addition
A pattern for adding components at runtime with AddComponent. Useful for effects and temporary behaviors.
DynamicComponent.cs
using UnityEngine;
public class DynamicComponent : MonoBehaviour
{
void Start()
{
// Adds a Rigidbody in code if not already attached.
if (!TryGetComponent<Rigidbody>(out _))
{
Rigidbody rb = gameObject.AddComponent<Rigidbody>();
rb.mass = 2f;
rb.useGravity = true;
Debug.Log("Rigidbody added.");
}
// Adds and configures an AudioSource.
AudioSource audio = gameObject.AddComponent<AudioSource>();
audio.playOnAwake = false;
audio.volume = 0.8f;
// Checks for the presence of a Renderer.
bool hasRenderer = TryGetComponent<Renderer>(out Renderer rend);
Debug.Log($"Has Renderer: {hasRenderer}");
if (hasRenderer)
Debug.Log($"Material: {rend.material.name}");
}
}
Common Mistakes
Common Mistake 1: Using GameObject.Find() Inside Update()
GameObject.Find() scans the entire scene and is expensive. Using it inside Update() causes a significant performance drop every frame.
using UnityEngine;
public class FindInUpdateNG : MonoBehaviour
{
void Update()
{
// NG: Scans the entire scene every frame.
GameObject enemy = GameObject.Find("Enemy");
if (enemy != null)
transform.LookAt(enemy.transform);
}
}
The corrected version looks like this:
using UnityEngine;
public class FindInUpdateOK : MonoBehaviour
{
private Transform _enemyTransform; // Cache field
void Start()
{
// OK: Search once during initialization and cache the result.
GameObject enemy = GameObject.Find("Enemy");
if (enemy != null)
_enemyTransform = enemy.transform;
}
void Update()
{
// Uses the cached reference.
if (_enemyTransform != null)
transform.LookAt(_enemyTransform);
}
}
Common Mistake 2: Accessing GetComponent Return Value Without Null Check
GetComponent returns null when the component is not attached. Accessing it without a null check causes a NullReferenceException.
using UnityEngine;
public class NullCheckNG : MonoBehaviour
{
void Start()
{
// NG: Throws NullReferenceException if Rigidbody is not attached.
GetComponent<Rigidbody>().AddForce(Vector3.up * 10f);
}
}
The corrected version looks like this:
using UnityEngine;
public class NullCheckOK : MonoBehaviour
{
void Start()
{
// OK: TryGetComponent combines retrieval and null check in one call.
if (TryGetComponent<Rigidbody>(out Rigidbody rb))
{
rb.AddForce(Vector3.up * 10f);
}
else
{
Debug.LogWarning("Rigidbody is not attached.");
}
}
}
Overview
GameObject.Find() scans the entire scene, so calling it inside Update(), which runs every frame, causes a significant performance drop. Call it only once in Start() or Awake() and cache the result in a field. When possible, prefer assigning references directly in the Inspector.
Accessing a null return value from GetComponent<T>() causes a NullReferenceException. Always add a null check, or use TryGetComponent<T>() instead. For debug output, see Debug.Log(). For Unity math functions, see Mathf.
If you find any errors or copyright issues, please contact us.