TIL - Unity UI FadeOut 코루틴 이해하기

김보근·2024년 12월 30일

Unity

목록 보기
96/113

TIL - Unity UI FadeOut 코루틴 이해하기

오늘은 Unity에서 UI 패널을 서서히 투명하게 만들고, 완전히 사라지면 HUD 패널을 켜주는 코루틴을 작성했다.

1. 코루틴이란?

Unity에서는 특정 작업을 시간에 따라 나눠서 실행하고 싶을 때 코루틴(Coroutine)을 사용한다. 일반적으로 코드는 한 번 실행되면 끝나지만, 코루틴은 yield return을 사용해 중간에 멈췄다가 다음 프레임에서 다시 시작하는 방식이다. 덕분에 애니메이션이나 UI 페이드 효과 같은 것들을 부드럽게 구현할 수 있다.

2. FadeOutPanel() 함수 분석

IEnumerator FadeOutPanel(GameObject panel, float duration, System.Action onComplete = null)

panel: 투명하게 만들 패널 오브젝트

duration: 페이드아웃이 완료되기까지 걸리는 시간(초)

onComplete: 패널이 완전히 사라진 후 실행할 콜백(선택 사항)

코루틴은 IEnumerator를 반환해야 한다. 이 메서드는 UI 패널을 서서히 투명하게 만든 뒤 비활성화하고, HUD 패널을 활성화하는 역할을 한다.

3. CanvasGroup 추가하기

CanvasGroup canvasGroup = panel.GetComponent<CanvasGroup>();
if (canvasGroup == null)
{
    canvasGroup = panel.AddComponent<CanvasGroup>();
}

CanvasGroup은 Unity에서 UI의 투명도(Alpha)를 조절하는 데 사용하는 컴포넌트다.

panel에 CanvasGroup이 붙어있는지 확인하고, 없으면 AddComponent를 사용해 동적으로 추가한다.

CanvasGroup.alpha 값만 조절하면 투명해지지만, interactable과 blocksRaycasts를 함께 사용하면 패널이 클릭되지 않도록 설정할 수도 있다.

왜 필요할까?

Unity에서는 Image나 TextMeshPro 자체에는 alpha 값을 조절하는 기능이 없다.

CanvasGroup을 사용해야만 부모 오브젝트 전체의 투명도를 조절할 수 있다.

4. 투명도 조절 (Lerp 사용)

float startAlpha = canvasGroup.alpha;
float elapsedTime = 0f;

while (elapsedTime < duration)
{
    elapsedTime += Time.deltaTime;
    canvasGroup.alpha = Mathf.Lerp(startAlpha, 0f, elapsedTime / duration);
    yield return null;
}

startAlpha: 시작 시의 투명도 값 (현재 패널의 alpha 값)

elapsedTime: 시간이 얼마나 흘렀는지를 계산하는 변수

Mathf.Lerp(a, b, t): a에서 b로 t만큼 선형 보간(lerp)하는 함수

elapsedTime / duration: 시간이 지나면서 0에서 1로 증가함

결과적으로 alpha 값이 startAlpha에서 0까지 서서히 변함

yield return null 덕분에 다음 프레임까지 기다리면서 alpha 값을 조절한다. 이게 바로 서서히 사라지는 효과의 핵심이다.

5. 패널 비활성화 및 HUD 패널 활성화

canvasGroup.alpha = 0f;
panel.SetActive(false);

hudPanel.SetActive(true);

반복문이 끝나면 alpha 값을 0으로 설정해 패널을 완전히 투명하게 만든다.

SetActive(false)로 패널 자체를 비활성화한다.

이후 HUD 패널을 활성화해 게임 UI를 표시한다.

6. 콜백(onComplete) 실행

onComplete?.Invoke();

?.는 onComplete가 null이 아닐 때만 호출하는 연산자다.

이 부분이 중요한 이유는 특정 패널이 사라진 후 추가 동작(예: 사운드 재생, 텍스트 변경 등)을 쉽게 붙일 수 있기 때문이다.

예시:

StartCoroutine(FadeOutPanel(enemyPanel, 2f, () => Debug.Log("패널이 사라졌습니다.")));

7. 전체 흐름 요약

IEnumerator FadeOutPanel(GameObject panel, float duration, System.Action onComplete = null)
{
    CanvasGroup canvasGroup = panel.GetComponent<CanvasGroup>();
    if (canvasGroup == null)
    {
        canvasGroup = panel.AddComponent<CanvasGroup>();
    }

    float startAlpha = canvasGroup.alpha;
    float elapsedTime = 0f;

    while (elapsedTime < duration)
    {
        elapsedTime += Time.deltaTime;
        canvasGroup.alpha = Mathf.Lerp(startAlpha, 0f, elapsedTime / duration);
        yield return null;
    }

    canvasGroup.alpha = 0f;
    panel.SetActive(false);

    // HUD 패널 활성화
    hudPanel.SetActive(true);

    // 완료 콜백 실행
    
onComplete?.Invoke();
}

CanvasGroup을 확인하고 없으면 추가한다.

시간이 지나면서 패널의 alpha 값을 서서히 0으로 줄인다.

완전히 투명해지면 패널을 비활성화하고 HUD 패널을 활성화한다.

추가 작업이 필요한 경우 onComplete 콜백을 실행한다.

8. 추가로 개선할 수 있는 점

페이드 인/아웃 모두 구현

IEnumerator FadePanel(GameObject panel, float duration, bool fadeIn)
{
    CanvasGroup canvasGroup = panel.GetComponent<CanvasGroup>() ?? panel.AddComponent<CanvasGroup>();
    float startAlpha = fadeIn ? 0f : canvasGroup.alpha;
    float targetAlpha = fadeIn ? 1f : 0f;

    float elapsedTime = 0f;
    while (elapsedTime < duration)
    {
        elapsedTime += Time.deltaTime;
        canvasGroup.alpha = Mathf.Lerp(startAlpha, targetAlpha, elapsedTime / duration);
        yield return null;
    }

    canvasGroup.alpha = targetAlpha;
    panel.SetActive(fadeIn);
}

fadeIn 값을 true로 설정하면 패널이 서서히 나타나고, false면 서서히 사라진다.

UI 클릭 방지 기능 추가

canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;

패널이 사라질 때 클릭을 막고 싶다면 위 코드를 추가한다.

9. 결론

Unity에서 UI를 서서히 사라지게 만들고 HUD 패널을 활성화하는 코루틴을 작성했다. 단순한 기능 같지만, 이를 직접 구현해보면서 CanvasGroup의 역할과 Lerp의 사용법, 코루틴의 흐름을 더 깊이 이해할 수 있었다. 앞으로 다른 UI 전환 효과에도 응용할 수 있을 것 같다.

profile
게임개발자꿈나무

0개의 댓글