TIL : 2024-12-09(월) :: 최종프로젝트 개발 일지(11) - Scene을 로드하는경우 파괴된 Object에 접근되는 상
Enemy 및 Projectile 을 ObjectPool Class에 넣어 관리를 하는데,Scene을 로드하는 경우 ObjectPollManager는 DontDestroy로 파괴되지 않아 데이터가 유지되지만Enemy Object들은 Scene이 로드되면서 파괴되기에 ObjectPoolM
01149.tistory.com
해당 관련된 글의 트러블 슈팅이다.
트러블 슈팅의 대처법으로
[ 결론은 Scene 재로드시에 ObjectPool을 비우는 구조를 설계를 해야만 한다. ]
였기에 , 우선 호출시점을 오브젝트 풀링을 셋팅하기 전으로 설계를 해야되고 , 각 클래스별로 오브젝트 풀링세팅하는것을 한 곳으로 모아서 작업을 하였으며 , 경로 같은 고정 문자열은 따로 Const 라는 고정 상수,문자열을 저장하는 클래스를 따로 만들어 관리하기로 하였다.
이렇게 한 이유는
첫번째 : 오브젝트 풀링 세팅은 한 Scene에서 세팅 후에 호출 및 반납만하기에 한 곳에서 해도 된다고 판단하였고
Scene 로드 할때 처음으로 오브젝트 풀을 비우면 중복 생성이나 파괴된 오브젝트에 접근하지 않을거라고 판단하였다.
두번째 : 경로는 보통 문자열로 이루어져있고 수정이 되지 않아야되고 접근이 가능해야되기에 Static Class로 생성 한뒤 readonly 기능을 이용하어 수정을 막았다.
GameSceneTrigger.cs
using System;
using UnityEngine;
public class GameSceneTigger : MonoBehaviour
{
private void Start()
{
ObjectPoolManager.Instance.ObjectPoolAllClear();
PlayerObjectPoolSetting();
EnemyObjectPoolSetting();
InventoryObjectPoolSetting();
GameManager.Instance.StartGame();
}
private void InventoryObjectPoolSetting()
{
}
private void PlayerObjectPoolSetting()
{
ObjectPool playerProjectilePool = new ObjectPool(Const.POOL_KEY_PLAYERPROJECTILE, Const.PLAYER_INITIAL_POOL_SIZE, Const.PLAYER_PROJECTILE_ENERGYBOLT_PATH);
ObjectPoolManager.Instance.AddPool(Const.PLAYER_PROJECTILE_ENERGYBOLT_KEY, playerProjectilePool);
}
private void EnemyObjectPoolSetting()
{
ObjectPool goblinPool = new ObjectPool(5000, 60, Const.ENEMY_PREFEB_GOBLIN_PATH);
ObjectPool goblinMagicianPool = new ObjectPool(5001, 60, "Prefabs/Enemy/GoblinMagician");
ObjectPool slashPool = new ObjectPool(6000, 60, "Prefabs/Enemy/Effects/Slash");
ObjectPool energyBoltPool = new ObjectPool(6001, 60, "Prefabs/Enemy/Effects/EnergyBolt");
ObjectPool slashBossPool = new ObjectPool(6002, 60, "Prefabs/Enemy/Effects/SlashBoss");
ObjectPool skillBoss1Pool = new ObjectPool(6003, 10, "Prefabs/Enemy/Effects/SkillBoss1");
ObjectPool goblinBossPool = new ObjectPool(5500, 3, "Prefabs/Enemy/GoblinBoss");
ObjectPoolManager.Instance.AddPool(Const.ENEMY_POOL_KEY, goblinPool);
ObjectPoolManager.Instance.AddPool(Const.ENEMY_POOL_KEY, goblinMagicianPool);
ObjectPoolManager.Instance.AddPool(Const.ENEMY_EFFECT_POOL_KEY, slashPool);
ObjectPoolManager.Instance.AddPool(Const.ENEMY_EFFECT_POOL_KEY, energyBoltPool);
ObjectPoolManager.Instance.AddPool(Const.ENEMY_EFFECT_POOL_KEY, slashBossPool);
ObjectPoolManager.Instance.AddPool(Const.ENEMY_EFFECT_POOL_KEY, skillBoss1Pool);
ObjectPoolManager.Instance.AddPool(Const.ENEMY_BOSS_POOL_KEY, goblinBossPool);
}
}
해당 코드의 기능은 GameScene을 로드시에 필요한 곳에서 ObjectPool을 세팅하는 Class입니다.
SceneManager의 SceneLoad를 사용해도 되지만, 세팅해야될 데이터가 많고 , 확장성을 대비해서 Class로 만든뒤 오브젝트에 컴포넌트로 적용시켜 사용 중입니다.