UI 배경 Dim 처리

2024. 3. 25. 15:48·유니티

1. UI Dim 처리란 무엇이며 왜 사용하는가?

  • 정의: UI Dim 처리는 현재 활성화되어 사용자의 상호작용이 필요한 최상위 UI 요소(팝업 창, 메뉴, 대화 상자 등) 뒤에, 화면 전체 또는 일부를 덮는 반투명한 어두운 배경 레이어를 추가하는 시각적 디자인 기법입니다.
  • 사용 목적:
    1. 시각적 집중 유도: 배경을 어둡게 처리함으로써 사용자의 시선이 자연스럽게 전면에 활성화된 UI 요소로 향하도록 유도합니다. 중요한 알림이나 필수적인 상호작용에 대한 주목도를 높입니다.
    2. 모달(Modal) 상태 명시: Dim된 배경은 현재 표시된 창이 '모달' 상태임을 시각적으로 나타냅니다. 즉, 사용자는 이 창과 상호작용을 완료하거나 닫기 전까지는 배경의 다른 요소들과 상호작용할 수 없다는 것을 암시합니다.
    3. 배경 상호작용 차단: Dim 처리된 배경 레이어가 마우스 클릭이나 터치와 같은 입력을 가로채어, 뒤쪽에 있는 버튼이나 다른 상호작용 요소들이 실수로 클릭되는 것을 방지합니다.

2. 구현 방법 1: 반투명 이미지(Image) 사용

가장 간단하고 직관적인 방법입니다.

  • 구현 방법:
    1. UI Canvas 내에 새로운 UI > Image 게임 오브젝트를 생성합니다.
    2. Hierarchy 창에서 이 Image 게임 오브젝트를 팝업/메뉴 UI 요소들의 바로 아래 (즉, 시각적으로 뒤에 그려지도록) 배치합니다.
    3. Inspector 창에서 Rect Transform 컴포넌트의 Anchor Presets를 Stretch-Stretch(가로 세로 모두 늘리기)로 설정하고 Left, Top, Right, Bottom 값을 모두 0으로 설정하여 화면 전체를 덮도록 만듭니다.
    4. Image 컴포넌트 설정을 조정합니다.
      • Source Image: 필수는 아닙니다. None으로 두거나, 기본 UISprite 또는 직접 만든 단색(주로 검정 또는 회색) 1x1 픽셀 Sprite를 할당할 수 있습니다.
      • Color: 원하는 Dim 색상(주로 검정 또는 회색 계열)을 선택하고, Alpha(A) 값을 조절하여 반투명도를 설정합니다. (예: RGBA(0, 0, 0, 150) - 약 60% 투명도의 검정색)
      • Raycast Target: 반드시 체크하여 true로 설정합니다. 이것이 배경 입력을 차단하는 핵심 설정입니다.
    5. 팝업/메뉴가 활성화될 때 이 Dim Image 게임 오브젝트도 함께 활성화(SetActive(true))하고, 팝업이 닫힐 때 비활성화(SetActive(false))합니다.
  • 장점: 구현이 매우 직관적이고 쉽습니다.
  • 단점: 팝업 UI와 Dim 배경의 애니메이션(예: 페이드 인/아웃)을 동기화하거나 그룹 단위로 제어하기가 다소 번거로울 수 있습니다.

3. 구현 방법 2: Canvas Group 활용

팝업/메뉴와 Dim 배경을 하나의 그룹으로 묶어 제어하는 더 유연한 방법입니다.

  • 구현 방법:
    1. 빈 GameObject를 생성하여 팝업/메뉴 그룹의 루트(Root)로 사용합니다 (예: PopupWindowGroup).
    2. 이 그룹 GameObject 아래에 위 2번 방법에서 설명한 Dim 배경 Image 게임 오브젝트를 자식으로 생성하고 설정합니다 (Raycast Target 포함).
    3. 마찬가지로 그룹 GameObject 아래에 실제 팝업/메뉴 콘텐츠를 담는 다른 UI 요소들(패널, 텍스트, 버튼 등)을 Dim 배경보다 Hierarchy 상 위에 (즉, 앞쪽에 그려지도록) 배치합니다.
    4. 루트 그룹 GameObject (PopupWindowGroup) 에 Canvas Group 컴포넌트를 추가합니다.
    5. Canvas Group 컴포넌트의 속성을 활용하여 그룹 전체를 제어합니다.
      • Alpha: 이 값을 0 (완전 투명)에서 1 (완전 불투명) 사이로 조절하면, 그룹 내의 모든 UI 요소(Dim 배경 포함)의 투명도가 한꺼번에 조절됩니다. 페이드 인/아웃 효과 구현에 매우 편리합니다.
      • Interactable: false로 설정하면 그룹 내 모든 UI 요소와의 상호작용(버튼 클릭 등)이 막힙니다. 팝업이 비활성 상태일 때 사용될 수 있습니다.
      • Blocks Raycasts: true로 설정하면 이 그룹 전체가 마우스/터치 Raycast를 차단합니다. Dim 배경의 Raycast Target 설정과 함께 사용되어 배경 입력 차단을 확실히 하거나, 그룹 전체의 입력 차단 상태를 제어하는 데 사용될 수 있습니다.
    6. 팝업/메뉴를 열고 닫을 때, 이 루트 그룹 GameObject의 활성 상태(SetActive)를 제어하거나, 또는 GameObject는 계속 활성 상태로 두고 Canvas Group의 Alpha, Interactable, Blocks Raycasts 속성들을 조절하여 표시 여부와 동작을 제어합니다 (애니메이션에 더 유리).
  • 장점: 팝업과 Dim 배경을 하나의 단위로 묶어 알파값(투명도), 상호작용 여부 등을 통합적으로 제어하기 매우 편리합니다. 특히 페이드 인/아웃과 같은 트랜지션 효과 구현에 유리합니다.
  • 단점: 단순 Image 방식보다 초기 구조 설정이 약간 더 복잡합니다.

