갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • 유니티 그래프 그리기
  • pc 게임 순위
  • pc게임 순위
  • 글로벌게임매출
  • C++ 소멸자
  • C# 예외 처리
  • 유니티 그래프
  • c# delegate
  • 게임 매출 순위
  • Unity Graph
  • 전세계게임매출순위
  • c# collection
  • c# Thread
  • 2020년 게임 매출
  • C# boxing
  • 게임 디자인 패턴
  • 전세계 게임 매출
  • 모바일 게임 순위
  • c# coroutine
  • 자바
  • 게임매출순위
  • 강남 방탈출
  • C++ virtual
  • c# unboxing
  • C++
  • 알고리즘
  • C++ 상속
  • c# 코루틴
  • 유니티 골드그래프
  • 롤 골드그래프

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

[유니티] Delegate를 이용한 공통 팝업
프로그래밍/유니티

[유니티] Delegate를 이용한 공통 팝업

2021. 7. 6. 01:12
728x90
반응형

언제든 사용할 수 있는 공용 팝업을 만들자!

생김새는 위와같이 3종류의 팝업을 만들어 상황에 맞추어 쓸 예정이다.

 

하이라키는 위처럼 만들었다.

MessagePopUp은 MessagePopUpController를 갖고 있으며

BlockPanel은 뒤에 배경 블러처리용으로 사용했다.

 

메인은 PanelPosition 아래있는 Notice, Caution, Warning이다.

자식으로 있는 Text는 위 그림과 같이 상단의 알림, 주의, 경고가 입력되어있다.

Message는 내가 넣고 싶은 텍스트를 입력할 수 있는 곳이고

OKButton과 YesOrNo버튼은 하단에 "확인" 버튼 하나만 띄울 것인지 "예, 아니오" 버튼 두개를 뜨게할지 골라 출력하게 한다.

 

대략 요런 형태가 된다.

 

아래는 코드


// MessagePopUpController.cs

using System;
using UnintyEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MessagePopUpController : MonoBehaviour
{
    public delegate void Callback();
    private Callback callbackOK = null;
    private Callback callbackYES = null;
    private Callback callbackNO = null;
    
    // Define
    public enum DialogType { NOTICE = 0, WARNING = 1, CAUTION = 2 }
    public enum DialogResponse { OK, YES, NO, ERROR }
    
    public GameObject[] Dialogs;
    public GameObject MessageBox;
    public GameObject OneButton;
    public GameObject YesOrNoButton;
    
    private Button OKButton;
    private Button YesButton;
    private Button NoButton;
    
    private DialogResponse thisResult;
    
    private void Awake()
    {
        // 버튼 배정
        OKButton = OneButton.GetComponent<Button>();
        YesButton = YesOrNoButton.transform.Find("YesButton").gameObject.GetComponent<Button>();
        NoButton = YesOrNoButton.transform.Find("NoButton").gameObject.GetComponent<Button>();
        
        // 기본 리스너 추가
        OKButton.onClick.AddListener(PopUpClose);
        YesButton.onClick.AddListener(PopUpClose);
        NoButton.onClick.AddListener(PopUpClose);
    }

    private void DialogInit() // 초기화
    {
        for (int i = 0; i < Dialogs.Length; i++)
            Dialogs[i].SetActive(false);
    }
    
    public void PopUp(string message, DialogType type)
    {
        SetCallback(null, DialogResponse.OK);

        DialogInit();
        Dialogs[(int)type].SetActive(true);
        MessageBox.GetComponent<Text>().text = message;

        YesOrNoButton.SetActive(false);
        OneButton.SetActive(true);
        OKButton.interactable = true;
        
        GetComponent<Animator>().SetTrigger("PopupOpen");
    }

    public void PopUp(string message, DialogType type, Callback Function)
    {
        SetCallback(Function, DialogResponse.OK);

        DialogInit();
        Dialogs[(int)type].SetActive(true);
        MessageBox.GetComponent<Text>().text = message;

        YesOrNoButton.SetActive(false);
        OneButton.SetActive(true);
        OKButton.interactable = true;

        GetComponent<Animator>().SetTrigger("PopupOpen");
    }

    public void YesOrNoPopUp(string message, DialogType type, Callback yesButtonFuncion, Callback noButtonFuntion)
    {
        SetCallback(yesButtonFuncion, DialogResponse.YES);
        SetCallback(noButtonFuntion, DialogResponse.NO);

        DialogInit();
        Dialogs[(int)type].SetActive(true);
        MessageBox.GetComponent<Text>().text = message;

        OneButton.SetActive(false);
        YesOrNoButton.SetActive(true);
        YesButton.interactable = true;
        NoButton.interactable = true;

        GetComponent<Animator>().SetTrigger("PopupOpen");
    }

    // 팝업이 닫힐 때, 지정해 둔 콜백 실행
    public void PopUpClose()
    {
        switch (EventSystem.current.currentSelectedGameObject.name)
        {
            case "OKButton":
                thisResult = DialogResponse.OK;
                callbackOK?.Invoke();
                callbackOK = null;
                break;
                
            case "YesButton":
                thisResult = DialogResponse.YES;
                callbackYES?.Invoke();
                callbackYES = null;
                break;

            case "NoButton":
                thisResult = DialogResponse.NO;
                callbackNO?.Invoke();
                callbackYES = null;
                break;

            default:
                thisResult = DialogResponse.ERROR;
                break;
        }

        OKButton.interactable = false;
        YesButton.interactable = false;
        NoButton.interactable = false;

        GetComponent<Animator>().SetTrigger("PopupClose");
    }

    // Callback 관련
    public void SetCallback(Callback call, DialogResponse buttontype)
    {
        switch (buttontype)
        {
            case DialogResponse.OK:
                callbackOK = call;
                break;

            case DialogResponse.YES:
                callbackYES = call;
                break;

            case DialogResponse.NO:
                callbackNO = call;
                break;

            default:
                callbackOK = call;
                callbackYES = call;
                callbackNO = call;
                break;
        }
    }

    internal void YesOrNoPopUp(string v1, DialogType nOTICE, object v2, object p)
    {
        throw new NotImplementedException();
    }
}

