오늘의 학습 키워드

바인딩, Enum.GetNames()

 

공부한 내용

UI 바인딩

UI 부분 관련해서 UI 바인딩에 관한 정보를 찾게 되었다.

UI 작업할 때 항상 문제점이 변수가 너무 많이 늘어나서 보기에 불편하다는 단점이 있었는데 UI 바인딩이 하나의 대체제가 될 수 있다고 생각이 들었다.

UI 바인딩 순서는 이렇다.

1. 바인딩의 매개변수로 들어가는 enum에는 해당 컴포넌트의 하위의 이름을 넣어둔 뒤

2. UI바인딩 메서드가 들어가 있는 UIBase를 상속 받아 enum을 키 값으로 하고 Object를 value 값으로 하는 딕셔너리에 등록을 한다.

3. Enum.GetNames()로 해당 enum 값을 배열로 불러와 foreach문을 돌며 이름으로 오브젝트를 찾아내 딕셔너리 값에 등록해준다.

4. 나중에 찾아서 쓸 때는 Get<타입>(인덱스)으로 딕셔너리 값인 Object 배열에서 타입을 가져올 수 있다. (enum인덱스 : 0,1,2... 딕셔너리 배열 인덱스 : 0,1,2...가 일치하므로)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class UIBase : MonoBehaviour
{
    // GameObejct가 Object를 상속받고 다른 컴포넌트들이 Object를 상속 받으므로 Object 타입으로 통일
    // UIBase를 상속받으면 _objectDict를 하나씩 가지고 있음
    private Dictionary<Type, UnityEngine.Object[]> _objectDict = new Dictionary<Type, UnityEngine.Object[]>();

    protected void Bind<T>(Type type) where T : UnityEngine.Object
    {
        string[] names = Enum.GetNames(type);
        UnityEngine.Object[] objects = new UnityEngine.Object[names.Length];

        _objectDict.Add(typeof(T), objects);

        for (int i = 0; i < names.Length; i++)
        {
            if (typeof(T) == typeof(GameObject))
            {
                objects[i] = Util.FindGameObject(gameObject, names[i], true);
            }
            else
            {
                objects[i] = Util.FindComponent<T>(gameObject, names[i], true);
            }

            if (objects[i] == null)
            {
                Debug.LogError($"Failed To Bind {names[i]}");
            }
        }
    }

    // enum값 0,1,2,... 배열 index 값 0,1,2,...
    protected T Get<T>(int index) where T : UnityEngine.Object
    {
        UnityEngine.Object[] objects = null;
        if (!_objectDict.TryGetValue(typeof(T), out objects))
        {
            return null;
        }
        else
        {
            return (T)objects[index];
        }
    }
}
using TMPro;

public class NameUI : UIBase
{
    enum Texts
    {
        NameText,
    }

    void Start()
    {
        Bind<TMP_Text>(typeof(Texts));
    }

    public void SetName(string name)
    {
        Get<TMP_Text>((int)Texts.NameText).text = name;
    }

}

잘 불러와지는 것을 볼 수 있다.

 

오늘의 회고

  오늘은 UI 바인딩에 대한 작업을 진행했다. 거의 접해보지 못했던 작업이라 이해하는데 시간도 걸리고 다른 작업들을 많이 진행하지 못했다. 아쉽지만 내일 남은 작업이라도 열심히 해봐야겠다는 생각이 들었다. 그럼에도 불구하고 이번에 배운 것들은 굉장히 프로그래머스러운(?) 작업이라 꽤나 보람이 있었다고 느꼈다.

 내일은 과제 제출일이다. 12시까지 하던 작업을 끝내고 Readme까지 완료해야겠다. 그 다음엔 여러 사람과 친해지는 시간이 있다는데 조금 떨리고 설레기도 한 것 같다. 내일 과제 마무리 잘 해보자. 파이팅!

+ Recent posts