게임 개발/Unity

[Unity C#] 팝업창 만들기 - 빌더패턴의 활용

Heesuk Lee 2019. 8. 3. 19:24

 

 

 

기존에 포스팅했었던 빌더패턴을 기반으로 유니티에서 가장 기초적인 빌더패턴을 이용한 팝업창을 구현해봤습니다. 

 

https://welcomeheesuk.tistory.com/44?category=786876

 

[디자인패턴]01. 빌더패턴(builder pattern)

빌더 패턴 위키백과: https://ko.wikipedia.org/wiki/%EB%B9%8C%EB%8D%94_%ED%8C%A8%ED%84%B4 1. 빌더패턴 빌더패턴이란 복합객체의 생성과정과 표현방법을 분리하여 동일한 생성절차에서 서로 다른 표현 결과를..

welcomeheesuk.tistory.com

 

 

팝업버튼을 클릭시 팝업창이 생성됩니다.

 

 

 

1. 팝업빌더 사용법

 

 1) 원하는 부분에서 팝업빌더를 new로 생성해줍니다.

 2) 내부요소들을 세팅해주는 메소드를 호출해줍니다.

 3) 마지막에 Build()메소드로 최종적인 팝업창을 생성합니다. 

    public void OnButtonEvent()
    {
        // 생성자의 매개변수로 팝업의 하이라키 위치 설정 -> 일반적으로 최상단 canvas가 좋다.
        PopupBuilder popupBuilder = new PopupBuilder(this.transform);
        popupBuilder.SetTitle("게임종료");
        popupBuilder.SetDescription("게임을 종료하시겠습니까?");
        
        // 버튼은 왼쪽부터 생성된다, 아무기능 없을때는 2번째 매개변수 작성 x
        popupBuilder.SetButton("취소");
        popupBuilder.SetButton("확인", this.ExitGame);
        popupBuilder.Build();
    }

 

 

2. 다음은 팝업빌더 클래스입니다.

 

 1) 팝업창에 각요소를 세팅해주는 메소드와

 2) 최종적으로 팝업창을 생성해주는 메소드로 구성됩니다.

* 자세한부분은 상단의 '빌더패턴' 링크를 참고해주시면 좀더 이해하기 좋습니다!

// 생성자의 사용을 위해 MonoBehaviour 의 상속제거
public class PopupBuilder
{
    private Transform target = null;
    
    // Build메소드 호출할때 팝업창을 꾸며주기 위한 멤버변수
    private string title = null;
    private string description = null;
    private List<PopupButtonInfo> buttonInfoList = null;
	
    // 생성자에서 부모타겟 매개변수로 가져온다.
    public PopupBuilder(Transform _target)
    {
        this.target = _target;
        this.buttonInfoList = new List<PopupButtonInfo>();
    }
    
    public void Build()
    {
    	// 최종적으로 모든정보를 가지고 팝업창생성
        
        // MonoBehaviour의 제거로 인해 Instantiate을 사용불가,
        // 프리팹생성을 위해 GameObject의 static메소드로 호출
        GameObject popupObject = GameObject.Instantiate(Resources.Load("Popup/" + "PopupPanel", typeof(GameObject))) as GameObject;
        popupObject.transform.SetParent(this.target, false);
        PopupPanel popupPanel = popupObject.GetComponent<PopupPanel>();

        // 팝업설정
        popupPanel.setTitle(this.title);
        popupPanel.setDescription(this.description);
        popupPanel.setButtons(this.buttonInfoList);
        popupPanel.Init();
    }

    public void SetTitle(string _title)
    {
    	// 타이틀정보 초기화
        this.title = _title;
    }
    
    public void SetDescription(string _description)
    {
    	// 설명정보 초기화
        this.description = _description;
    }
    
    public void SetButton(string _text, CallbackEvent _callback = null)
    {
    	// 버튼정보 초기화 - 호출할때마다 버튼 하나씩 추가
        this.buttonInfoList.Add(new PopupButtonInfo(_text, _callback));
    }
}

 

중요한것은 Resources.Load를 위해선 Resources폴더에 있어야합니다.

 

 

 

3. 실제로 팝업창이 컴포넌트로 가져야하는 클래스입니다.

 

PopupPanel이 가지는 하이라키입니다.

// 팝업창 객체가 들고있는 클래스 builder에서 가져온 정보로 팝업창을 꾸며준다.
public class PopupPanel : MonoBehaviour
{
	
    // 제목 text오브젝트
    [SerializeField]
    private Text titleText = null;
    
    // 설명 text오브젝트
    [SerializeField]
    private Text descriptionText = null;
    
    // 버튼생성시 버튼들의 부모, 레이아웃을 사용해 생성시마다 위치를 잡아준다.
    [SerializeField]
    private GameObject buttonsLayout = null;
	
    // 버튼 프리팹
    [SerializeField]
    private GameObject buttonPrefab = null;

    public void Init()
    {
        // 팝업등장 - 추가적인 초기화 정보는 여기에 구현, 팝업창생성시 확대되는 느낌같은 연출 넣기에 좋다.
    }
    
    public void setTitle(string _title)
    {
        this.titleText.text = _title;
    }
    
    public void setDescription(string _description)
    {
        this.descriptionText.text = _description;
    }
    
    public void setButtons(List<PopupButtonInfo> _popupButtonInfos)
    {
        // 버튼 초기화
        foreach (var info in _popupButtonInfos)
        {
            // 버튼 동적생성
            GameObject buttonObject = Instantiate(this.buttonPrefab);
            buttonObject.transform.SetParent(this.buttonsLayout.transform, false);
            PopupButton popupButton = buttonObject.GetComponent<PopupButton>();

            popupButton.Init(info.text, info.callback, this.gameObject);
        }
    }
}

 

 

PopupPanel클래스에 들어갈 각요소와 팝업버튼 프리팹이 필요합니다.

 

 

4. 팝업창에서 동적으로 생성되는 버튼이 컴포넌트로 가지고있어야할 클래스입니다.

// 팝업창에서 생성되는 팝업버튼의 클래스
public class PopupButton : MonoBehaviour
{
    [SerializeField]
    private Text buttonString = null;

    private GameObject target = null;
    private CallbackEvent callbackEvent = null;
    
    public void Init(string _text, CallbackEvent _callback, GameObject _target)
    {
        // 초기화 - 매개변수로 받은 이름과 콜백함수로 클릭시 콜백함수를 호출해주는 팝업버튼
        this.buttonString.text = _text;
        this.callbackEvent = _callback;
        this.target = _target;
    }

    public void OnButton()
    {
        // 초기화된 콜백함수 호출
        this.callbackEvent();
        Destroy(target);
    }
}

 

 

5. 팝업창 구현을 위해 패턴이외에 필요로 했었던 추가적인 부분입니다.

 

 1) 버튼을 눌렀을때 호출되는 콜백함수입니다.

 2) 버튼이 필요한 정보를 들고있는 PopupButtonInfo 클래스 입니다.

// 팝업창에 생기는 버튼이벤트를 위한 델리게이트 콜백함수
public delegate void CallbackEvent();

public class PopupButtonInfo
{
    // 버튼정보를 들고있는 클래스 - Builder에서 popup객체로 정보를 보낼때 사용
    public string text = null;
    public CallbackEvent callback = null;

    public PopupButtonInfo(string _text, CallbackEvent _callback)
    {
        this.text = _text;
        this.callback = _callback == null ? () => {} : _callback;
    }
}
반응형