대환장파티의 풀 반환 오류를 드디어 해결했다!
오류의 원인이 되는 부분이 많았어서 하나하나 찾기 쉽지 않았는데 튜터님의 도움으로 해결할 수 있었다.
[ 문제 상황 ]
1. 풀에 이미 반환된 오브젝트가 2번 반환을 시도
2. 풀에서 가져온 타입과 다른 타입으로 풀에 반환
3. 풀에 반환할 오브젝트의 인덱스 에러
(추후 에러 로그 정보 추가 예정)
[ 문제 원인 ]
1. 미니언 반환에서 이중 반환 및 타입이 맞지 않게 반환시키는 부분이 있었다.
public class Minion : Monster
{
public override void ReturnToVillage()
{
base.ReturnToVillage();
_summonerMonster.RemoveMinion(this);
GameManager.Instance.RemoveActiveList(this);
PoolManager.Instance.ReturnToPool<Minion>(data.poolTag, this);
}
}
public abstract class Monster : MonoBehaviour
{
public virtual void ReturnToVillage()
{
if (_coroutine != null) StopCoroutine(_coroutine);
_coroutine = StartCoroutine(FadeOutAndReturnToPool());
}
private IEnumerator FadeOutAndReturnToPool()
{
GameManager.Instance.RemoveActiveList(this);
PoolManager.Instance.ReturnToPool(data.poolTag, this);
yield return null;
}
}
부모 타입(Monster)로 먼저 ReturnToVillage 하며 Minion이 Monster 타입으로 반환되어 버린다.
public class summonerMonster : Monster
{
private void ClearMinion()
{
if (MinionList == null || MinionList.Count == 0) return;
foreach (Minion minion in MinionList)
{
GameManager.Instance.RemoveActiveList(minion);
PoolManager.Instance.ReturnToPool(minion.data.poolTag, minion);
}
MinionList.Clear();
}
}
foreach 실행 도중 몬스터 리스트에 변동이 있어 잘못된 인덱스를 참조하게 된다.
Summoner 몬스터의 ClearMinion이 실행되는 도중 Minion도 풀에 반환되는 상황이 되면 이중 반환이 되는 문제가 발생한다.
[ 문제 해결 ]
Monster의 ReturnToVillage에서 Minion이 아닌 경우에만 활성 리스트에서 삭제하고 풀에 반환하도록 수정
Minion은 본인의 스크립트에서 오버라이딩하여 삭제하고 풀 반환하게 만들기
public class Minion : Monster
{
public void ReturnToVillage(bool remove)
{
base.ReturnToVillage();
if (remove)
{
_summonerMonster.RemoveMinion(this);
}
GameManager.Instance.RemoveActiveList(this);
PoolManager.Instance.ReturnToPool<Minion>(data.poolTag, this);
}
}
public abstract class Monster : MonoBehaviour
{
public virtual void ReturnToVillage()
{
if (_coroutine != null) StopCoroutine(_coroutine);
_coroutine = StartCoroutine(FadeOutAndReturnToPool());
}
private IEnumerator FadeOutAndReturnToPool()
{
if (this.GetType().Name != "Minion")
{
GameManager.Instance.RemoveActiveList(this);
PoolManager.Instance.ReturnToPool(data.poolTag, this);
}
yield return null;
}
}
반복 중에 리스트 요소를 삭제하는 경우 foreach 대신 for 문을 사용해 뒤에서부터 삭제하도록 만들어 인덱스 에러 방지
해당 요소가 씬에 활성화되어있는지 확인 후 풀에 반환시키기
public class summonerMonster : Monster
{
private void ClearMinion()
{
if (MinionList == null || MinionList.Count == 0) return;
int mCount = MinionList.Count;
for (int i = 0; i < mCount; i++)
{
if (MinionList[MinionList.Count - 1].gameObject.activeSelf)
{
MinionList[MinionList.Count - 1].ReturnToVillage(true);
}
}
if (MinionList.Count > 0)
{
MinionList.Clear();
}
}
}'내일배움캠프 > TIL' 카테고리의 다른 글
| [내배캠][Unity6기][TIL] 코루틴 중지 트러블슈팅 (0) | 2025.01.08 |
|---|---|
| [내배캠][Unity6기][TIL] 다중 스폰 포인트 (0) | 2025.01.07 |
| [내배캠][Unity6기][TIL] ObjectDisposedException 트러블슈팅 (0) | 2025.01.06 |
| [내배캠][Unity6기][TIL] 힐러 타입 인간 추가 (0) | 2025.01.03 |
| [내배캠][Unity6기][TIL] 데이터 로드 리팩토링 (2) (0) | 2024.12.31 |