관리 메뉴

cyphen156

유니티 InputSystem ActionMap 할당 에러 해결 일지 본문

프로젝트/유니티

유니티 InputSystem ActionMap 할당 에러 해결 일지

cyphen156 2025. 10. 14. 18:08

유니티 개발하던 중 싱글턴 인스턴스의 딕셔너리 참조가 날아가는 듯한 상황이 발생했다.

다른 키입력 같은 함수 호출로 인한 InputSystem ActionMap 실행 도중에 터진 에러다.

인스펙터 상에서 분명 리스트 제대로 호출되고 있는데 디버그 코드로 확인하면 도중에 딕셔너리에 저장된 키들이 싹 날아간다.

그래서 디버그로 찍어봤는데 인스턴스 ID가 다르게 나온다...?
DDOL 객체에다가 씬을 전환하지도 않았고 그냥 딕셔너리안에 있는 요소 체크해서 찾은 오브젝트를 활성/비활성만 하는데 딕셔너리가 날아간다...?

 

뭔가뭔가 해서 찾아보는데 처음의 실행에는 제대로씬에 있는 인스턴스에서 함수를 호출한다.

근데 다음 호출할때는 프로젝트 내의 원본 프리팹에서 함수를 호출해버린다.

그리고 여기선 인스턴싱이 안되있으니 당연히 딕셔너리에 있는 참조 UI Object도 없다.

왜 이렇게 될까....?를 생각하다가 

InputManager에서 액션 맵 연결을 내가 프리펩에다가 해놨나? 싶어서 하나는 Scroll 호출은 프리팹에, Menu 호출은 씬내부의 인스펙터로 연결해 보았다.

찾아냈다. 내 생각이 맞았다.

보면 Menu 호출은 정상적으로 작동하는데 Scroll은 안먹는다

이거는 따로 InputManager를 처음 렌더링 할 때 액션 매핑을 등록하는 함수를 만들던지 아니면 인스펙터 상에서 하이어라키에 배치된 인스턴스의 함수 호출로 항상 매핑할지를 선택해야 하겠다. 프리팹에 매칭하는건 오늘 보았듯 프리팹이 인스턴싱만 하고 렌더링 되지 않아 내부 변수들이 죄다 할당이 안될 것이기에 NRE가 발생할 것이기 때문에 절대 해선 안될 것이다.

할당 안되는 이유는 뭐냐고?

그건 내가 외부 참조변수 할당은 항상 Start로 강제하기 때문이다.

내부 참조 변수는 Awake에서 하더라도 항상 외부 인스턴스의 참조할당은 " 반드시" Start에서 해야 유니티 인스턴스 생명주기에 의한 NRE가 방지되기 때문이다. 적어도 Start 전에 항상 외부 변수들이 Awake되어 있다는 것은 보장되니까 인스턴스 자체는 이미 생성되어 있다는 이야기이기 때문이다.

다음은 에러 발견을 위해 작성햇던 디버그 코드다.

인스펙터 상에서 Debug모드를  활성화 시켜줘야 엔티티 ID를 확인할 수 있다.

 /// 딕셔너리가 날아가는 문제 로그
 /// 현재 남은 딕셔너리 요소를 출력
 
 string dictContents = "Current UI Dictionary Contents:\n";
 foreach (var key in uiObjects.Keys)
 {
     dictContents += $"- {key}\n";
 }
 Debug.Log(dictContents);
 Debug.Log($"[UIManager] instanceID={GetInstanceID()}\n[Name] = {this.name}\ndictCount={uiObjects.Count}");

현실적으로 생각하면 인스펙터 할당이 편하기도 하고 빠르고 아트나 외부 협력에 효과적이긴 한데... 오늘같은 버그 발생할 확률이 코드로 강제하는거보다 훠어어어어어어어얼씬 높다는게 함정이다. 

알아서 잘 선택하자