오늘 배울 내용
- 오브젝트 풀
- 파티클 시스템
- 오디오
Instantiate 함수
Object Pooling
- 미리 생성된 객체를 필요할 때
꺼내고/넣고 쓰는 방식
1. Instantiate 함수 Unity 내부에서 일어나는 일
1-1. 메모리 할당 및 직렬화 해제
1-2. 역직렬화(Deserialization)
- Instantiate 함수 호출 시, 역직렬화 발생
1-3. 리플렉션 비용 발생
- 프리팹(Prefeb)을 복사(Instantiate)할 때,
어떤 데이터와 컴포넌트가 붙어 있는지 일일이 확인해서 복붙 (역시 CPU가 부담)
1-4. 드로우콜 부담
- Awake() {}
- Start() {}
- Update() {}
-> 위 이벤트 함수를 호출하는 스크립트가 붙은 오브젝트 -> 천개 단위로 있다.
2. 오브젝트 풀링
생성 비용 -> 활성화 비용으로 치환하는 기술
-
화면에 필요한 양만큼 미리 오브젝트를 메모리에 적재해서 사용
-
객체 파괴(Destroy)대신 -> SetActive(False)를 사용
-> 메모리 할당/해제 막고 GC 발생 원천 차단
-
메모리 점유율을 일정하게 유지
(+추가) Instantiate 함수가 오브젝트 풀보다 느린 이유
1. 데이터 전송 (HDD/SDD -> RAM -> VRAM)
- 전송해야 될 데이터가 크면 클수록, CPU 부담 발생 -> 게임이 '렉' 걸림...
2. 쉐이더 컴파일
3. 오브젝트 풀링 장점
CPU & RAM 최적화
- `생성/삭제` 연산 횟수 최소화
-> 재사용성의 장점 (오브젝트 ON/OFF)
-> 매 프레임 게임 안정성 유지, GC렉 방지
4. 오브젝트 풀 -> 메서드
-
메모리 단편화(Fragment)
-
GC 호출 최소화
5. 유니티 Profiler 테스트
[Instantiate/Destroy]

[옵젝 풀]

