booooox
[Unity] Reverse Mask UI 팝업 (구멍 팝업) 본문
반응형
1. Reverse Mask : 이미지를 타켓이미지 모양대로 출력하는 방식의 Mask를 역으로 사용한 방식
2. 기대효과 :
1) Fade Out효과와 함께 사용하여 씬 변경에 이용할 수 있다.
3. 사용법 :
1) - MaskImage (부모) : 구멍 낼 이미지
- MaskedImage (자식) : 배경 이미지
2) MaskedImage (자식) 오브젝트에 <Image> 컴포넌트를 지우고 아래 스크립트를 추가하고 사이즈를 넉넉하게 해준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
public class MaskedUI : Image
{
public override Material materialForRendering
{
get
{
Material material = new Material(base.materialForRendering);
material.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
return material;
}
}
protected override void Start()
{
base.Start();
StartCoroutine(Fix());
}
/// Fix for async loading scenes
private IEnumerator Fix()
{
yield return null;
maskable = false;
maskable = true;
}
}
3) MaskImage (부모) 오브젝트에 <Image> 컴포넌트에 적용할 모양의 이미지를 넣고 구멍 안쪽으로 이미지 크기를 설정한다.
4) 아래 스크립트등 으로 팝업으로 활용 가능하다. (페이드 인, 아웃 적용)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FadePopup : MonoBehaviour
{
[SerializeField] private Image maskImage;
[SerializeField] private Image maskedImage;
[SerializeField, Range(0.1f, 3f)] private float fadeSpeed = 1f;
[ReadOnly] private float maskImageMaxWidth;
[ReadOnly] private float maskImageMaxHeight;
private void Awake()
{
// 이미지 안가리도록 maskImage 마스크 설정 해 두기
maskImage.TryGetComponent<RectTransform>(out RectTransform maskImageRect);
maskImageMaxWidth = maskImageRect.rect.width;
maskImageMaxHeight = maskImageRect.rect.height;
// UnActive maskImage
maskImage.gameObject.SetActive(false);
}
/// <summary>
/// Call Fade_Out
/// </summary>
/// <param name="fadeAction">Action that Completes Fade Out</param>
public void FadeOut(Action fadeAction = null) => StartCoroutine(FadeOutCoroutine(fadeAction));
IEnumerator FadeOutCoroutine(Action fadeAction)
{
yield return null;
maskImage.TryGetComponent<RectTransform>(out RectTransform maskImageRect);
maskImageRect.sizeDelta = new Vector2(maskImageMaxWidth, maskImageMaxHeight);
maskImage.gameObject.SetActive(true);
float currentTime = 0;
float currentWidth = maskImageMaxWidth;
float currentHeight = maskImageMaxHeight;
while(true) {
yield return null;
currentTime += Time.deltaTime;
currentWidth = currentWidth <= 0f ? 0f : Mathf.Lerp(maskImageMaxWidth, 0f, currentTime / fadeSpeed);
currentHeight = currentHeight <= 0f ? 0f : Mathf.Lerp(maskImageMaxHeight, 0f, currentTime / fadeSpeed);
maskImageRect.sizeDelta = new Vector2(currentWidth, currentHeight);
if (currentWidth <= 0f && currentHeight <= 0f) break;
}
fadeAction?.Invoke();
}
/// <summary>
/// Call Fade_In
/// </summary>
public void FadeIn() => StartCoroutine(FadeInCoroutine());
IEnumerator FadeInCoroutine()
{
yield return null;
maskImage.TryGetComponent<RectTransform>(out RectTransform maskImageRect);
maskImageRect.sizeDelta = new Vector2(0, 0);
maskImage.gameObject.SetActive(true);
float currentTime = 0;
float currentWidth = 0;
float currentHeight = 0;
while(true) {
yield return null;
currentTime += Time.deltaTime;
currentWidth = currentWidth >= maskImageMaxWidth ? maskImageMaxWidth : Mathf.Lerp(0f, maskImageMaxWidth, currentTime / fadeSpeed);
currentHeight = currentHeight >= maskImageMaxHeight ? maskImageMaxHeight : Mathf.Lerp(0f, maskImageMaxHeight, currentTime / fadeSpeed);
maskImageRect.sizeDelta = new Vector2(currentWidth, currentHeight);
if (currentWidth >= maskImageMaxWidth && currentHeight >= maskImageMaxHeight) break;
}
maskImage.gameObject.SetActive(false);
}
}
반응형
'Unity > System' 카테고리의 다른 글
[Unity] SoundManager (Audio Mixer) (0) | 2024.10.16 |
---|---|
[Unity] PopupManager (팝업 시스템) (1) | 2024.10.09 |
[Unity] 플레이어 상태 전환 (전략패턴) (0) | 2024.08.21 |
[Unity] Animation Event (시작, 끝 이벤트) (0) | 2024.07.23 |
[Unity] MonoSingleton (모노싱글톤) (4) | 2024.07.22 |