4. 입력 차단 (Blocking Input)

Dim 배경의 중요한 역할 중 하나는 뒤쪽에 있는 UI 요소들이나 게임 월드와의 원치 않는 클릭/터치 상호작용을 막는 것입니다.

  • 핵심: 화면을 덮는 Dim 배경 UI 요소가 Raycast Target으로 설정되어 있어야 합니다.
  • Image 컴포넌트: Raycast Target 속성을 true로 설정하는 것이 가장 중요합니다. 이 Image가 Raycast를 '흡수'하여 뒤쪽으로 이벤트가 전달되는 것을 막습니다. Image의 색상 알파값이 0이 되어 완전히 투명해 보이더라도, Raycast Target이 켜져 있으면 여전히 입력을 차단합니다 (단, 사용자에게 혼란을 줄 수 있으므로 알파값 0일 때는 Raycast Target도 꺼주는 것이 좋을 수 있습니다).
  • Canvas Group 컴포넌트: Blocks Raycasts 속성을 true로 설정하면 해당 Canvas Group 영역 전체(자식 요소 포함)가 Raycast를 차단합니다. Dim 배경 이미지의 Raycast Target과 함께 사용하면 더 확실한 차단이 가능하며, 그룹 전체의 Raycast 차단 여부를 동적으로 제어할 때 유용합니다.

5. 코드 예시 및 설정

(a) Image 방식 설정 예시:

- Canvas
  └─ MyPopupPanel (GameObject, 비활성 상태로 시작)
     │  └─ (Popup Content: Text, Buttons, etc.)
     └─ DimBackgroundImage (Image Component, 비활성 상태로 시작)
        ├─ RectTransform: Anchor=Stretch-Stretch, Left/Top/Right/Bottom=0
        ├─ Image: Color=RGBA(0,0,0,150), Raycast Target=True
        └─ (Optional) Button: Interaction 없음, Dim 영역 클릭 시 팝업 닫기 용도

(b) Canvas Group 방식 설정 예시:

- Canvas
  └─ PopupWindowGroup (GameObject + Canvas Group Component, 비활성 또는 Alpha=0으로 시작)
     ├─ Canvas Group: Alpha=0, Interactable=False, Blocks Raycasts=False (초기 상태)
     ├─ DimBackgroundImage (Image Component)
     │  ├─ RectTransform: Anchor=Stretch-Stretch, L/T/R/B=0
     │  └─ Image: Color=RGBA(0,0,0,150), Raycast Target=True
     └─ PopupPanelContent (GameObject - Popup UI 요소들의 부모)
        └─ (Text, Buttons, etc.)

(c) 간단 활성화/비활성화 스크립트 (Canvas Group 방식 예시):

using UnityEngine;
using UnityEngine.UI; // CanvasGroup 사용 위해 필요

public class PopupManager : MonoBehaviour
{
    // Inspector에서 루트 그룹 GameObject 또는 CanvasGroup 할당
    public CanvasGroup popupCanvasGroup;
    public float fadeDuration = 0.3f; // 페이드 효과 시간

    private Coroutine _fadeCoroutine;

    void Start()
    {
        // 시작 시 숨김 상태 확인
        if (popupCanvasGroup != null && popupCanvasGroup.alpha == 1f)
        {
             ClosePopupImmediate(); // 즉시 닫기
        }
    }

    public void OpenPopup()
    {
        if (popupCanvasGroup == null) return;
        if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
        _fadeCoroutine = StartCoroutine(FadeCanvasGroup(popupCanvasGroup, 0f, 1f, fadeDuration, true));
    }

    public void ClosePopup()
    {
        if (popupCanvasGroup == null) return;
        if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
        _fadeCoroutine = StartCoroutine(FadeCanvasGroup(popupCanvasGroup, popupCanvasGroup.alpha, 0f, fadeDuration, false));
    }

    // 즉시 닫기 (애니메이션 없이)
    public void ClosePopupImmediate()
    {
         if (popupCanvasGroup != null)
         {
             popupCanvasGroup.alpha = 0f;
             popupCanvasGroup.interactable = false;
             popupCanvasGroup.blocksRaycasts = false;
         }
    }

