내일배움캠프/TIL

[내배캠][Unity6기][TIL] ObjectDisposedException 트러블슈팅

binary는 호남선 2025. 1. 6. 21:12

[ 문제 상황 ]

GameManager에서 활성화된 오브젝트들의 리스트를 관리하고 있는데

ObjectDisposedException과 type is not a supported pptr value 에러가 발생했다.

public class GameManager : SingletonBase<GameManager>
{
    public List<Human> activeHumans = new List<Human>();
    public List<Monster> activeMonsters = new List<Monster>();
}
public class Human : MonoBehaviour
{
    protected virtual void OnEnable()
    {
        GameManager.Instance.activeHumans.Add(this);
    }
    protected virtual void OnDisable()
    {
        GameManager.Instance.activeHumans.Remove(this);
    }
}
public class Monster : MonoBehaviour
{
    protected virtual void OnEnable()
    {
        GameManager.Instance.activeMonsters.Add(this);
    }
    protected virtual void OnDisable()
    {
        GameManager.Instance.activeMonsters.Remove(this);
    }
}

 

[ 문제 분석 ]

구글링 결과 호환되지 않는 버전의 문제일 수 있으며(? 전에는 잘 됐는데 왜 갑자기 저러는지는 모르겠지만...)

List를 인스펙터 창에 노출시키면 해당 에러가 발생한다고 한다.

https://discussions.unity.com/t/nullreferenceexception-serializedobject-of-serializedproperty-has-been-disposed/916708/7

 

[ 문제 해결 ]

반드시 public 이어야 하지는 않으므로 private으로 설정해주고 외부에서 public 함수를 통해 접근하도록 수정했다.

디버깅 시 인스펙터창 모드를 디버그로 설정하면 직렬화되어 해당 문제가 다시 발생한다.

(에러 로그는 뜨지만 정상작동하고 있다..)

public class GameManager : SingletonBase<GameManager>
{
    public List<Human> activeHumans = new List<Human>();
    public List<Monster> activeMonsters = new List<Monster>();
    
    public void AddActiveList<T>(T obj)
    {
        if (obj is Human)
        {
            activeHumans.Add(obj as Human);
            return;
        }

        if (obj is Monster)
        {
            activeMonsters.Add(obj as Monster);
        }
    }
    
    public void RemoveActiveList<T>(T obj)
    {
        if (obj is Human)
        {
            activeHumans.Remove(obj as Human);
            return;
        }

        if (obj is Monster)
        {
            activeMonsters.Remove(obj as Monster);
        }
    }
}
public class Human : MonoBehaviour
{
    protected virtual void OnEnable()
    {
        GameManager.Instance.AddActiveList(this);
    }
    protected virtual void OnDisable()
    {
        GameManager.Instance.RemoveActiveList(this);
    }
}
public class Monster : MonoBehaviour
{
    protected virtual void OnEnable()
    {
        GameManager.Instance.AddActiveList(this);
    }
    protected virtual void OnDisable()
    {
        GameManager.Instance.RemoveActiveList(this);
    }
}