본문 바로가기
Unity

Unity에서 Enum을 Dictionary로 연결하여 Hierarchy 자식 관리하기

by Oz Driver 2025. 4. 27.

 

Unity 프로젝트를 진행하다 보면, 게임 오브젝트의 Hierarchy 안에 있는 자식 오브젝트들을 코드로 관리해야 할 때가 많습니다.

가장 단순한 방법은 배열([]) 을 사용하여 인덱스 번호(0, 1, 2, ...) 로 오브젝트를 저장하는 것입니다. 하지만 이 방법에는 한 가지 문제점이 있습니다. "인덱스 번호는 의미를 설명하지 못합니다." ( 0이 무슨 상태이고, 1이 무슨 상태인지 숫자만 보고 알기 어렵습니다. )

또한 배열 인덱스 대신 enum을 사용하려고 (int)enum 식으로 강제 변환을 하게 되는데, 이 역시 코드 가독성과 유지보수성을 떨어뜨리는 요인이 됩니다.

 

배열 대신 Dictionary로 구조 개선하기

Dictionary 를 사용하면 Enum 값을 키(Key)로, 오브젝트 리스트를 값(Value)으로 관리할 수 있습니다.

* 숫자 인덱스 대신 의미 있는 이름으로 접근할 수 있습니다.

* 코드 가독성과 유지보수성이 크게 향상됩니다.

 

기본 구조

private Dictionary<PlayerState, List<Transform>> playerStateDic;

 

PlayerState는 관리하고 싶은 상태 enum입니다. 각 상태에 해당하는 오브젝트 리스트를 저장할 수 있습니다.

 

초기화 흐름

Dictionary를 빈 상태로 초기화한 뒤, Enum 값을 자동으로 순회하며 빈 리스트를 준비합니다.

playerStateDic = new Dictionary<PlayerState, List<Transform>>();
foreach (PlayerState state in Enum.GetValues(typeof(PlayerState)))
{
    playerStateDic[state] = new List<Transform>();
}

 

이렇게 하면 PlayerState에 새로운 값이 추가되더라도 코드를 따로 수정할 필요가 없습니다.

 

Hierarchy 자식 오브젝트 연결

Transform을 순회하면서 자식 오브젝트의 이름과 Enum 이름을 비교하여 자동으로 매칭할 수 있습니다.

( 유니티 Hierarchy 창에서 자식 오브젝트들의 이름과 enum 값을 일치시켜주어야 합니다.)

foreach (Transform child in transform)
{
    if (Enum.TryParse<PlayerState>(child.name, true, out PlayerState state))
    {
        foreach (Transform subChild in child)
        {
            if (subChild != null)
            {
                playerStateDic[state].Add(subChild);
            }
        }
    }
    else
    {
        Debug.LogWarning($"[Player] {child.name} is not a valid PlayerState.");
    }
}

 

Enum.TryParse를 사용하여 문자열 이름을 Enum 값으로 변환합니다. 변환에 성공하면 자동으로 Hierarchy를 연결할 수 있습니다.

 

실제 사용 예시

다음은 Dictionary에 등록된 오브젝트를 안전하게 꺼내어 사용하는 예시입니다.

private void UpdateMoveObjects(int activeIndex)
{
    if (!playerStateDic.TryGetValue(PlayerState.Move, out List<Transform> moveList))
    {
        Debug.LogWarning("[Player] Move 상태의 자식 오브젝트를 찾을 수 없습니다.");
        return;
    }

    int count = 0;
    foreach (var obj in moveList)
    {
        if (obj != null)
        {
            obj.gameObject.SetActive(count == activeIndex);
        }
        count++;
    }
}

 

TryGetValue를 사용하면 키가 존재하지 않는 경우에도 안전하게 처리할 수 있습니다. 필요한 오브젝트만 활성화하고, 나머지는 비활성화합니다.

 

마무리 

* 배열을 사용할 때 발생할 수 있는 인덱스 혼란을 없앨 수 있습니다.

* Enum 이름으로 오브젝트를 직접 접근할 수 있어 코드가 더욱 읽기 쉬워집니다.

* Enum.TryParse를 통해 이름 기반 매칭이 가능하고, 에러를 방지할 수 있습니다.

* TryGetValue를 통해 Dictionary 조회를 안전하게 처리할 수 있습니다.