20240209_유니티 초기화 순서 관련

2024. 2. 10. 10:51IT/TIL

오늘의 TIL은 유니티에서 Awake 함수로 만든 함수들에서 나올 수 있는 오류와 관련된 내용이다.

 

유니티에서 다양한 스크립트에 Awake 함수를 만드는 경우에 생길 수 있는 오류로

 

다른 오브젝트를 받아오게 처리한 경우에 생기는 오류이다.

 

예를 들어서 A라는 스크립트에서 Awake 함수에서 자신에게 컴포넌트를 붙이게 만드는데,

 

B라는 스크립트에서 A에 있는 특정 컴포넌트를 참조하게 만들었다고 가정하자.

 

그렇다면 A부터 Awake 함수가 실행되고 B가 실행된다면 문제가 없지만,

 

B가 먼저 실행된다면 A에는 컴포넌트가 없는데 이를 참조하므로 null 오류가 발생한다.

 

이를 해결하기 위해서는 우선 null이 아닌 상태인 경우에 작동하게 하는 방법이 있는데,

 

if (aaaaa != null)
{
    // 실행할 함수 내용
}
else
{
    Debug.Log("aaaaa is null");
}

 

위와 같이 aaaaa라고 선언된 컴포넌트가 null이 아니라면 작동하게 만들면 된다.

 

단, 이는 null이라면 오류가 발생하지 않는 것이지, 이를 해결한 방안은 아니다.

 

따라서 이 Awake 함수가 작동하는 순서를 조정하지 않는다면 근본적으로 해결한 것은 아니다.

 

 

그렇다면 이 초기화 순서로 생기는 오류는 어떻게 해결하면 좋을까?

 

(단, Script Execution Order에서 순서를 조정하는 것은 고려하지 않는다)

 

1. 순서를 관리하는 Manager 만들기

A와 B의 Awake를 관리하는 Manager를 만드는 방법이 있을 수 있지만,

 

이 또한 Script Execution Order를 사용하는 것과 크게 차이가 없는 방법으로,

 

모든 스크립트들의 순서를 정해주어야되므로 근본적인 해결책은 아니다.

 

 

2. Hierarchy(하이어라키) 창 순서 조정

기본적으로 유니티의 하이어라키 창에 있는 위에서부터 아래쪽으로 작동되게 되어있다.

 

따라서 A와 B의 위치를 조정함으로써 먼저 작동시킬 스크립트를 조정할 수 있다.

 

특히, 자식과 부모 관계로 조정한다면 부모가 먼저 작동되므로 이를 이용하여 조정할 수 있다.

 

 

3. 종속되는 개념은 Awake가 아닌 필요한 시점으로 조정

Awake에서 실행할 필요가 없는 작업을 시키는 경우라고 판단되면

 

이를 Awake가 아닌 작동되는 시점에서 가져오도록 하면 된다.

 

예를 들어서 A에게 종속된 B 스크립트에서 Awake에 문제가 생기는 경우,

 

B 스크립트에서 A의 컴포넌트를 받아오는 것은 A와 B의 상호작용을 수행하려고 하는 것이다.

 

따라서 B의 Awake에서 필요한 컴포넌트를 받아오지 않고,

 

A와 B가 상호작용하여 그 처리를 하는 시점에서 받아오는 방식으로 수정할 수 있다.

 

만약 받아와야 되는 정보의 양이 너무 많다면 이 방법을 사용할 수 없지만,

 

둘의 상호작용의 경우 필요한 정보의 양이 적은 경우가 많기 때문에 이런 방식으로 해결할 수 있는 경우가 많다.

 

 

 

실제로 이 방법을 사용해서 문제를 해결했는데,

 

부모와 자식의 관계로 수정할 수 없고, 프리팹화 시킨 오브젝트들이 생성되게 하는 부분에서 생겼던 오류였는데

 

두 물체의 충돌과 관련된 부분으로 받아와야되는 부분이 B의 위치와 Bool 값 정도로

 

이 정도의 정보는 충돌 시(OnTriggerEnter2D)에 처리해도 크게 문제가 없는 부분이였다.

 

이런 방식으로 문제를 접하고 해결하기 위해 방법을 찾고 시도해본 뒤에 해결했는데

 

TIL로 작성하여 기록하는 것이 좋을 것이라 생각되어 오늘의 TIL로 작성하게 되었다.