• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

질문있습니다@!!

23.12.12 02:03 작성 23.12.12 14:13 수정 조회수 172

0

안녕하세요 강의를 듣다 enum으로 하나씩 넣는게 제 개인적인 생각으로는 귀찮다라는 생각을 받았어요 그래서 이걸 오브젝트의 이름만 받아서 사용할 수 있게 해보자 해서 짜봤는데

 

강의에서 소개해주신 enum으로 관리하는 것과 제 코드와 비교해서 enum으로 관리할 때의 장점이 있을까요?

 

그리고 아래 코드에서 개선할만한 부분도 있다면 알려주시면 감사하겠습니다

private Dictionary<Type, UnityEngine.Object[]> _componentDictionary = new Dictionary<Type, UnityEngine.Object[]>();

private void Start()
{
    Bind<Button>();
    Bind<TextMeshProUGUI>();
    Bind<Image>();
    Bind<GameObject>();

    Debug.Log(Get<GameObject>("ddd").transform.position.x);
}

void Bind<T>() where T : UnityEngine.Object
{
    //필터 해줄 타입 추가
    if (typeof(T) != typeof(Button) && typeof(T) != typeof(TextMeshProUGUI) && typeof(T) != typeof(Image) && typeof(T) != typeof(GameObject)) return;

    
    if (typeof(T) == typeof(GameObject))
    {
        Transform[] transforms = Util.FindChild<Transform>(transform, true);
        GameObject[] gameObjects = new GameObject[transforms.Length];
        for (int i = 0; i < transforms.Length; i++)
        {
            gameObjects[i] = transforms[i].gameObject;
        }
        
        _componentDictionary.Add(typeof(GameObject), gameObjects);
        return;
    }

    T[] objects = Util.FindChild<T>(transform, true);

    _componentDictionary.Add(typeof(T), objects);
}

T Get<T>(string name) where T : UnityEngine.Object
{
    UnityEngine.Object[] objects = null;
    if (_componentDictionary.TryGetValue(typeof(T), out objects) == false) return null;

    foreach (UnityEngine.Object obj in objects)
    {
        if (obj.name == name) return obj as T;
    }

    return null;
}

 

public static T[] FindChild<T>(UnityEngine.Transform transform, bool recursive = false) where T : UnityEngine.Object
{
    if (transform == null) return null;

    if (recursive == false)
    {
        T[] dd = new T[transform.childCount];
        
        for (int i = 0; i < transform.childCount; i++)
        {
            dd[i] = transform.GetChild(i).GetComponent<T>();
        }
        return dd;
    }
    else
    {
        return transform.GetComponentsInChildren<T>();
    }
}

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.12.14

안녕하세요, 인프런 AI 인턴입니다.
toyboy0113님, 질문 주셔서 감사합니다. Enum을 이용하여 관리할 때의 장점에 대해 설명드리겠습니다.

Enum을 사용할 때의 주된 장점은 다음과 같습니다:
1. 코드의 가독성 향상: Enum은 상수들의 집합으로, 의미 있는 이름을 부여할 수 있어 가독성이 좋아집니다.
2. 유효한 값의 제한: Enum은 사전에 정의된 값들만 사용하기 때문에, 잘못된 값을 사용할 위험이 줄어듭니다.
3. 리팩토링 용이: Enum의 이름이 변경되면 컴파일 타임에 오류를 찾아낼 수 있어서, 안전하게 리팩토링이 가능합니다.
4. 타입 안정성: Enum은 특정 타입만을 허용하기 때문에 타입 안정성을 보장받을 수 있습니다.

제시해주신 코드를 보면, 오브젝트 이름으로 컴포넌트를 관리하시려는 것 같습니다. 이 방법도 동작에는 문제가 없지만, Enum을 사용하지 않을 경우 발생할 수 있는 단점으로는 실수로 잘못된 문자열을 입력했을 때 오류를 컴파일 시점이 아니라 런타임에서야 발견할 수 있다는 점입니다. 이 때문에 오류 발견과 디버깅이 어려워질 수 있습니다.

코드 개선에 대해서 몇 가지 제안해보겠습니다:
- Bind<T>() 메서드에서 특정 타입을 필터링 하고 있는 부분은 확장성이 떨어지므로, 필터링 없이 모든 T 타입에 대해 동작하도록 개선할 수 있습니다. 필터링이 필요한 경우 별도의 메서드나 로직을 추가하는 것이 좋습니다.
- Dictionary<Type, UnityEngine.Object[]>의 대신 Dictionary<Type, Dictionary<string, UnityEngine.Object>> 형태로 관리하면 이름으로 바로 접근이 가능하므로 효율적일 수 있습니다.
- 예외 처리: FindChild<T>() 메서드에서는 null을 반환하기보다는 빈 배열을 반환하는 것이 더 안전한 코딩 관행입니다.

코드의 구조나 목적 등에 따라 위의 조언이 모두 적용되는 것은 아니므로, 상황에 맞게 적용하시는 것이 좋습니다.