1. 게임 오브젝트(GameObject)와 컴포넌트(Component)
게임 오브젝트란?
유니티에서 게임 오브젝트는 씬(Scene)에 존재하는 모든 대상의 기본 단위입니다.
- 넓은 범위의 개념: 플레이어, 몬스터, 아이템뿐만 아니라 눈에 보이지 않는 공기, 관리자 시스템 등도 모두 오브젝트입니다.
- 빈 껍데기: 오브젝트 그 자체는 아무런 기능이 없는 '상자'와 같습니다. 이 상자에 어떤 '기능'을 담느냐에 따라 역할이 결정됩니다.
컴포넌트(Component) 기반 설계
오브젝트에 실질적인 기능과 성질을 부여하는 것이 바로 컴포넌트입니다.
- Transform 컴포넌트: 모든 게임 오브젝트가 예외 없이 가지는 기본 컴포넌트입니다. 오브젝트의 위치(Position), 회전(Rotation), 크기(Scale) 정보를 담고 있습니다.
- 기능의 결합: 게임 오브젝트(상자) + Mesh Renderer(외형) + Rigidbody(물리) + Script(동작) = 플레이어 캐릭터 완성!
2. 오브젝트의 상속과 참조
상속(Parenting) 구조
유니티는 여러 오브젝트를 하나로 묶어 관리하기 위해 상속(Hierarchy) 개념을 사용합니다.
- 장점: 부모 오브젝트를 움직이면 자식 오브젝트들이 함께 움직이므로 그룹화된 제어가 간편합니다.
- 주의점: 상속 단계가 너무 깊어지면(Deep Nesting) 데이터 접근이 어려워지고, 연산량이 증가하여 성능 저하 및 유지보수의 어려움을 초래할 수 있습니다.
컴포넌트 참조하기 (Scripting)
스크립트에서 특정 오브젝트의 기능을 가져오기 위해 사용하는 주요 함수들입니다.
| 함수명 | 설명 |
| GetComponent<T>() |
해당 오브젝트에서 타입 T의 컴포넌트 하나를 반환
|
| GetComponents<T>() |
해당 오브젝트의 모든 타입 T 컴포넌트를 배열로 반환
|
| GetComponentInChildren<T>() |
자신과 자식 오브젝트를 순회하며 타입 T의 컴포넌트 탐색
|
| GetComponentInParent<T>() |
자신과 부모 오브젝트를 순회하며 타입 T의 컴포넌트 탐색
|
3. 프리팹(Prefab): 게임의 설계도
프리팹은 미리 만들어둔 게임 오브젝트의 '설계도(템플릿)'입니다.
- 붕어빵틀과 붕어: 프리팹은 붕어빵틀이고, 이를 통해 씬에 배치된 실제 오브젝트(인스턴스)는 붕어빵입니다.
- 재사용성: 한 번 만들어두면 에셋으로 저장되어 언제든 다시 꺼내 쓸 수 있습니다.
- 일괄 수정: 프리팹 원본을 수정하면 씬에 배치된 수많은 인스턴스에 변경 사항이 한꺼번에 적용되어 유지보수가 매우 쉽습니다.
4. 오브젝트의 생성과 파괴 (Creation & Destruction)
게임 도중 총알이 발사되거나 몬스터가 죽는 등 동적인 변화를 처리하기 위해 생성과 파괴 함수를 사용합니다.
주요 함수
- 생성: Instantiate(GameObject prefab); 런타임에 동적으로 오브젝트를 소환합니다.
- 파괴: Destroy(GameObject object); 오브젝트를 제거합니다. 단, 호출 즉시 사라지는 것이 아니라 해당 프레임이 끝난 후에 정리됩니다.
// 1. 오브젝트 생성 (기본)
// 매개변수로 입력된 GameObject를 씬에 생성합니다.
Instantiate(GameObject prefab);
// 2. 위치와 회전을 지정하여 생성 (권장)
// 생성과 동시에 위치(Vector3)와 회전(Quaternion)을 설정합니다.
Instantiate(prefab, position, rotation);
// 3. 오브젝트 파괴
// 지정된 오브젝트를 씬에서 제거하고 메모리에서 해제 준비를 합니다.
Destroy(gameObject);
// 4. 지연 파괴
// 지정된 시간(초)이 지난 후 오브젝트를 파괴합니다. (예: 3초 후 제거)
Destroy(gameObject, 3.0f);
⚠️ 메모리 관리와 최적화 (중요!)
오브젝트의 생성과 파괴는 메모리 힙(Heap) 할당과 관련이 깊습니다.
- 가비지 컬렉션(GC) 발생: Destroy를 자주 호출하면 유니티의 메모리 관리 시스템인 GC가 작동하여 불필요한 메모리를 수거하는데, 이 과정에서 프레임 드랍(렉)이 발생할 수 있습니다.
- 해결책 - 오브젝트 풀링(Object Pooling): 총알처럼 자주 쓰이는 물체는 매번 만들고 부수는 대신, 미리 많이 만들어두고 **활성화/비활성화(Active/Inactive)**만 하여 재사용하는 기법을 사용해야 합니다.
생성과 파괴의 메모리 흐름
오브젝트가 생성되고 파괴될 때 메모리에서는 다음과 같은 일이 일어납니다.
- 생성 (Creation): Instantiate()가 호출되면 메모리(Heap)에 데이터가 할당되고 오브젝트가 활성화됩니다.
- 파괴 (Destruction): Destroy()가 호출되면 오브젝트는 즉시 제거되지 않고, 보통 해당 프레임이 끝난 후에 제거 예약이 됩니다.
- 메모리 해제: 유니티의 메모리 관리 시스템인 **가비지 컬렉션(GC, Garbage Collection)**이 더 이상 참조되지 않는 파괴된 오브젝트의 메모리를 수거합니다.
5. 성능 최적화: 오브젝트 풀링 (Object Pooling)
반복적으로 오브젝트를 생성하고 파괴하면 가비지 컬렉션이 자주 발생하여 게임이 순간적으로 멈추는 '렉(Freeze)' 현상이 발생할 수 있습니다. 이를 방지하기 위한 필수 기법이 오브젝트 풀링입니다.
- 개념: 총알, 적 캐릭터처럼 자주 사용되는 오브젝트를 미리 대량으로 생성해 '풀(Pool)'에 담아둡니다.
- 방식: 필요할 때 Instantiate 대신 미리 만든 오브젝트를 **활성화(Active)**하고, 필요 없어지면 Destroy 대신 **비활성화(Inactive)**하여 재사용합니다.
- 장점: 매번 메모리를 할당/해제하지 않으므로 CPU 부담을 줄이고 프레임 드랍을 방지할 수 있습니다.
📝 오늘의 요약
- 게임 오브젝트는 컴포넌트를 담는 상자이며, Transform은 필수이다.
- 상속은 편리하지만 너무 깊어지면 성능과 가독성을 해친다.
- 프리팹은 효율적인 대량 생산과 관리를 위한 설계도이다.
- 생성과 파괴는 메모리에 부담을 주므로, 빈번한 작업은 오브젝트 풀링으로 최적화하자.
"프로그래밍에서의 생성과 파괴는 단순한 동작이 아니라 메모리 할당과 해제입니다. 힙 메모리의 특성을 이해하고 최적화를 고민하는 개발자가 됩시다!"
'유니티 > UnityEngine3D 입문 및 스크립팅 기초' 카테고리의 다른 글
| 코루틴 (0) | 2026.01.02 |
|---|---|
| 물리, 충돌 (0) | 2026.01.02 |
| Transform 및 위치 이동 (0) | 2026.01.01 |
| 유니티 개요 (0) | 2026.01.01 |