본문 바로가기
스파르타 내배캠

스파르타 내배캠 Unity 3기 35일차

by LemongO 2024. 2. 9.

(빨리 쓰고 본가 가야 함)

 

다들 새복많!


UI 자동화 3 - UI를 씬에 보여주기 (UI Manager)

 

어제까지 한 내용에서는 UI 내부의 자동화 방식을 보여줬다.

그렇다면 그렇게 자동화 해놓은 UI를 아무것도 없는 씬에 불러오는 방법은?

 

다음은 예시 화면이다.

Sign Up 버튼을 누른다

 

다음과 같은 메인 화면에서 Sign Up 버튼을 누르게 되면 회원가입 창이 나오게 된다.

 

 

이 때 회원가입 UI가 생성되는 방식은?

 

UIManager 코드를 보자.

 

public class UIManager
{
    public GameObject Root
    {
        get
        {
            GameObject root = GameObject.Find("@UI_Root");
            if (root == null)
            {
                GameObject go = Resources.Load<GameObject>($"Prefabs/@UI_Root").gameObject;
                root = Object.Instantiate(go);
                root.name = go.name;                
            }                
            return root;
        }
    }

    public void ShowSceneUI<T>(string path = null) where T : UI_Base => Util.Instantiate<T>(path);
    public void ShowMenuUI<T>(string path = "Prefabs/UI") where T : UI_Base => Util.Instantiate<T>(path, Root.transform);
    public void ShowPopupUI<T>(string alert, string path = "Prefabs/UI") where T : UI_Base
    {
        UI_Popup popup = Util.Instantiate<T>(path, Root.transform).GetComponent<UI_Popup>();
        popup.SetupAlert(alert);
    }
    
    public void CloseUI(GameObject go) => Object.Destroy(go);
}

 

(이번 개인과제 프로젝트에 맞춰서 만들어놓은 급조 UIManager 이므로 퀄리티가 별로다.)

 

먼저 GameObject Root 프로퍼티는 get을 통해 씬에있는 "@UI_Root" 오브젝트를 찾고

있으면 바로 return을 해주고, 없으면 Resources/Prefab 폴더의 @UI_Root 오브젝트를 생성해서 return 해준다.

Root의 역할은 씬에 마구잡이로 나열 돼있으면 보기 안 좋아서 모음집 역할을 한다. 즉 SetParent 때 부모가 된다.

 

그 다음 ShowMenuUI 함수를 보자.(다른 Show 함수는 넘어간다.)

 

MenuUI를 씬에 생성하는 함수이며 UI_Base 를 상속받은 T 타입을 받고 string path를 넘기거나 기본값으로

해당 Resources 폴더 path 위치에서 원하는 MenuUI 를 꺼내오게 된다. 이 때, Root도 넘겨줘 부모로 설정한다.

 

그럼 Util 클래스의 Instantiate 함수를 보자.

 

public static GameObject Instantiate<T>(string path = null, Transform parent = null)
{
    if (string.IsNullOrEmpty(path))
        path = "Prefabs";        

    string fileName = typeof(T).Name;

    GameObject prefab = Resources.Load<GameObject>($"{path}/{fileName}");
    
    GameObject go = Object.Instantiate(prefab, parent);
    go.name = prefab.name;

    return go;
}

 

(이 또한 프로젝트에 맞춰 제작되었다)

 

범용적으로 쓰일 수 있고, Popup UI를 만들 때 경고메세지를 바꿀 수 있게 하기위해
반환값으로 게임오브젝트를 반환해준다. 

 

또한 인스펙터에 등록된 GameObject를 생성하는 방식이 아니라 Resources 폴더에 있는 프리팹을 불러오는 방식이다.

 

파일의 이름 fileName 은 T 의 이름으로 정해준다. 즉 프리팹의 이름과 클래스의 이름이 동일해야한다.

 

GameObject prefab 은 Resources 폴더에 있는  $"{path}/{fileName}" 의 GameObject 를 불러온다.

 

그리고 불러온 prefab을 parent 를 부모 삼아 go를 생성해준다. (이 때, 씬에 생성된다.)

 

go의 이름을 바꿔주는 이유는 프리팹을 생성하면 이름뒤에 (Clone) 이 붙게되는데 그걸 삭제해주기 위함이다.

 

 

그럼 버튼을 눌렀을 때 UI를 생성해야 하므로 실제 사용은 다음과 같이 한다.

public class UI_Login : UI_Base
{
    enum Buttons
    {
        Login_Btn,
        SignUp_Btn,
    }
    
    public override bool Init()
    {
        if (base.Init() == false)
            return false;

        BindButton(typeof(Buttons));
        
        GetButton((int)Buttons.SignUp_Btn).onClick.AddListener(SignUp);

        return true;
    }

    private void SignUp() => Managers.UI.ShowMenuUI<UI_SignUp>();
}

UI_Login 클래스가 생성될 때 Button 들을 바인드 후,

SignUp 버튼 Addlistener에 SingUp UI를 생성하는 함수를 할당하면 끝이다.