[unity] 모듈 제작 : 팝업 시스템 만들기(3)
팝업을 관리하는 매니저 클래스인 PopupManager Class를 제작해보자.
1. 스크립트 작성
제작 해야될 스크립트는 총 7가지로 각 클래스 별 기능 설명을 하자면 다음과 같다.
1. Popup : 팝업 객체에 붙는 컴포넌트로 팝업 내 UI 요소들을 컨트롤 하는 클래스
2. PopupManager : 팝업을 관리하는 매니저 클래스
3. PopupAnimator : 팝업 애니메이션을 관리하는 클래스
4. PopupButton : 팝업 전용 버튼 클래스
5. PopupButtonInfo : 팝업 전용 버튼 정보 클래스
6. PopupButtonType : 팝업 버튼 타입 정의 Enum
7. PopupInfo : 팝업 생성을 위한 정보를 담은 클래스
1. Popup Class
- 타이틀, 내용, 버튼의 UI 요소를 가지고 있으며, 초기화 시 해당 내용을 UI에 업데이트 해준다.
using UnityEngine;
using UnityEngine.UI;
using System;
namespace Container.Popup
{
[Serializable]
public class PopupInfoDictionary : SerializableDictionary<PopupButtonType, PopupButtonInfo> { }
[RequireComponent(typeof(PopupAnimator))]
public class Popup : MonoBehaviour
{
[SerializeField]
protected Text txt_title = null;
[SerializeField]
protected Text txt_content = null;
[SerializeField]
protected Transform root_button = null;
[SerializeField]
protected GameObject basic_PopupButton = null;
[SerializeField]
private PopupInfoDictionary dic_popupButtonInfo;
public bool IsShow => this.gameObject.activeSelf;
/// <summary>
/// 초기화 함수.
/// </summary>
/// <param name="info">팝업 정보</param>
public void OnInitialize(PopupInfo info)
{
txt_title.text = info.Title;
txt_content.text = info.Content;
SetButtons(info.Buttons);
}
protected virtual void SetButtons(PopupButtonType[] btns)
{
for (int i = 0; i < btns.Length; i++)
{
GameObject popupObject = Instantiate(basic_PopupButton, root_button);
popupObject.transform.localScale = Vector3.one;
popupObject.SetActive(true);
PopupButton popupButton = popupObject.GetComponent<PopupButton>();
popupButton.Type = btns[i];
try
{
popupButton.Name = dic_popupButtonInfo[popupButton.Type].str_name;
popupButton.Color = dic_popupButtonInfo[popupButton.Type].color_button;
}
catch { Debug.Log("요청 타입이 PopupInfo에 정의되어 있지 않습니다."); }
}
}
protected virtual void SetButtonColor()
{
}
public void Show()
{
gameObject.SetActive(true);
}
public void Hide()
{
PopupButton[] popupButtons = root_button.GetComponentsInChildren<PopupButton>(true);
foreach (PopupButton btn in popupButtons)
{
DestroyImmediate(btn.gameObject);
}
gameObject.SetActive(false);
}
}
}
2. PopupManager Class
- 싱글톤으로 구현하여, Instance를 통해 어디서든 접근하기 용이하게 구성한다.
- ShowPopup 함수를 통해 팝업을 Show 시킨다.
- HidePopup 함수를 통해 팝업을 Hide 시킨다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Container.Popup
{
public class PopupManager : MonoBehaviour
{
[SerializeField]
protected GameObject dim = null;
[SerializeField]
protected Popup popup = null;
protected PopupAnimator obj_Animator = null;
protected System.Action<PopupButtonType> OnClosedPopupListener;
public static PopupManager Instance { get; private set; }
private void Awake()
{
Instance = this;
if (popup == null)
popup = GetComponentInChildren<Popup>(true);
obj_Animator = popup.GetComponent<PopupAnimator>();
}
private void OnDestroy()
{
Instance = null;
}
public void ShowPopup(string contents)
{
ShowPopup(string.Empty, contents);
}
/// <summary>
/// Basic 한 팝업 호출시 사용.
/// </summary>
/// <param name="title">타이틀 내용</param>
/// <param name="contents">콘텐츠 내용</param>
public void ShowPopup(string title, string contents)
{
PopupInfo info = new PopupInfo.Builder()
.SetTitle(title)
.SetContent(contents)
.SetButtons(PopupButtonType.Confirm)
.Build();
ShowPopup(info);
}
/// <summary>
/// 팝업의 다양한 정보를 가지고 호출할시 사용.
/// </summary>
/// <param name="info">팝업 정보</param>
public void ShowPopup(PopupInfo info)
{
if(popup.IsShow)
{
return;
}
if (info.PauseScene)
Time.timeScale = 0;
popup.OnInitialize(info);
OnClosedPopupListener = info.Listener;
dim.SetActive(true);
popup.Show();
obj_Animator.startAnimation(info.Animation);
}
public void HidePopup()
{
Time.timeScale = 1;
dim.SetActive(false);
popup.Hide();
}
public virtual void OnClosePopup(PopupButtonType type)
{
if (OnClosedPopupListener != null)
{
OnClosedPopupListener(type);
OnClosedPopupListener = null;
}
HidePopup();
}
}
}
3. PopupAnimator
- 팝업이 Show/Hide 될때 약간의 Tween 효과를 주기 위해 필요한 클래스이다.
- LeanTweenType을 설정하여, 다양한 Tween 효과를 줄 수 있다.
- PopupAnimationType 은 4가지로 제공한다.
. Alpha : 팝업이 천천히 나오고 천천히 사라지는 컬러 효과
. Scale : 팝업이 스케일 0에서 1까지 나오는 효과
. LeftToRight : 팝업이 왼쪽에서 나와서 오른쪽으로 사라지는 효과
. TopToBottom : 팝업이 위에서 나와서 아래로 사라지는 효과
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Container.Popup
{
public enum PopupAnimationType
{
None = 0,
Alpha = 1,
Scale = 2,
LeftToRight = 3,
TopToBottom = 4,
}
public class PopupAnimator : MonoBehaviour
{
protected const float MOTION_SPEED = 0.5f;
public LeanTweenType tweenType = LeanTweenType.easeOutBack;
private RectTransform rect_Target = null;
private void Awake()
{
if (rect_Target == null)
rect_Target = GetComponent<RectTransform>();
}
public virtual void startAnimation(PopupAnimationType animationType)
{
if (rect_Target == null)
rect_Target = GetComponent<RectTransform>();
switch (animationType)
{
case PopupAnimationType.Scale:
{
rect_Target.localScale = Vector3.zero;
LeanTween.scale(rect_Target, Vector3.one, MOTION_SPEED)
.setEase(tweenType)
.setIgnoreTimeScale(true);
break;
}
case PopupAnimationType.Alpha:
{
if (!GetComponent<CanvasGroup>())
gameObject.AddComponent<CanvasGroup>();
GetComponent<CanvasGroup>().alpha = 0;
LeanTween.alphaCanvas(GetComponent<CanvasGroup>(), 1, MOTION_SPEED)
.setEase(tweenType)
.setIgnoreTimeScale(true);
break;
}
case PopupAnimationType.LeftToRight:
{
rect_Target.localPosition = new Vector3(-Screen.width, 0);
LeanTween.move(rect_Target, Vector2.zero, MOTION_SPEED)
.setEase(tweenType)
.setIgnoreTimeScale(true);
break;
}
case PopupAnimationType.TopToBottom:
{
rect_Target.localPosition = new Vector3(0, Screen.height);
LeanTween.move(rect_Target, Vector2.zero, MOTION_SPEED)
.setEase(tweenType)
.setIgnoreTimeScale(true);
break;
}
}
}
}
}
댓글