Addressable Asset을 사용하면서 알게 되었던 Instance 개념에 대해서 정리해 볼 것이다.
Addressable Asset에 대해서 모르시더라도, 내용을 이해하는 데에는 문제 없습니다.
개요
public static async Task<GameObject> LoadingToPath(string path) where T : Object
{
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(path);
// GameObject를 불러온다.
await handle.Task;
// GameObject를 불러올 때까지 대기한다.
GameObject result = GameObject.Instantiate(handle.Result);
// 변수에 GameObject의 인스턴스를 할당한다.
Addressables.Release(handle);
// 불러온 GameObject를 해제한다.
return result;
// 위에서 생성한 인스턴스를 반환한다.
}
‘Type과 주소를 입력 받아서 Asset을 불러오고, 반환해주는 함수이다.’
에디터/빌드 환경에서의 실행 결과
- 에디터
반환 받은 에셋을 사용하는데 오류가 발생하지 않았다. - 빌드
반환 받은 에셋을 사용하려 할 때, NullReferenceException이 발생하였다.
인스턴스 파헤치기
1.
우선, 에디터에서 객체(인스턴스) 생성에 대해서 알아야 한다. 그 중에서 Prefab을 예시로 들어보겠다.
"Prefab의 인스턴스를 생성한 이후, 프리팹 원본을 삭제한다."
//플레이 모드가 영향을 주지 않습니다.
위의 경우에는 인스턴스에 문제가 생길 것 같이 느껴질 수 있지만, 실제로는 아무런 문제가 없다.
"Prefab의 색상과 이미지를 바꿔도, 컴포넌트를 추가/제거 하여도 문제가 발생하지 않는다."
여기서 이미 생긴 인스턴스의 경우에는 원본이 삭제되었음에도 불구하고, 그 영향을 받지 않는다. 이걸 다르게 말하자면, ‘원본과 영향을 주고받지 않지만, 원본과 똑같은 독립된 하나의 객체다.’
2.
빌드 환경에서 실행 결과를 다시 살펴보자. 사용한 시점은 반환 이후이다. 이것으로 알 수 있는 점은 인스턴스 생성 이후, 반환 이전 시점에 오류가 발생하게 된 것이다.
에셋의 해제가 생성한 인스턴스에서 NullReferenceException을 발생시켰다는 것을 알 수 있다.
그래서, 왜?
빌드 환경에서는 에디터 환경과 다르게, 기능들이 최적화되어서 동작한다. 그로 인해서 에디터 환경과는 다르게, 원본이 해제되면서, 원본이 가지는(사용하는) 리소스가 함께 해제되면서, 인스턴스들은 리소스에 참조가 유지할 수 없게 된다.
결과적으로 빌드 환경에서 NullReferenceException이 발생하게 되었다.
마무리하며
아래 내용은 제 개인적인 견해입니다.
저는 에디터와 빌드 환경에서 인스턴스의 차이점을 정리하면서, ‘값 타입’과 ‘참조 타입’이 생각 났습니다.
원본에 영향을 받지 않는 에디터 환경은 ‘값 타입의 인스턴스’
원본에 영향을 받는 빌드 환경은 ‘참조 타입의 인스턴스’
저는 값 타입과 참조 타입으로 대입 해보는 것이, 이해에 도움이 될거라 생각해서 남기게 되었습니다.
타입(Type)
타입(Type)이란?값이 메모리에 저장되고, 어떻게 처리하는지 나타내준다.메모리 저장 영역은 크게 4단계이다.Code : 기계어 코드가 들어가며, 읽기 전용의 데이터이다. CPU가 명령을 읽고 처리한다.D
fore4022.tistory.com
값 타입과 참조 타입에 대해서 모른다면, 위의 글을 읽어주세요.
'유니티 > 겪었던 문제' 카테고리의 다른 글
| ScriptableObject를 사용하며 겪었던 문제 (0) | 2025.04.24 |
|---|---|
| 충돌 검사 (0) | 2024.12.24 |
| New Input System에서 겪었던 문제들 (0) | 2024.11.26 |