반응형
기본 설정
Canvas를 생성하여 UI를 구성하고 팝업 상자를 띄울 Panel Object를 생성합니다.
(Canvas > Render Mode를 Screen Space - Camera로 설정했습니다.)
(Panel은 Raycast Target을 끄거나 최상단 자식으로 두어야 합니다. 마우스 Click, Enter, Exit 이벤트를 방해할 수 있습니다.)
Popup Panel의 자식으로 팝업 상자와 텍스트를 추가합니다.
(텍스트는 TextMeshPro를 사용했습니다.)
스크립트 추가
PopupManager.cs
더보기
using System.Collections;
using UnityEngine;
using TMPro;
/// <summary>
/// 팝업 상자를 관리하는 클래스입니다.
/// </summary>
public sealed class PopupManager : MonoBehaviour
{
static PopupManager instance = null;
public static PopupManager Instance {
get {
if(instance == null){
instance = FindObjectOfType<PopupManager>();
}
return instance;
}
}
void Update() {
if(IsOnPopup) {
RectTransformUtility.ScreenPointToLocalPointInRectangle(popup_panel.GetComponent<RectTransform>(), Input.mousePosition, Camera.main, out Vector2 position_adjusted);
popup_object.transform.localPosition = position_adjusted;
}
}
/// <summary>
/// 팝업 상자를 띄우는 구역 Object입니다.
/// </summary>
[SerializeField] GameObject popup_panel = null;
/// <summary>
/// 팝업 상자 Object입니다.
/// </summary>
[SerializeField] GameObject popup_object = null;
/// <summary>
/// 팝업 상자 텍스트입니다.
/// </summary>
[SerializeField] TextMeshProUGUI popup_txt = null;
/// <summary>
/// 팝업 상자 활성화 여부입니다.
/// </summary>
bool isOnPopup = false;
/// <summary>
/// 팝업 상자 활성화 여부입니다.
/// </summary>
public bool IsOnPopup { get { return isOnPopup; } }
/// <summary>
/// 팝업 상자 활성화 Coroutine입니다.
/// </summary>
Coroutine enterCount_coroutine;
/// <summary>
/// 팝업 상자 비활성화 Coroutine입니다.
/// </summary>
Coroutine exitCount_coroutine;
/// <summary>
/// 팝업 상자 활성화 대기 시간입니다.
/// </summary>
const float TIME_ENTER = 1f;
/// <summary>
/// 팝업 상자 비활성화 대기 시간입니다.
/// </summary>
const float TIME_EXIT = 0.4f;
/// <summary>
/// 팝업 상자 활성화를 준비합니다.
/// (TIME_ENTER초 후에 팝업 상자를 띄웁니다.)
/// </summary>
/// <param name="description">팝업 상자 내용입니다.</param>
/// <param name="position_target">팝업 상자를 띄울 위치입니다.</param>
public void SetPopup(string description, Vector2 position_target) {
if(enterCount_coroutine != null) { StopCoroutine(enterCount_coroutine); }
if(exitCount_coroutine != null) {StopCoroutine(exitCount_coroutine); }
if(IsOnPopup) {
OnPopup(description, position_target);
} else {
enterCount_coroutine = StartCoroutine(CountEnterTime(description, position_target));
}
IEnumerator CountEnterTime(string description, Vector2 position_target) {
float timer = 0f;
while(timer < TIME_ENTER) {
timer += Time.unscaledDeltaTime;
yield return null;
}
OnPopup(description, position_target);
}
}
/// <summary>
/// 팝업 상자 비활성화를 준비합니다.
/// (TIME_EXIT초 후에 팝업 상자를 닫습니다.)
/// </summary>
public void UnsetPopup() {
if(enterCount_coroutine != null) { StopCoroutine(enterCount_coroutine); }
if(exitCount_coroutine != null) { StopCoroutine(exitCount_coroutine); }
if(IsOnPopup) {
exitCount_coroutine = StartCoroutine(CountExitTime());
}
IEnumerator CountExitTime() {
float timer = 0f;
while(timer < TIME_EXIT) {
timer += Time.unscaledDeltaTime;
yield return null;
}
OffPopup();
}
}
/// <summary>
/// 팝업 상자를 띄웁니다.
/// </summary>
/// <param name="description">팝업 상자 내용입니다.</param>
/// <param name="position_target">팝업 상자를 띄울 위치입니다.</param>
public void OnPopup(string description, Vector2 position_target) {
popup_txt.text = description;
RectTransformUtility.ScreenPointToLocalPointInRectangle(popup_panel.GetComponent<RectTransform>(), position_target, Camera.main, out Vector2 position_adjusted);
popup_object.transform.localPosition = position_adjusted;
popup_object.SetActive(true);
isOnPopup = true;
}
/// <summary>
/// 팝업 상자를 닫습니다.
/// </summary>
public void OffPopup() {
popup_object.SetActive(false);
StartCoroutine(AvailablePopup());
IEnumerator AvailablePopup(){
yield return null;
if(!popup_object.activeSelf) {
isOnPopup = false;
}
}
}
}
해당 Popup Panel에 위 PopupManager 스크립트를 추가합니다.
PopupArea.cs
더보기
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// 팝업 상자를 띄우는 구역을 지정하는 클래스입니다.
/// </summary>
public class PopupArea : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
/// <summary>
/// 해당 구역에서 표시할 문자열입니다.
/// </summary>
[TextArea(3, 5)][SerializeField] string description;
/// <summary>
/// 마우스 클릭시 발생하는 이벤트입니다.
/// </summary>
public void OnPointerClick(PointerEventData pointerEventData) {
PopupManager.Instance.OnPopup(description, pointerEventData.position);
}
/// <summary>
/// 마우스가 구역 안으로 들어올 때 발생하는 이벤트입니다.
/// </summary>
public void OnPointerEnter(PointerEventData pointerEventData) {
PopupManager.Instance.SetPopup(description, pointerEventData.position);
}
/// <summary>
/// 마우스가 구역 밖으로 나갈 때 발생하는 이벤트입니다.
/// </summary>
public void OnPointerExit(PointerEventData pointerEventData) {
PopupManager.Instance.UnsetPopup();
}
}
팝업 상자를 띄울 영역(오브젝트)에 위 PopupArea 스크립트를 추가합니다.
(해당 오브젝트들의 Raycast Target 옵션이 켜져 있어야 합니다.)
다음과 같이 모든 필드 데이터를 할당합니다.
마지막으로 팝업 상자를 비활성화시킵니다.
위와 같이 팝업 상자가 뜨는 것을 확인할 수 있습니다.
(TIME_ENTER, TIME_EXIT 값을 조정하여 팝업 상자가 뜨고 내리는 시간을 조정할 수 있습니다.)
반응형