6. 오브젝트 풀 실전 사례
- 오디오(Audio)
- 파티클(Particle)
Q. 풀링은 언제 사용하면 안될까?
- 씬에 객체 개수가 그렇게 많지 않다면 + 빈번하게 생성/파괴가 일어나지 않는다면
7. 오브젝트 풀 어떤 자료구조 사용하는가?
- List
- Stack
- Queue
- Dictionary
- HashSet
- Array
- LinkedList
7-1. List (비권장)
- 특징: 순서가 있고 인덱스 접근이 가능하다.
- 문제점: 중간 데이터를 삭제하거나 삽입할 때 뒤의 데이터를 당겨오거나 밀어내는
오버헤드가 발생 풀링의 목적인 '최적화'에 부합하지 않아서 단독으로는 잘 쓰이지 않는다.
7-2. Stack (성능 중시) - "CPU 캐시 효율을 극대화하여 0.1ms라도 아껴야 할 때"
- 특징: 후입선출(LIFO)
- 사용사례:
대량의 탄막/탄피: 방금 사용하고 반납된 '따끈따끈한' 객체는 메모리의 캐시(Cache)에 남아있을 확률이 매우 높다. 이를 즉시 재사용하면 CPU 연산 속도가 비약적으로 향상된다.
동적 확장: 필요한 만큼만 조금씩 늘려가며 사용할 때, 최근 생성된 객체를 우선 사용하므로 `캐시 적중률(Cache Hit) 이 최상이다.
- 가치:
퍼포먼스 최상. 자원이 한정적인 모바일 환경이나 대규모 탄막 게임에서 필수이다.
7-3. Queue(★안정성 중시) - "예외 없는 초기화와 시스템의 균일한 동작이 중요할 때"
- 특징: 선입선출(FIFO)
- 사용 사례:
파티클/이펙트: 연출 시간이 제각각인 이펙트들을 골고루 순환시켜, 특정 객체만 과부하가 걸리는 것을 방지하고 파티클 연산의 꼬임을 막습니다.
- `버그 탐지(QA): 100개중 1개라도 초기화(Reset) 로직이 잘못되었다면, 순환 구조상 무조건 버그가 발견된다. "안걸리고 넘어가는 버그"를 원천 차단한다.
- 가치:
디버깅과 시스템 안정성. 로직이 복잡한 대작 프로젝트나 개발 초기 단계에서 권장
7-4 Dictionary(관리의 핵심) - "수많은 종류의 프리팹을 하나의 매니저에서 관리할 때"
- 특징: 키(Key)를 통해 원하는 바구니(Value)를 즉시 찾는다.(O(1)의 속도)
- 실무 활용:
Enum이나 GameObject(Prefab) 자체를 키값으로 사용하여, 어떤 물건을 빌려줄지 결정하는 '거대 창고 관리 대장' 역할을 한다.
- 주의: 메모리를 다소 점유하므로 키값을 너무 남발하지 않도록 주의해야 한다.
[실무] 자주 사용하는 구조
Dictionary<키,자료구조<키>>
Dictionary<Enum,Queue<GameObject>>
Dictionary<Enum,Stack<GameObject>>
오브젝트 풀 구조
- PoolManager.cs -> 객체를 꺼내서 On(Get 함수) / (Release)OFF
- Object Script : IPoolable -> 상태 초기화(OnSpawn 함수) 및 돌려주기(OnDespawn 함수)
- Object Script : IPoolable -> 상태 초기화(OnSpawn 함수) 및 돌려주기(OnDespawn 함수)
- Object Script : IPoolable -> 상태 초기화(OnSpawn 함수) 및 돌려주기(OnDespawn 함수)...
Particle System
협업 프로세스
- VFX/이펙트 아티스트 or Assets
- 클라이언트 개발자
- 제작된 파티클 프리팹 -> 오브젝트 풀 등록 -> 게임 로직에 맞춰서 호출되는 코드 작성
기본 속성
- Main Module:
Start Lifetime, Start Speed등 파티클의 초기 설정을 결정
- Simulation Space:
World = 잔상 효과
- Emission: 파티클 생성 빈도를 결정
- 단발성 피격 효과는
Rate over Time X Bursts(한꺼번에 뿜어내기) 사용
- Shape: 파티클이 방출되는 모양(구체, 원뿔, 박스 등)을 정의
- Color over Lifetime: 시간이 지남에 따라 파티클의 색상이나 투명도(Alpha)를 변화
- Size over Lifetime: 입자가 크기를 변화를 줌(역동성)
- Renderer: 파티클 시각적 외형을 결정
파티클 초기화 함수
- 파티클 OFF -> 초기화X -> 파티클 켜진 상태 잔상 남은 상태에서 어색하게 Play 됨
ps.Clear();
ps.Stop(ture, ParticleSystemBehaviour.StopEmittingAndClear);
ps.Play();
Audio
유니티 오디오 3요소
- Audio Listener (귀)
- Audio Source (스피커)
- Audio Clip (음원)
Audio Clip
Load type
- Deconpress on Load(★)
- 짧은 효과음(SFX)
- Compressed In Memory
- 일반적인 소리
- 메모리에 압 올리고 -> 재생시 압축 풀림
- Streaming
- 배경음(BGM)
- PCM
- 무압축 고음질 데이터
- Vorbis(★)
- 압축률이 좋음 -> 실무에서 자주 사용
- ADPCM
- PCM보다 용량 작음
- Force To Mono
- 채널이 하나로 합쳐짐 -> 용량이 절반
AudioSource
핵심 속성
- Priority
- 0~256설정 가능 -> 주로 배경음은 0 설정
- Spatial Blend
- 01 (2D3D)
- 0 (2D - BGM, UI)
- 1 (3D - 발소리, 효과음)
- Volume & Pitch
- Pitch: 0.9~1.1 사이로 조정할 때 사운드 풍부
- Play On Awake
- 체크 시, 게임 시작과 동시에 시작
거리 감쇄 (FallOff)
- Min Distance / Max Distance: 소리 거리 설정
- Rolloff Mode
- 평시: Logaritmic
오디오 실행 함수
- Play()
- 기존 소리 끊고 새로 시작
- PlayOneShot()
- 기존 소리에 '중첩'해서 재생