[Unity] Project. Personal_6

Lingtea_luv·2025년 6월 16일

Project

목록 보기
22/38
post-thumbnail

Where Am I?


6일차

6일차는 본격적으로 UI 작업에 들어갔던 날이다. 물론 그 전에 몬스터 에셋을 구해서 적용시키는 작업을 진행했고, UI와 함께 작업하기 위한 기능을 정리하여 아래의 작업들을 진행할 수 있었다.

  1. 몬스터 에셋 적용, 애니메이터 구현
  2. player status interface UI 제작 및 인벤토리 연동
  3. 상자 보관 기능 구현, UI 제작 및 연동
  4. Popup UI 제작 및 상황에 따른 안내 문구 출력
  5. 제작 기능 구현, UI 제작 및 연동
  6. 인게임 Hud 제작 및 status, date 연동

6일차 개발을 진행하면서 하게된 고민은 UI와 오브젝트와의 연동 방식이었다. UI는 UI Scene에서 오브젝트는 Ingame Scene에서 따로 작업했기에 인스펙터 상에서 연동하는 방식은 사용할 수 없었는데, 따라서 UI Binder 클래스를 통해 연동 기능을 담당시켰다.

UI Manager

UI Manager 클래스는 UI를 켜고 끄는 기능 만을 담당하도록 구현했다. 또한 일시정지를 하게 되면 일시정지 UI가 나와야해서 해당 기능만 이벤트로 구독하여 처리했다.

또한 여러 UI 창을 띄우고 해당 UI를 순서대로 저장할 수 있도록 stack을 활용했다.

public class UIManager : Singleton<UIManager>
{
    public Stack<GameObject> CurUI;
    
    protected override void Awake()
    {
        base.Awake();
        if (transform.parent == null)
        {
            DontDestroyOnLoad(gameObject);
        }

        Init();
    }

    private void Start()
    {
        GameManager.Instance.IsPaused.OnChanged += GamePause;
    }
    
    public void OpenUI(GameObject curUI)
    {
        if (curUI != null)
        {
            CurUI.Push(curUI);
            CurUI.Peek().gameObject.SetActive(true);
        }
    }

    public void CloseUI()
    {
        CurUI.Pop().SetActive(false);
    }
    
    private void GamePause(bool isPaused)
    {
        CurUI.Push(UIBinder.Instance.GetPauseUI().gameObject);
        CurUI.Pop().SetActive(isPaused);
    }

    private void Init()
    {
        CurUI = new Stack<GameObject>();
    }
}

UI Binder

UI를 작업했던 6~8일차 동안 정말 많은 고민을 하게 했던 클래스이다. 직접 연결하면 의존성이 너무 강해질까봐 중개자 역할을 하기 위해 만들었는데, 결국 God class가 되어버려 해당 방향이 맞는걸까 하는 의문이 든다.

따로 멤버 함수를 만들어 조금 더 의존성을 줄일 수 있지 않을까 라는 생각도 했지만, 각 UI 역할이 통일되지 않아 어떻게 구현해야할지 아직까지 감이 안 잡히는 것 같다.

public class UIBinder : Singleton<UIBinder>
{
    [Header("Drag&Drop")] 
    [SerializeField] private PauseUI _pauseUI;
    [SerializeField] private PortalUI _portalUI;
    [SerializeField] private ChestUI _chestUI;
    [SerializeField] private PopUpUI _popUpUI;
    [SerializeField] private StatusUI _statusUI;
    
    [SerializeField] private InventoryUI _inventoryUI;
    [SerializeField] private InventoryInChestUI _inventoryInChestUI;
    [SerializeField] private InventoryInCraftUI _inventoryInCraftUI;
    
    [SerializeField] private ChestInventoryUI _chestInventoryUI;
    
    [SerializeField] private CraftStuff _craftStuff;
    [SerializeField] private CraftResult _craftResult;
    
    public PauseUI GetPauseUI()
    {
        return _pauseUI;
    }

    public PortalUI GetPortalUI()
    {
        return _portalUI;
    }
    
    public ChestUI GetChestUI()
    {
        return _chestUI;
    }

    public CraftStuff GetCraftUI()
    {
        return _craftStuff;
    }

    public PopUpUI GetPopUpUI()
    {
        return _popUpUI;
    }
    
    public void Mediate(PlayerProperty playerProperty)
    {
        _statusUI.SetProperty(playerProperty);
    }

    public void Mediate(PlayerInventory playerInventory)
    {
        _inventoryUI.SetProperty(playerInventory);
        _inventoryInChestUI.SetProperty(playerInventory);
        _inventoryInCraftUI.SetProperty(playerInventory);
    }

    public void Mediate(Chest chest)
    {
        _chestInventoryUI.SetProperty(chest);
    }

    public void Mediate(Crafting craftNPC)
    {
        _craftStuff.SetProperty(craftNPC);
        _craftResult.SetProperty(craftNPC);
    }
}
profile
뚠뚠뚠뚠

0개의 댓글