Quick Reference
GetComponent 계열은 필요한 위치와 의존성의 성격에 따라 고릅니다. 같은 GameObject의 필수 Component는 초기화 시 가져와 검사하고, 씬·prefab의 외부 연결은 Inspector reference로 보이는 편이 유지보수에 유리합니다.
| 필요 대상 | API 또는 연결 | 반환/실패 | cache 판단 |
| --- | --- | --- |
| 같은 GameObject의 필수 Component | TryGetComponent(out field) | 없으면 false | 보통 Awake에 cache |
| 같은 GameObject의 선택 Component | GetComponent<T>() | 없으면 null | 반복 사용하거나 존재 확인이 필요할 때 |
| child / parent | GetComponentInChildren, GetComponentInParent | 계층 범위와 inactive 포함 여부에 따름 | 탐색 결과가 안정적으로 유지될 때 |
| 다른 씬·prefab 대상 | [SerializeField] | Inspector에서 누락 확인 가능 | cache가 아니라 의존성을 명시 |
[RequireComponent(typeof(Rigidbody))]
public sealed class PlayerMover : MonoBehaviour
{
private Rigidbody body;
private void Awake()
{
if (!TryGetComponent(out body))
{
enabled = false;
}
}
}조회 범위와 반환값
GetComponent<T>()는 호출한 Component와 같은 GameObject만 검사합니다. Component가 없으면 null이고, 같은 타입 Component가 여러 개면 원하는 인스턴스가 어떤 것인지 명확히 하기 어려워질 수 있습니다. TryGetComponent<T>(out T component)는 없음을 분기할 때 null 비교 대신 성공 여부를 바로 읽는 형태입니다.
GetComponentInChildren<T>()와 GetComponentInParent<T>()는 계층을 포함해 찾습니다. child 검색의 기본 overload는 inactive GameObject를 포함하지 않으므로, 비활성 UI·무기 슬롯처럼 inactive 대상까지 찾아야 하면 GetComponentInChildren<T>(true)를 명시합니다. 이 선택은 "지금 비활성인 객체도 의존성으로 인정하는가"라는 설계 판단입니다.
[SerializeField] private Transform muzzle;
private ParticleSystem muzzleFlash;
private void Awake()
{
// muzzle 자체가 Inspector에서 연결됐는지 먼저 확인합니다.
if (muzzle != null)
{
muzzle.TryGetComponent(out muzzleFlash);
}
}GameObject.Find, 이름·tag 탐색은 씬 구조가 변할수록 대상이 모호해질 수 있습니다. 정말 동적으로 발견해야 하는 시스템이라면 찾는 범위, 여러 후보일 때의 선택, spawn/unload 뒤 cache 무효화까지 코드로 드러냅니다.
cache와 초기화 시점
cache는 "항상 성능을 위해"가 아니라, 같은 의존성을 반복해서 쓰고 그 참조가 유효한 생명주기가 분명할 때 씁니다. 같은 GameObject의 Rigidbody·Animator·Collider는 Awake에서 cache하는 패턴이 읽기 쉽습니다. 반면 pool에서 child가 교체되거나 Addressables instance가 재생성된다면 이전 참조가 더 이상 맞지 않을 수 있으므로, 생성/대여 시점에 다시 연결합니다.
RequireComponent는 script를 붙이는 순간 빠진 타입을 추가해 setup 오류를 줄입니다. 기존 prefab을 자동 수정하지 않고 runtime 제거까지 막지 않으므로, 필수 dependency에는 TryGetComponent 실패 처리와 asset migration을 함께 둡니다. OnValidate는 Editor에서 연결 누락을 경고하기 좋지만 build runtime의 보증 수단은 아닙니다.
private void OnValidate()
{
if (!TryGetComponent<Rigidbody>(out _))
{
Debug.LogWarning("Rigidbody is required for PlayerMover.", this);
}
}자주 틀리는 부분
| 증상 | 원인 | 수정 |
|---|---|---|
GetComponent가 null | 대상 Component가 다른 GameObject나 child에 있음 | same object인지, 계층 탐색 또는 Inspector reference가 맞는지 확인 |
| 비활성 child가 검색되지 않음 | includeInactive 기본값 사용 | 정말 필요한 경우에만 true overload 사용 |
| cache한 reference가 pool 뒤에 엉뚱한 대상 | 재생성·교체 lifecycle을 고려하지 않음 | spawn/rent·return 시 cache를 재획득하거나 해제 |
RequireComponent를 붙였는데 기존 prefab이 고장 | attribute가 이미 존재하던 instance를 보정하지 않음 | prefab migration과 validation 추가 |
| 매 프레임 탐색이 문제인지 불명확 | 측정 없이 일괄 cache 또는 일괄 최적화 | Profiler에서 hot path인지 확인하고 반복 탐색만 줄임 |
참고 링크
3 sources