0514 - <팀 프로젝트 5일차> Unity부트캠프 [25일차]

Hyeon O·2025년 5월 14일

Unity_BootCamp 6주차

목록 보기
3/5

📚 오늘은….

기존 투사체에 오브젝트 풀링 시스템을 다른 팀원이 만들어둔 기반으로 적용하는 작업을 진행하였다.

💡오늘 진행한 프로젝트 과정

팀원이 만들어둔 오브젝트풀링을 투사체에 적용하는과정에서 만난 문제들이다.

  • NullReferenceException
    • SpawnProjectile에서 PoolManager.GetObjectnull을 반환해 GetComponent 호출 시 NRE 발생
  • KeyNotFoundException
    • ReturnProjectile에 넘긴 키(data.dataKey 혹은 data.name)가 pools에 등록된 키와 달라서 큐를 찾을 수 없음
  • 풀링이 동작되지 않음
    • SpawnProjectile에서 매번 Instantiate(data.prefab,…)만 호출해 풀에서 꺼내지 않고, 반환 시에도 올바른 키로 Return되지 않음

원인 분석은 다음과 같다.

  • 키 불일치
    • InitPool()에선 data.name을, SpawnProjectileDestroyProjectile에선 data.dataKey를 사용
  • 풀 사용 흐름 무시
    • 생성 시 Instantiate, 반환 시 ReturnProjectile을 모두 사용하지 않고 혼용
  • 에디터 설정 누락
    • PoolSetting에 등록된 dataKey와 실제 ProjectileDatadataKey가 일치하지 않음

즉, 발사체를 생성할 때 풀에서 꺼내오지 않고 사용해서 발생한 오류와

투사체 오브젝트의 키 값에서 불일치 때문에 발생한 문제였다.

해결 방법은 다음과 같다.

  1. 키를 ScriptableObject의 dataKey(혹은 이름)으로 통일
  2. 생성 시 풀에서 꺼내기 →
/ ProjectileManager.cs
GameObject go = PoolManager.Instance.GetObject(data.dataKey, position);
var ctrl = go.GetComponent<ProjectileController>();
ctrl.Initialize(data, direction, atk);
return ctrl;
  1. 반환 시 풀로 넣기 (ProjectileController.DestroyProjectile)
// ProjectileController.cs
string key = data.dataKey;
ProjectileManager.Instance.DespawnProjectile(key, gameObject);

이를 구현하는 과정에서

이전 데이터 구조가

WeaponData : ScriptableOject
{
	무기 공격력
	공격 속도
	공격 범위
	...
	투사체 수
	화살 퍼짐 각도
	
}

ProjectileData : weaponData
{
	발사체 프리팹
	발사체 속도
	발사체 생명주기
	발사체 색
	..
}

위 구조에서

BaseData : ScriptableOject
{
	키 값
	프리팹
	
}
WeaponData : BaseData 
{
	무기 공격력
	공격 속도
	공격 범위
	...
	투사체 수
	화살 퍼짐 각도
	
}

ProjectileData : weaponData
{
	발사체 프리팹
	발사체 속도
	발사체 생명주기
	발사체 색
	..
}

이런식으로 계층을 잡았다.

BaseData에 정보로 오브젝트 풀링을 하기에

상속관계를 가지게 하였다.

하지만 이렇게 해보니

상속 구조를 좀 더 다르게 하면 좋을 것 같다는 생각을 하였다.

일단 시간 상 데이터 구조를 바꾸면 시간이 너무 걸릴 것 같아서

하지는 못했지만 시도해보려고 했던 구조는 다음과 같다.

    BaseData (공통 풀링 키 등)
           ├─ WeaponData  (id, atk, speed, range 등)
           │     ├─ MeleeWeaponData
           │     └─ RangedWeaponData (투사체 관련 필드 별도 정의)
           └─ ProjectileData (순수 투사체 전용 SO)

회고는 없다. 오늘은 못 잘 것 같기 때문이다.

profile
천천히, 꾸준하게, 끝까지

0개의 댓글