본문 바로가기
Project/<team Not Same> 꿈의 왕국 : 영원한 보금자리

[PJ] UIStage 데이터테이블 연동, 추상팩토리와 빌더 패턴

by 왹져박사 2023. 5. 1.
728x90

R&D하고 본 프로젝트에 적용하기 위해 패턴을 공부하였다. 

들어가는 요소들을 데이터로 받아오거나 조절해야 하는 부분들이 많았는데, 직접 붙였던 부분을 개선하고 싶었다. 

chatGPT에게 내 상황을 설명하고, 어떠한 디자인패턴을 적용해야 효과적일까? 물어보았더니, 3~4가지 패턴을 추천해주었다. 그 중에 빌더패턴이 효과적으로 보여 그 패턴과 연계시킬 수 있는 패턴을 물어보았다. 2~3가지를 추천해 주어 원래 싱글톤으로 진행하여 했던 빌더패턴을 추상팩토리와 연계시켜 공부하며 작성해나갔다. 

 

전의 R&D

2023.05.01 - [Project/꿈의 왕국 : 영원한 보금자리] - [R&D] UI small Stage Map UIPlayer Move

 

IUIBuilder 추상팩토리 패턴

인터페이스는 이름 앞에 I(대문자i)를 붙이는 것이 암묵적인 규칙이라고 한다. 

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

public interface IUIBuilder
{
    public IUIBuilder BuildButton();
    public IUIBuilder SetRectTrans(RectTransform rectTrans);
    public IUIBuilder SetName(string name);
    public IUIBuilder SetNum(int num);
    public IUIBuilder SetPosition(float x, float y);
    public IUIBuilder SetSize(float w, float h);
    public IUIBuilder SetSprite(Sprite spriteColor);
}

이를 상속받은 

UIStageCellBuilder

UIStageCell만의 메서드들을 추가하였다. 의도대로 UIStage를 구성하기 위해 메서드를 정말 많이 수정하였다. 

결과 보고, 수정하고 하는 부분이 가장 오래 걸린 듯 하다. 아직도 깔끔하게 수정할 부분이 남은것 같다. 

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

public class UIStageCellBuilder : IUIBuilder
{
    UIStageCell _uiStageCell;

    private const string DefaultName = "Stage";
    private const int DefaultNum = -1;

    private const GameObject DefaultPlayerPosGo = null;
    private const GameObject DefaultColorGo = null;
    private const GameObject DefaultBlackGo = null;
    private const GameObject DefaultLockGo = null;
    private const GameObject DefaultFocusGo = null;

    private RectTransform rectTrans;
    private string _name;
    private int _num;
    private GameObject _btnStageGo;
    private GameObject _playerPosGo;
    private GameObject _lockGo;
    private GameObject _focusGo;

    private GameObject stageGo;

    public UIStageCellBuilder() 
    {
        this.stageGo = new GameObject();
        this.rectTrans = this.stageGo.AddComponent<RectTransform>();
        //this.rectTrans.position = new Vector2(0, 0);
        this._uiStageCell = this.stageGo.AddComponent<UIStageCell>();
    }

    public IUIBuilder SetRectTrans(RectTransform rectTrans)
    {
        this.stageGo.GetComponent<RectTransform>().SetParent(rectTrans);
        return this;
    }

    public IUIBuilder BuildButton()
    {
        this._btnStageGo = new GameObject("btnStage");
        this._btnStageGo.AddComponent<RectTransform>().SetParent(this.rectTrans);
        this._btnStageGo.GetComponent<RectTransform>().localPosition = new Vector2(0, 0);
        //this._btnStageGo.AddComponent<Image>();
        //this._btnStageGo.GetComponent<Image>().color = new Color(1, 1, 1, 0);
        this._btnStageGo.AddComponent<Button>();
        return this;
    }
    public IUIBuilder SetName(string name)
    {
        this.stageGo.name = name;
        this._name = name;
        return this;
    }
    public IUIBuilder SetNum(int num)
    {
        this._num = num;
        return this;
    }
    public IUIBuilder SetPosition(float x, float y)
    {
        var pos = this.rectTrans.localPosition;
        pos.x = x;
        pos.y = y;
        this.rectTrans.localPosition = new Vector3(x,y,0);
        return this;
    }
    public IUIBuilder SetSprite(Sprite spriteColor)
    {
        var img = this._btnStageGo.AddComponent<Image>();
        img.GetComponent<Image>().sprite = spriteColor;
        img.SetNativeSize();
        img.color = new Color(0.3f, 0.3f, 0.3f);

        return this;
    }

