[20260212] Object Pool Pattern (feat. Audio, Particle)

SmartBear·2026년 2월 12일

Object Pool Pattern

Q. 우리가 게임을 만들 때 무엇을 많이 하는 것은?

A. Object 생성/파괴

  • Object 생성: Instatiate
  • Object 파괴: Destory

Goal

  1. Intantiate 함수의 문제점?
  2. Object Pool 배우는 이유는?
  3. Object Pool 구현을 위해서 최적의 자료 구조 선택은? (결국 알아야 하는 내용)

Instantiate

객체를 생성해주는 함수

  1. 메모리 할당 및 직렬화 해제
    • 메모리 할당 -> RAM 위에 올리는 단계
  2. 역직렬화
    • Intantiate 함수 호출 시, 역직렬화 발생
  3. 리플렉션 비용 발생
    • 프리팹(Prefab)을 복사(Instantiate)할 때, 어떤 데이터컴포넌트가 붙어있는지 일일이 확인해서 복사 붙여넣기를 실행 (CPU 부담)
  4. Draw-call 부담

참고: Script 내 빈 이벤트 함수(Awake, Update 등)을 호출하는 것도 CPU 에 부담을 준다.

Instantiate 함수가 Object Pool 보다 느린 이유

  • 데이터 전송 : (Disk -> RAN -> VRAM). 전송 데이터 크기에 따라 CPU 부하 발생 -> 게임 발생.
  • 셰이더 컴파일 : GPU 에서 화면에 뿌릴 옷을 입혀주는 과정. Cache 에 없으므로 GPU 부하 발생.

Object Pooling

미리 생성된 객체를 필요할 때 꺼내고/넣고 쓰는 방식. 생성 비용 -> 활성화 비용으로 치환하는 기술

  1. 화면에 필요한 양만큼 미리 오브젝트를 메모리에 적재해서 사용.
  2. 객체 파괴 (Destory) 대신 -> SetActive(false) 를 사용.
    • 메모리 할당/하제 막고 GC 발생 최소화
  3. 메모리 점유율을 일정하게 유지

장점

  • **CPU & RAM 최적화**
    • 생성/삭제 연산 횟수 최소화
    • 재사용성의 장점 (오브젝트 On/Off)
    • Frame 안정성 유지. GC 렉 방지.
  • **메모리 관점 이득**
    • 메모리 단편화 (Fragmentation) 해결에 유리
      • 빈번한 할당/하제는 메모리 공간을 잘게 쪼개어 큰 데이터를 올릴 공간이 부족하게 만듬.
    • GC 호출 최소화

Unity Profiler

  • 단순 Instantiate 후 Destory 했을 때 프로파일

Object Pool 실전 사례

오디오(Audio)

  • AudioSource 컴포넌트
  • 사용 사례: 피격음, 총 발사, 타격음, 폭발음, 걷거나 뛰는 소리 등 이벤트가 많은 소리

파티클(Particle)

  • 사용 사례: 피격 이펙트, 트레일(궤적)

Q. Object Pool이 굳이 필요하지 않는 경우는?

A. 빈번한 생성/파괴가 일어나지 않거나 씬에 존재 오브젝트가 많이 않을 경우.

Object Pool 유효 자료 구조

  • List: 순서. Index로 접근 가능. 데이터 삭제시 당겨오는 비용 발생.
  • Stack: 후입선출. 메모리 캐시 효율이 좋음.
    • 빠른 재사용이 필요할 떄. 사운드/이팩트 등
  • Queue: 선입선출. 안정성이 좋다.
    • 빈번하게 생성하는 Object.
  • Dictionary: 키(Key) -> 값(Value) 찾기. 메모리 점유량 많음.
Dictionary<Enum, Queue<GameObject>>
Dictionary<Enum, Stack<GameObject>>

오브젝트 Pool 구조

  • PoolManager.cs ; 객체 On/Off
  • Object.cs ; 상태 초기화 및 돌려주기(Off)
  • IPoolable.cs ; Pool 관련 함수 인터페이스

오디오 (Audio)

유니티 오디오 3요소

  1. Audio Listener
  2. Audio Source
  3. Audio Clip

Audio Clip

  • Load Type
    • Decompress On Load : 짧은 효과음. Load 시 압축 해제 (Default)
    • Compressed In Memory : Build 시 압축되어 메모리에 올라감. (잘 안씀)
    • Streaming : BGM 처럼 긴 배경음에서 씀. 메모리에 올리지 않고 사용.
  • Compression Format
    • PCM : 무압축 고음질
    • Vorbis: 품질 대비 압축률이 좋음 (대부분 이것 사용. Default)
    • ADPCM: PCM 보다는 용량이 작음. 노이즈 섞인 짧은 소리.
  • Force To Mono
    • 강제로 Mono 로 변경. 용량도 작아짐.

Audio Source

  • Priority
  • Spatial Blend: 2D (UI 등) / 3D (발소리등)
  • Volumn: 말그대로 불륨
  • Pitch: 소리 빠르게 혹은 느리게 재생
  • 3D Sound Setting
    • Volumn Rolloff; 거리에 따른 소리 음량 낮아지고 높아지고
    • Max/Min Distance: 소리 발생 거리 조절

오디오 실행 함수

  • Play()
    • 기존 소리 끊고 새로 시작
    • BGM 교체
  • PlayOnShot()
    • 기존 소리에 중첩해서 재생

Audio Pool Manager

  • Audio 역시 자주 쓰이는 내용이 많기 때문에 필요시마다 불러와 실행하는 방식을 많이 채택한다.
  • 단, Audo 자체가 특정 부모 오브젝트에 붙어 있는 경우가 많기 때문에 한꺼번에 불려와 사용되는 경우가 더욱 많다.

파티클 (Particle)

협업 프로세스

  1. VFX (이팩트) 아티스트 or Assets
    • 파티클 모양, 색상, 텍스처 제작
  2. 클라 개발자
    • 제작된 파티클 프리팹 -> 오브젝트 풀 등록
    • Game Logic 에 맞춰 호출되는 코드 작성

기본 속성(자주 쓰는 속성)

  • Main Module: Start Lifetime, Start Speed 등 파티클의 초기 설정을 결정
    - Simulation Space: World = 잔상 효과
  • Emission: 파티클 생성 빈도를 결정
    - 단발성 타격 효과는 Rate over TimeBursts(한꺼번에 뿜어내기) 사용
  • Shape: 파티클이 방출되는 모양(구체, 원뿔, 박스 등)을 정의
  • Color over Lifetime: 시간이 지남에 따라 파티클의 색상이나 투명도(Alpha)를 변화
    - ex: 연기가 서서히 투명해지는 효과
  • Size over Lifetime: 입자가 크기를 변화를 줌 (역동성)
  • Renderer: 파티클의 시각적 외형을 결정

파티클 리셋

  • 파티클 Off -> 초기화x -> 파티클 켜진 상태 잔상 남은 상태에서 어색하게 Play
  • 파티클 초기화 코드
ps.Clear(); 
// 위 것의 대체로
ps.Stop(ture, ParticalSystemBehavior.StopEmittingAndClear);
profile
Python Dev with Infra -> Game Programmer

0개의 댓글