다른 코드는 전부 보면 이해가고 핵심은 delegate를 이용해 메소드를 넘겨주어 처리한다는 것이다.

사용은 아래와 같이 하면 된다.

// 싱글톤
    MessagePopupController.instance.Popup("Message", DialogType.Notice, MethodName);
    MessagePopupController.instance.Popup("Message", DialogType.Notice, () => HelloWorld());
    
// public으로 등록해놓고 쓰기
    messagePopupController.YesOrNoPopUp("Message", DialogType.Notice, YesMethod, null);
    messagePopupController.YesOrNoPopUp("Message", DialogType.Notice, null, () => NoMethod(param));

Delegate를 간단하게 요약하자면 (이전에 쓴글 복붙)

인자를 전달하려면 람다식을 쓰면 된다.

 

최종결과물

    MessagePopUpController.instance.YesOrNoPopUp("튜토리얼 화면을 종료하고 다음으로 진행하시겠습니까?",
                                                 DialogType.Notice,
                                                 () => CombatManager.instance.StartBattle(player, State.Start),
                                                 null);

 

아,

1. Delegate를 쓸 때 Invoke를 사용하자

2. ?를 통해 null검사가 가능하다. (Method?.Invoke();)

728x90
반응형

'프로그래밍 > 유니티' 카테고리의 다른 글

[유니티] 롤 골드그래프를 만들어보자(2) - 선 찍기  (0) 2021.08.10
[유니티] 롤 골드그래프를 만들어보자(1) - 점 찍기  (26) 2021.08.09
[유니티] UI 클릭 등 이벤트 처리  (0) 2020.12.10
[유니티] 3D 오브젝트 마우스로 회전시키기  (0) 2020.12.10
[유니티] 뷰포리아(Vuforia) SDK를 이용한 오브젝트 트레킹 체크  (0) 2017.09.28
    '프로그래밍/유니티' 카테고리의 다른 글
    • [유니티] 롤 골드그래프를 만들어보자(2) - 선 찍기
    • [유니티] 롤 골드그래프를 만들어보자(1) - 점 찍기
    • [유니티] UI 클릭 등 이벤트 처리
    • [유니티] 3D 오브젝트 마우스로 회전시키기
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바