안녕하세요! 유니티로 게임을 개발하다 보면 가장 많이 치는 코드가 무엇일까요? 아마도 transform.position 다음으로 GetComponent가 아닐까 싶습니다.
"내 오브젝트에 붙은 다른 컴포넌트를 가져오고 싶다!" 혹은 "내 자식 오브젝트의 스크립트를 제어하고 싶다!" 할 때 필수적인 이 함수들.
오늘은 **GetComponent 4대장(기본, InChildren, InParent, plural)**의 정확한 차이점과, 실무에서 꼭 지켜야 할 성능 최적화 꿀팁까지 정리해 보겠습니다.
1. 가장 기본: GetComponent<T>()
가장 흔하게 사용하는 함수입니다. "현재 스크립트가 붙어 있는 바로 그 GameObject" 안에서 컴포넌트를 찾습니다.
- 탐색 범위: 내 GameObject 하나.
- 특징: 찾고자 하는 컴포넌트가 없으면 null을 반환합니다.
void Start()
{
// 내 오브젝트에 붙어있는 Rigidbody 가져오기
Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null)
{
rb.AddForce(Vector3.up * 10);
}
}
2. 자식들 다 나와: GetComponentInChildren<T>()
나(현재 오브젝트)를 포함하여 내 하위(자식, 손자...) 계층 구조를 뒤져서 컴포넌트를 찾습니다.
- 탐색 범위: 나(Self) + 모든 자식(Children) 오브젝트.
- 주의점:
- 나 자신부터 검사합니다. 내 오브젝트에 해당 컴포넌트가 있다면 자식 껀 무시하고 내 껄 반환합니다.
- 깊이 우선 탐색(DFS) 방식으로 찾으며, 하나라도 찾으면 즉시 탐색을 종료하고 반환합니다.
- 비활성화(activeSelf == false)된 오브젝트는 기본적으로 무시합니다 (오버로딩으로 포함시킬 수 있음).
// 내 자식들(혹은 나) 중에 MeshRenderer가 있으면 하나만 가져와!
MeshRenderer childMesh = GetComponentInChildren<MeshRenderer>();
3. 부모님 계신가요: GetComponentInParent<T>()
이번엔 반대로 위쪽(부모)으로 올라가며 탐색합니다.
- 탐색 범위: 나(Self) + 부모(Parent) + 부모의 부모...
- 특징: 역시 나 자신부터 검사합니다. 주로 UI 버튼에서 상위 캔버스의 특정 스크립트를 찾거나, 캐릭터의 파츠(손, 발)에서 몸통(Main Body) 스크립트를 찾을 때 유용합니다.
// 내 위쪽 계층에 있는 PlayerController 스크립트 찾기
PlayerController player = GetComponentInParent<PlayerController>();
4. 싹 다 긁어모아: GetComponents<T>() (뒤에 's' 주의!)
위의 함수들은 조건에 맞는 컴포넌트를 '딱 하나'만 찾아옵니다. 하지만 한 오브젝트에 BoxCollider가 3개 붙어있다면요? 혹은 자식들에 있는 모든 Enemy 스크립트를 관리하고 싶다면요?
이때 s가 붙은 함수들을 사용합니다. (GetComponents, GetComponentsInChildren 등)
- 반환 타입: 해당 컴포넌트들의 **배열(T[])**을 반환합니다.
void Start()
{
// 내 자식들에 있는 모든 'Monster' 스크립트를 가져와서 배열에 담음
Monster[] monsters = GetComponentsInChildren<Monster>();
// 반복문으로 전체 제어
foreach (Monster m in monsters)
{
m.Die(); // 전멸 시키기
}
}
💡 [중요] 실무 개발자의 성능 최적화 Tip
GetComponent 시리즈는 편리하지만, 내부적으로 GameObject를 뒤지는 연산이 들어가기 때문에 비용이 꽤 비싼 함수입니다.
1. 절대 Update() 문에 넣지 마세요!
초보자들이 가장 많이 하는 실수입니다.
// ❌ 최악의 예시 (매 프레임마다 찾으러 다님)
void Update() {
GetComponent<Rigidbody>().velocity = Vector3.zero;
}
// ✅ 좋은 예시 (캐싱 사용)
Rigidbody rb;
void Start() {
rb = GetComponent<Rigidbody>(); // 시작할 때 한 번만 찾아서 저장
}
void Update() {
rb.velocity = Vector3.zero; // 저장된 변수 사용
}
2. TryGetComponent를 애용하세요 (Unity 2019.2+)
최신 유니티 버전에서는 TryGetComponent 사용을 권장합니다. 컴포넌트를 가져오는 동시에 null 체크까지 안전하게 처리하며, 메모리 할당(GC) 측면에서도 미세하게 더 유리합니다.
// 이렇게 쓰세요!
if (TryGetComponent<Rigidbody>(out Rigidbody rb))
{
// rb가 null이 아닐 때만 실행됨
rb.mass = 10;
}
마치며
오늘은 유니티 스크립팅의 기초인 GetComponent 패밀리에 대해 알아보았습니다.
- 내꺼 찾을 땐: GetComponent
- 자식꺼 찾을 땐: GetComponentInChildren
- 부모꺼 찾을 땐: GetComponentInParent
- 여러 개 찾을 땐: GetComponents
이 4가지만 상황에 맞춰 잘 쓰고, 캐싱(Caching)만 습관화한다면 여러분의 코드는 훨씬 깔끔하고 빨라질 것입니다.
'개발 > Unity' 카테고리의 다른 글
| (Unity) 인스펙터 창을 깔끔하게! [Header] 속성 완벽 가이드 (0) | 2025.12.20 |
|---|---|
| (Unity) transform.position은 Vector3인데, 왜 Vector2 변수에 그냥 들어갈까? (0) | 2025.12.20 |
| (Unity) 근처 적을 스캔하고 최단 거리 대상 찾기 (1) | 2025.12.13 |
| (Unity) 회전하는 오브젝트 구현 가이드 (0) | 2025.12.12 |
| Unity 내장 오브젝트 풀(Object Pool) 사용하기 (0) | 2025.10.13 |