본문 바로가기
카테고리 없음

[TRW] UIManager 설정

by mazayong 2024. 7. 24.

0. 이전에 작업한 내용

1. 구현한 부분

(++내가 생각하는 UIManager의 역할)

2. 고민하는 부분 및 리팩토링해야하는 부분

 

 

 

 

 

 

 

 

 

0. 이전에 작업한 부분

* InventoryUI 자동화

* Player Input의 작동키와 UI 연결

 

 

 

 

 

 

 

 

 

1. 구현한 부분

* Player Input부분 리팩토링

= 처음에 Player Input에 플래그를 걸어 해당 키 입력이 들어올 때 창이 닫혔다 열렸다 되는 부분을 구현했다. 

그런데 해당 부분이 코드도 비효율적인 것 같고 UIManager를 설정해서 UI 관련 관리하는 부분을 분리하기 위해 UIManager를 구현했다.

 

UIManager.cs

private Dictionary<string, GameObject> uiInstances = new Dictionary<string, GameObject>();
private Canvas canvas;
private string currentActiveUI = null;

= 현재 씬에서 생성되어있는 게임 오브젝트를 저장해서 사용하기 위해 딕셔너리를 만들고, 해당 UI의 이름을 Key로 설정해서 해당 UI를 찾기 용이하게 설정했다.

(생성되는 UI 종류가 정해져 있으면 BaseUI.cs를 만들고 해당 UI의 타입을 enum으로 선언하거나 id를 선언한 뒤 사용하는 것도 좋은 것 같다.)

= 특정 UI가 켜져 있는 상황에서 작동시킨 키를 사용해 UI를 비활성화시켜야 하기 때문에 현재 활성화된 UI를 판단하는 currentActiveUI를 추가했다.

 

    public void ToggleUI(string uiName)
    {
        if(currentActiveUI == uiName)
        {
            DeactivateUI(uiName);
            currentActiveUI = null;
            return;
        }

        DeactivateAllUI();

        if (!uiInstances.ContainsKey(uiName))
        {
            GameObject uiPrefab = GetUIPrefab(uiName);

            if(uiPrefab != null)
            {
                GameObject uiInstance = Instantiate(uiPrefab, canvas.transform, false);
                uiInstances[uiName] = uiInstance;
            }
        }


        if(uiInstances.ContainsKey(uiName))
        {
            uiInstances[uiName].SetActive(true);
            currentActiveUI = uiName;
        }
    }

= UI가 현재 존재하는지 판단하고, 해당 UI가 이미 활성화되어 있을 경우 활성화된 해당 UI를 비활성화한다.

= 원하는 UI를 활성화하기 위해 현재 생성된 모든 UI를 비활성화하고, 해당 UI가 딕셔너리 안에 들어와있을 경우 그대로 활성화하고, 딕셔너리 안에 존재하지 않을 경우 해당 UI를 생성한 후 딕셔너리에 생성했다고 등록한다.

 (++이 때 현재 씬에 활성화된 경험이 있는 UI들은 UIManager에서 관리하도록 private  처리한다.)

 

private void DeactivateAllUI()
    {
        foreach (var uiInstance in uiInstances.Values)
        {
            uiInstance.SetActive(false);
        }
    }

    private GameObject GetUIPrefab(string uiName)
    {
        switch(uiName)
        {
            case "Inventory":
                return inventoryUIPrefab;
            //skip
            default:
                return null;
        }
    }

    public bool IsUIActive()
    {
        return currentActiveUI != null;
    }

= 모든 생성된 UI를 비활성화하는 함수를 넣었다.

= switch-case로 원하는 UI를 가져오도록 설정했다.

= 외부에서 UI의 활성화 여부는 접근하는 함수가 있는 것이 용이할 것 같아서 해당 부분을 점검하는 함수를 작성했다.

 

 

이렇게 위와 같이 작성하면, UI 활성화를 아래 코드만으로 이용할 수 있다.

uiManager.ToggleUI("Inventory");

 

 

 

* Player Input 키 추가

= 이동키(WASD)를 Input Action에 추가했다.

 

 

 

* UI 활성화시 해당 UI를 활성화한 키를 제외하고 모두 비활성화

= UI를 활성화하는 키는 무난하게 처리할 수 있었지만, 움직임의 경우는 UI와 관련이 없었기 때문에 OnMove()에서 IsUIActive()를 조건문으로 넣어서 해결했다.

    void OnMove(InputValue inputValue)
    {
        if (uiManager.IsUIActive())
            return;
        inputVector = inputValue.Get<Vector2>();
    }

 

 

 

 

 

2. 고민하는 부분 및 리팩토링해야 하는 부분

= Addressable System을 이용한 비동기 처리

=> UI가 초기에 렌더링되는 시간과 메모리를 줄이고 싶어서 방안을 고민했는데, 프리로딩과 비동기 처리 중 비동기처리를 택했다. 해당 부분에 대해서는 내용을 좀 더 정리하고 내일 본격적으로 블로그에 고민한 내용들을 기록할 예정이다.