    public IUIBuilder SetSize(float w, float h)
    {
        Debug.LogFormat("<color=red>SetSize {0},{1}", w, h);
        var rectTrans = this._btnStageGo.GetComponent<RectTransform>();
        rectTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, w);
        rectTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, h);

        return this;
    }

    public UIStageCellBuilder AddLock(Sprite spriteLock)
    {
        this._lockGo = new GameObject("lockGo");
        this._lockGo.AddComponent<RectTransform>().SetParent(this.rectTrans);
        var rectTrans = this._lockGo.GetComponent<RectTransform>();
        rectTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 220);
        rectTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 220);
        var img = this._lockGo.AddComponent<Image>();
        img.color = new Color(1, 1, 1, 0);

        rectTrans.localPosition = new Vector2(0, 0);

        var go = new GameObject("icon");
        go.AddComponent<RectTransform>().SetParent(rectTrans);
        var rectTrasnIcon = go.GetComponent<RectTransform>();
        var imgIcon = go.AddComponent<Image>();
        imgIcon.sprite = spriteLock;
        imgIcon.SetNativeSize();
        rectTrasnIcon.localPosition = new Vector2(0, 0);
        rectTrasnIcon.localScale = new Vector3(0.8f, 0.8f, 0.8f);

        return this;
    }
    public UIStageCellBuilder AddFocus(Sprite spriteFocus)
    {
        this._focusGo = new GameObject("focusGo");
        this._focusGo.AddComponent<RectTransform>().SetParent(this.rectTrans);
        var rectTrans = this._focusGo.GetComponent<RectTransform>();
        rectTrans.localPosition = new Vector2(0, -50);
        this._focusGo.SetActive(false);
        var img = this._focusGo.AddComponent<Image>();
        img.sprite = spriteFocus;
        img.SetNativeSize();
        rectTrans.localScale = new Vector3(1f, 1f, 1f);

        return this;
    }

    public UIStageCellBuilder SetPlayerPos()
    {
        this._playerPosGo = new GameObject("PlayerPosGo");
        this._playerPosGo.AddComponent<RectTransform>().SetParent(this.rectTrans);
        this._playerPosGo.GetComponent<RectTransform>().localPosition = new Vector2(0, -130);

        return this;
    }

    public GameObject Build()
    {
        _uiStageCell._name = _name;
        _uiStageCell._num = _num;
        _uiStageCell._btnStageGo = _btnStageGo;
        _uiStageCell._focusGo = _focusGo;
        _uiStageCell._playerPosGo = _playerPosGo;
        _uiStageCell._lockGo = _lockGo;

        return this.stageGo;
    }
}

 

그리고 UIStageCell

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

public class UIStageCell : MonoBehaviour
{
    public RectTransform rectTrans;

    public string _name;
    public int _num;
    public GameObject _btnStageGo;
    public GameObject _focusGo;
    public GameObject _playerPosGo;
    public GameObject _lockGo;

    public bool isClear = false;

    private void Start()
    {
        this.rectTrans = GetComponent<RectTransform>();
    }
}

확실히 전보다 훨씬 깔끔해지고 사용하기 편한 느낌이다. 수정이 필요한 상황에도 메서드 이름을 보고 바로 찾아갈 수 있다. 빌더패턴 최고..!

 

728x90