✅ 기능
특정한 스토리나 전달하고자 할 메시지를 강조하기위해서, 마치 영상을 보고있는 느낌을 주기위해 레터박스를 사용할 수 있습니다. 레터박스 기능을 구현하고, 매우 쉽게 호출하여 연출할 수 있도록 정리해봤습니다.
✅ 응용 기능
UI에서 사용하는 RectTransform을 이용합니다.
✅ 흐름도
✅ 사용 예시
✅ 구현
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 레터박스 기능을 제공하는 클래스
/// </summary>
public class LetteringBoxController : Singleton<LetteringBoxController>
{
private static bool mIsEnable; //현재 활성화 되어있는가?
/// <summary>
/// 현재 레터박스가 활성화 되어있는가?
/// </summary>
public static bool IsEnable
{
get
{
return mIsEnable;
}
}
[Header("위쪽 레터박스 트랜스폼")]
[SerializeField] private RectTransform mTopBoxTransform;
[Header("아래쪽 레터박스 트랜스폼")]
[SerializeField] private RectTransform mBottomBoxTransform;
[Header("레터박스 활성화 시 설정할 높이(Scale With Screen Size 800*600 기준)")]
[SerializeField][Range(0f, 300f)] private float mBoxHeight = 50f; //활성화 시 사용할 박스의 높이
[Header("레터박스를 토글할 때 활성화/비활성화 할 UI요소들")]
[SerializeField] private CanvasGroup[] mToggleObjects;
private Vector2 mEnableBoxSize; //활성화 시 사용할 박스의 크기
private Coroutine mToggleCoroutine; //토글에 사용할 코루틴
private void Awake()
{
//초기 사이즈는 0으로 설정
mBottomBoxTransform.sizeDelta = mTopBoxTransform.sizeDelta = Vector2.zero;
//박스 높이 저장
mEnableBoxSize = new Vector2(0f, mBoxHeight);
}
/// <summary>
/// 레터박스와 UI요소를 토글한다.
/// </summary>
/// <param name="isEnable">레터박스를 활성화 할것인가?</param>
/// <param name="delayTime">레터박스 토글을 시작할 딜레이 시간</param>
/// <param name="duration">레터박스 토글에 걸리는 소요시간</param>
public void ToggleBox(bool isEnable, float delayTime = 0f, float duration = 1.0f)
{
if(mToggleCoroutine != null) { StopCoroutine(mToggleCoroutine); }
mToggleCoroutine = StartCoroutine(COR_ToggleLetteringBox(isEnable, delayTime, duration));
}
/// <summary>
/// 레터박스와 UI요소를 토글한다.
/// </summary>
private IEnumerator COR_ToggleLetteringBox(bool isEnable, float delayTime, float duration)
{
//딜레이가 있다면 대기
if(delayTime > 0f) { yield return new WaitForSeconds(delayTime); }
float process = 0f; //프로세스 생성
Vector2 currentSize = mTopBoxTransform.sizeDelta; //현재 사이즈 가져오기
if(isEnable) { mIsEnable = true; } //활성화 상태 등록
while(process < 1.0f)
{
//duration을 적용하여 process 증가
process += Time.deltaTime / duration;
//레터박스 크기 설정
mTopBoxTransform.sizeDelta = mBottomBoxTransform.sizeDelta = Vector2.Lerp(currentSize, isEnable ? mEnableBoxSize : Vector2.zero, process);
//캔버스 그룹 토글
foreach(CanvasGroup canvasGroup in mToggleObjects) { canvasGroup.alpha = Mathf.Lerp(canvasGroup.alpha, isEnable ? 0f : 1f, process); }
yield return null;
}
if(!isEnable) { mIsEnable = false; } //비활성화 상태 등록
}
}
- 레터박스는 씬 내에 하나만 존재하며, 컨트롤러(본 스크립트)또한 하나만 존재합니다.
- 싱글턴 패턴을 적용하여 외부에서 간편하게 호출하도록 구현하였습니다.
public static bool IsEnable
- 현재 레터박스가 활성화 되어있는지 확인하기 위한 정적변수입니다.
- LetteringBoxController.IsEnable로 외부에서 현재 레터박스가 활성화되었는지 검사할 수 있습니다.
[Header("위쪽 레터박스 트랜스폼")]
[SerializeField] private RectTransform mTopBoxTransform;
[Header("아래쪽 레터박스 트랜스폼")]
[SerializeField] private RectTransform mBottomBoxTransform;
- 캔버스에서 위쪽, 아래쪽에 있는 레터박스 오브젝트의 트랜스폼입니다.
- 상단 레터박스라고 가정했을때, 아래 사진과 같이 앵커는 상단 및 스트레치, 피벗은 상단 중앙으로 설정합니다.
[Header("레터박스 활성화 시 설정할 높이(Scale With Screen Size 800*600 기준)")]
[SerializeField][Range(0f, 300f)] private float mBoxHeight = 50f; //활성화 시 사용할 박스의 높이
- 레터박스를 활성화 할 때 레터박스의 높이를 설정합니다.
- 사용하는 높이는 캔버스 설정이 Scale With Screen Size로 되어있음을 기준으로 하며, 높이는 600으로 설정한 상태입니다.
[Header("레터박스를 토글할 때 활성화/비활성화 할 UI요소들")]
[SerializeField] private CanvasGroup[] mToggleObjects;
- 레터박스가 토글될 때 함께 토글될 게임오브젝트들을 설정하는 배열입니다.
- 레터박스가 활성화되면 배열에 있는 오브젝트들의 캔버스그룹을 사용하여 서서히 투명해지게 합니다.
public void ToggleBox(bool isEnable, float delayTime = 0f, float duration = 1.0f)
- 외부에서 호출하며, 레터박스를 토글하는 함수입니다.
isEnable: 레터박스를 활성화 할것인가?
delayTime: 레터박스 토글을 시작할 딜레이 시간
duration: 레터박스 토글에 걸리는 소요시간
private IEnumerator COR_ToggleLetteringBox(bool isEnable, float delayTime, float duration)
- 실질적인 토글 수행하는 코루틴으로, 서서히 나타나고, 사라지게 하도록 합니다.
- process를 사용하여 duration과 함께 계산하여 duration을 설정한 값대로 정확히 작동하게 합니다.
✅ 사용(외부에서 호출)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GlobalEventHandler : Singleton<GlobalEventHandler>
{
...
/// <summary>
/// 특정 Id의 이벤트를 시작한다
/// </summary>
/// <param name="eventId">시작할 이벤트 Id</param>
public void RunEvent(int eventId)
{
...
switch (mCurrentEventId)
{
case 0: //게임시작
{
//레터박스 활성화
LetteringBoxController.Instance.ToggleBox(true);
//대사 호출
float duration = QuoteManager.Instance.DisplayQuote(QuoteManager.Instance.GetPreloadLabel("Player"), 0);
//이벤트 호출
RunEvent(1, duration);
break;
}
case 1: //움직임 튜토리얼
{
//대사 호출
float duration = QuoteManager.Instance.DisplayQuote(QuoteManager.Instance.GetPreloadLabel("Tutorial0"), 1, null, 0f);
//레터박스 활성화
LetteringBoxController.Instance.ToggleBox(false, duration);
break;
}
...
}
}
...
}
LetteringBoxController.Instance.ToggleBox(true);
LetteringBoxController.Instance.ToggleBox(false, duration);
- 인자에 true가 들어가면 레터박스가 활성화됩니다.
- 두번째 인자인 duration은 duration초 만큼 기다렸다가 토글되게 합니다.
'unity game modules' 카테고리의 다른 글
[유니티] 인벤토리 시스템(번외) - 장비 아이템 착용 (1) | 2023.02.06 |
---|---|
[유니티] 인벤토리 시스템(번외) - 아이템 툴팁 (0) | 2023.02.06 |
[유니티] VideoPlayer URL 재생 및 관리 (0) | 2023.01.02 |
[유니티] 인벤토리 시스템(번외) - 쿨타임 기능 (0) | 2022.12.28 |
[유니티] 인벤토리 시스템(6) - 아이템 사용 (0) | 2022.12.27 |