    // Canvas Group 알파 페이드 코루틴
    private IEnumerator FadeCanvasGroup(CanvasGroup cg, float startAlpha, float endAlpha, float duration, bool isOpening)
    {
        // 열릴 때는 즉시 상호작용 가능하게 설정
        if (isOpening)
        {
            cg.interactable = true;
            cg.blocksRaycasts = true;
        }

        float timer = 0f;
        while (timer < duration)
        {
            timer += Time.unscaledDeltaTime; // Time.timeScale 영향 안 받도록
            cg.alpha = Mathf.Lerp(startAlpha, endAlpha, timer / duration);
            yield return null;
        }
        cg.alpha = endAlpha; // 최종 값 보정

        // 닫힐 때는 최종적으로 상호작용 불가하게 설정
        if (!isOpening)
        {
            cg.interactable = false;
            cg.blocksRaycasts = false;
        }
        _fadeCoroutine = null; // 코루틴 완료
    }

    // 테스트용 Update
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.O)) OpenPopup();
        if (Input.GetKeyDown(KeyCode.C)) ClosePopup();
    }
}

6. 고려사항 및 모범 사례

  • 레이어 및 정렬 순서: Dim 배경은 반드시 팝업 내용보다는 뒤에, 그리고 가려야 할 다른 UI 요소들보다는 앞에 렌더링되어야 합니다. Canvas 내 Hierarchy 순서나 Canvas 컴포넌트의 Sort Order, 또는 Graphic Raycaster 관련 설정을 통해 이를 조절합니다.
  • 성능 (Overdraw): 화면 전체를 덮는 반투명 이미지는 필연적으로 오버드로(Overdraw: 같은 픽셀을 여러 번 덧그리는 현상)를 유발합니다. 대부분의 현대 기기에서는 큰 문제가 되지 않지만, 극도로 최적화가 필요한 모바일 환경에서는 Dim 영역을 최소화하거나, 매우 낮은 알파값을 사용하거나, 필요 없는 경우 빠르게 비활성화하는 것이 좋습니다.
  • 트랜지션 (페이드 효과): Canvas Group의 Alpha 값을 코루틴이나 DoTween, LeanTween 같은 Tweening 라이브러리를 사용하여 점진적으로 변경하면 부드러운 페이드 인/아웃 효과를 쉽게 구현할 수 있습니다. 이는 사용자 경험을 크게 향상시킵니다.
  • 클릭하여 닫기 기능: Dim 배경 영역 자체에 투명한 Button 컴포넌트(Image는 None)를 추가하거나 IPointerClickHandler 인터페이스를 구현한 스크립트를 추가하여, 사용자가 Dim 영역을 클릭했을 때 팝업 창이 닫히도록 구현하는 것이 일반적입니다. 이 경우에도 해당 UI 요소의 Raycast Target은 켜져 있어야 합니다.
  • 재사용성: 여러 팝업에서 동일한 Dim 배경 스타일을 사용한다면, Dim 배경 자체를 프리팹으로 만들거나, 팝업 시스템의 일부로서 공통적으로 관리하는 것이 좋습니다.

7. 결론

UI 배경 Dim 처리는 Unity에서 모달 창(팝업, 메뉴 등)을 구현할 때 사용자 경험과 인터페이스 명확성을 향상시키는 간단하면서도 매우 효과적인 기법입니다. 반투명 Image 컴포넌트를 사용하거나 Canvas Group으로 팝업과 Dim 배경을 함께 관리하는 방식으로 구현할 수 있으며, 핵심은 Raycast Target (또는 Canvas Group의 Blocks Raycasts) 설정을 통해 배경 입력을 적절히 차단하는 것입니다. 특히 Canvas Group 방식은 페이드 인/아웃과 같은 부드러운 전환 효과를 구현하는 데 유리합니다. 레이어 순서, 성능(Overdraw), 클릭하여 닫기 기능 등을 고려하여 프로젝트의 요구사항에 맞게 구현한다면, 사용자가 현재 활성화된 UI에 집중하고 의도치 않은 상호작용을 방지하는 깔끔하고 전문적인 UI를 만들 수 있을 것입니다.


8. 참고 자료

  • Unity 매뉴얼 - 이미지 (Image)
  • Unity 매뉴얼 - 캔버스 그룹 (Canvas Group)
  • Unity 매뉴얼 - 레이캐스트 작동 방식 (How Raycasting Works) (UI Raycasting 관련 내용 포함)

 

'유니티' 카테고리의 다른 글
  • 유니티 라이프사이클
  • UnityEngine 클래스 상속 계층
  • LineRenderer를 활용한 수류탄 궤적 시각화 및 투척 예시
  • 비동기 씬 로드
뇌장하드 주인장
뇌장하드 주인장
  • 뇌장하드 주인장
    뇌장하드
    뇌장하드 주인장
    • 분류 전체보기 (88)
      • C++ (9)
      • C# (15)
      • CS (9)
      • 유니티 (39)
      • 유니팁 (7)
      • 유니티 패턴 (8)
      • - (1)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
뇌장하드 주인장
UI 배경 Dim 처리
상단으로

티스토리툴바