방문자

오늘
—
어제
—
누적
—

불러오는 중

게임 개발 · 기술 동향 · 팀 블로그MIRO
헤드라인

Unity · 런타임 설계

Unity 투사체 풀링, 다시 쏘기 전에 초기화할 것들

대기 풀에서 투사체를 가져와 사용하고 초기화 후 반환하는 흐름과 풀이 가득 찼을 때 제거하는 분기
직접 제작한 도식: 투사체의 대여·반환과 상태 초기화 흐름.

사라진 투사체가 이전 상태를 기억한다면

연속 사격에서는 짧게 나타났다 사라지는 투사체가 반복됩니다. 매번 생성하고 파괴하는 대신 사용이 끝난 인스턴스를 보관했다가 다시 꺼내는 방식이 오브젝트 풀링입니다. Unity 6.0 공식 문서는 반복 생성 비용과 메모리 할당을 줄이는 용도로 이 패턴을 소개합니다. 다만 재사용하는 객체에는 이전 사용에서 바뀐 값도 남을 수 있습니다.

예를 들어 적을 관통한 횟수나 남은 수명이 초기화되지 않으면 새로 발사한 탄환이 곧바로 사라질 수 있습니다. 풀링을 적용할 때는 생성 횟수보다 먼저, 한 번의 사용이 어디서 시작하고 끝나는지 정의하는 편이 좋습니다.

네 가지 동작을 나눕니다

ObjectPool<T>는 생성, 가져오기, 반환, 제거 시 실행할 콜백을 받습니다. Get은 대기 중인 인스턴스를 꺼내고, 풀이 비어 있으면 생성 함수를 호출합니다. 사용이 끝나면 Release로 돌려보냅니다. 이미 보관 한도에 도달했다면 반환된 인스턴스에 제거 콜백이 호출됩니다.

이 구조에서 풀의 최대 크기를 동시 발사 수 제한으로 이해하면 곤란합니다. 꺼낼 객체가 없을 때의 생성과, 돌려받을 객체를 얼마나 보관할지는 별개입니다. 발사 수를 제한하려면 게임 규칙에서 활성 투사체 수를 따로 판단해야 합니다. 또한 이 API는 스레드 안전하지 않으므로 백그라운드 작업에서 직접 호출하지 않습니다.

초기화 목록을 객체 가까이에 둡니다

투사체라면 위치와 방향, 속도, 남은 수명, 충돌 이력을 확인할 수 있습니다. 이는 모든 프로젝트에 고정된 목록이 아니라 컴포넌트 구성에 맞춰 정할 점검 항목입니다. 공식 문서도 물리 상태, 애니메이션, 이벤트 구독 등 사용 중 바뀌는 상태를 정리하도록 안내합니다.

설계 예시로는 반환 함수에서 진행 중인 효과와 구독을 정리하고, 가져오기 함수에서 새 발사의 위치와 소유자 정보를 설정할 수 있습니다. 초기화 코드를 여러 무기 스크립트에 흩어 놓으면 새 무기를 추가할 때 일부 값만 빠지기 쉽습니다. 객체가 자신의 재사용 준비를 담당하게 하면 확인할 범위가 줄어듭니다.

반환은 한 번만 일어나야 합니다

충돌 처리와 수명 만료가 같은 투사체를 반환하려는 경우를 생각해 볼 수 있습니다. 개발 중에는 collection check로 중복 반환 오류를 찾고, 실제 동작에서는 사용 중인지 확인하는 상태와 반환 경로를 함께 정리합니다. 검사용 옵션 하나만으로 수명 관리가 완성되지는 않습니다.

검증은 같은 인스턴스를 두 번 사용하면서 시작 상태가 같은지 비교하는 것부터 시작할 수 있습니다. 다음으로 짧은 시간에 많은 탄환을 발사하고 모두 회수했을 때, 활성 객체가 남거나 이벤트가 중복 실행되지 않는지 봅니다.

성능 비교에서는 같은 발사 패턴과 기기 조건을 유지하고 생성 횟수, 프레임 시간, 메모리를 함께 기록하는 편이 좋습니다. 풀에 너무 많은 객체를 보관하는 비용도 살펴야 합니다. 이 글의 검증 절차는 실험 제안이며, 특정 게임에서 측정한 개선 수치를 제시하지 않습니다.

출처

댓글

이 글에 대한 생각을 남겨 주세요.

댓글 삭제

헤드라인

같은 카테고리의 글

게임 기술 전체 보기 ↗