강의, 책/[Unity] C#과 유니티로 만드는 MMORPG 게임 개발 시리즈

Section 7. UI - 코드 정리

hye3193 2024. 1. 31. 13:54

1. getOrAddComponent 함수를 extension method로 변경해준다

 

Assets > Scripts > Utils > Extension.cs

public static class Extension
{
    public static T GetOrAddComponent<T>(this GameObject go) where T : UnityEngine.Component
    {
        return Util.GetOrAddComponent<T>(go);
    }
    
    public static void AddUIEvent(this GameObject go, Action<PointerEventData> action, Define.UIEvent type = Define.UIEvent.Click)
    {
        UI_Base.AddUIEvent(go, action, type);
    }
}

기존 함수 형태를 가져와서 gameobject 앞에 this를 붙여주면

// 기존 코드
UI_Inven_Item invenItem = Util.GetOrAddcomponent<UI_Inven_Item>(item);

// extension method 사용
UI_Inven_Item invenItem = item.GetOrAddcomponent<UI_Inven_Item>();

아래와 같이 사용할 수 있게 된다

(AddUIEvent 함수도 같은 방식으로 구현했었음, section 7. UI - 자동화(이벤트) 참고)

 

 

2. 프리팹 생성 시 이름 뒤에 붙는 (Clone) 제거하기

 

Assets > Scripts > Managers > ResourceManager.cs

public class ResourceManager
{
    public T Load<T>(string path) where T : Object
    {
        return Resources.Load<T>(path);
    }
    
    public GameObject Instantiate(string path, Transform parent = null)
    {
        GameObject original = Load<GameObject>($"Prefabs/{path}");
        if (original == null)
        {
            Debug.Log($"Failed to load prefab : {path}");
            return null;
        }
        
        GameObject go = Object.Instantiate(original, parent);
        go.name = original.name;
        
        return go;
    }
    
    public void Destory(GameObject go)
    {
    if (go == null)
        return;
    
    Object.Destory(go);
}

위와 같이 수정해줄 수 있다

 

int index = go.name.IndexOf("(clone)");
if (index > 0)
    go.name = go.name.Substring(0, index);

Clone 글자를 위와 같은 방식으로 제거해도 된다

 

 

3. GetObject 함수 생성

 

Assets > Scripts > UI > UI_Base.cs

protected GameObject GetObject(int idx) { return Get<GameObject>(idx); }

GetText, GetButton, GetImage 함수 있는 위치에 GetObject 함수도 추가해준다

 

 

4. UI > Popup, Scene, (new)SubItem

인벤토리 실습 할 때 InvenItem의 경우, popup에도 scene에도 해당되지 않고, scene의 산하에 들어간 오브젝트였는데, 이런 케이스의 아이템들을 관리하기 위해 UI 폴더 산하에 SubItem 폴더를 새로 만들어준다

 

그리고 Assets > Scripts > Managers > UIManager.cs

public T MakeSubItem<T>(Transform parent = null, string name = null) where T : UI_Base
{
    if (string.IsNullOrEmpty(name))
        name = typeof(T).Name;
    
    GameObject go = Managers.Resource.Instantiate($"UI/SubItem/{name}");
    if (parent != null)
        go.transform.SetParent(parent);
    
    return Util.GetOrAddComponent<T>(go);
}

MakeSubItem 함수를 추가해준다

사용은 아래와 같이 하면 된다

GameObject item = Managers.UI.MakeSubItem<UI_Inven_Item>(parent: gridPanel.transform).gameObject;

 

인자를 넘겨줄 때 가독성을 위해 parent를 지정해줘도 된다