🤔

GetComponent methods#

GetComponent, TryGetComponent, GetComponentInChildren, and other similar methods are perfect for dynamic runtime references like those gathered in a physics message or query.

It's preferable to use serialized references where possible.

Use with interfaces#

The GetComponent family of functions can return components that implement interfaces, making them powerful tools to work with composition.

Example#

using UnityEngine;

/// <summary>
/// Damages components marked with <see cref="IDamageable"/> that enters the attached trigger.
/// </summary>
public class DamageTrigger : MonoBehaviour
{
	[SerializeField] private int _damage = 100;

	void OnTriggerEnter(Collider collider)
	{
		if (!collider.TryGetComponent(out IDamageable damageable))
		{
			// Exit early, the collider's object doesn't have an IDamageable component.
			return;
		}

		// Call our Damage method.
		damageable.Damage(_damage);
	}
}

/// <summary>
/// Marks a component as capable of receiving damage.
/// </summary>
public interface IDamageable
{
	void Damage(int amount);
}

/// <summary>
/// Our player can receive damage from <see cref="IDamageable"/> sources.
/// </summary>
public class Player : MonoBehaviour, IDamagable
{
	public void Damage(int amount)
	{
		// ...
	}
}

Notes#

Garbage collection#

GetComponent#

Due to Unity null, GetComponent will always allocate in the editor, whereas using TryGetComponent will not.

Collection pools#

Unity provides various collection pool classes (introduced in 2021.1) that can be used in combination with the multi-object GetComponent functions. Do note that pooled collections can last the lifetime of your application, and care must be taken when allocating them.

using (ListPool<IDamageable>.Get(out var damageables))
{
	collider.GetComponentsInChildren(damageables);
	foreach (IDamageable damageable in damageables)
		damageable.Damage(_damage);
}

See ListPool.