event 와 delegate 를 이용.
Canvas 에서 UI 를 아래처럼 만든다.
YesnoBox, MsgPanel => Panel
YesButton, NoButton => Button
MsgText, Text => Text
프리팹으로 집어 넣는다.
필요할 때마다 런타임에 로드하기 위해 Assets/Resources/Prefabs/Canvas/YesnoBox 에 집어 넣었다.
YesnoBox.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class YesnoBox : MonoBehaviour
{
[SerializeField]
public Text txtMsg;
[SerializeField]
public Text txtButtonYes;
[SerializeField]
public Text txtButtonNo;
public delegate void YesnoCallBack();
private event YesnoCallBack yesCallBack;
private event YesnoCallBack noCallBack;
void Start()
{
// txtMsg 는 호출하는 쪽에서 셋팅
txtButtonYes.text = "네";
txtButtonNo.text = "아니오";
}
public void SetYesCallback(YesnoCallBack listener)
{
yesCallBack += listener;
}
public void SetNoCallback(YesnoCallBack listener)
{
noCallBack += listener;
}
public void OnYes()
{
yesCallBack?.Invoke();
}
public void OnNo()
{
noCallBack?.Invoke();
}
}
YesnoBox 에 이 스크립트를 붙인다.
그리고 text 들을 참조 시킨다.
Yes 버튼과 No 버튼의 OnClick() 설정을 한다. 참조 오브젝트는 YesnoBox 를 넣는다.
호출하는 쪽은 다음과 같다.
void AskYesno()
{
GameObject obj = Resources.Load<GameObject>("Prefabs/Canvas/YesnoBox");
GameObject parent = GameObject.Find("Canvas");
GameObject yesnoBox = Instantiate<GameObject>(obj, parent.transform, false);
yesnoBox.gameObject.SetActive(true);
YesnoBox yesnoScript = yesnoBox.GetComponent<YesnoBox>();
yesnoScript.txtMsg.text = "하시겠습니까?";
yesnoScript.SetYesCallback(() =>
{
print("Yes callback");
Destroy(yesnoBox.gameObject);
});
yesnoScript.SetNoCallback(() =>
{
print("No callback");
Destroy(yesnoBox.gameObject);
});
}
실행된 모습