1. UI Dim 처리란 무엇이며 왜 사용하는가?
- 정의: UI Dim 처리는 현재 활성화되어 사용자의 상호작용이 필요한 최상위 UI 요소(팝업 창, 메뉴, 대화 상자 등) 뒤에, 화면 전체 또는 일부를 덮는 반투명한 어두운 배경 레이어를 추가하는 시각적 디자인 기법입니다.
- 사용 목적:
- 시각적 집중 유도: 배경을 어둡게 처리함으로써 사용자의 시선이 자연스럽게 전면에 활성화된 UI 요소로 향하도록 유도합니다. 중요한 알림이나 필수적인 상호작용에 대한 주목도를 높입니다.
- 모달(Modal) 상태 명시: Dim된 배경은 현재 표시된 창이 '모달' 상태임을 시각적으로 나타냅니다. 즉, 사용자는 이 창과 상호작용을 완료하거나 닫기 전까지는 배경의 다른 요소들과 상호작용할 수 없다는 것을 암시합니다.
- 배경 상호작용 차단: Dim 처리된 배경 레이어가 마우스 클릭이나 터치와 같은 입력을 가로채어, 뒤쪽에 있는 버튼이나 다른 상호작용 요소들이 실수로 클릭되는 것을 방지합니다.
2. 구현 방법 1: 반투명 이미지(Image) 사용
가장 간단하고 직관적인 방법입니다.
- 구현 방법:
- UI Canvas 내에 새로운 UI > Image 게임 오브젝트를 생성합니다.
- Hierarchy 창에서 이 Image 게임 오브젝트를 팝업/메뉴 UI 요소들의 바로 아래 (즉, 시각적으로 뒤에 그려지도록) 배치합니다.
- Inspector 창에서 Rect Transform 컴포넌트의 Anchor Presets를 Stretch-Stretch(가로 세로 모두 늘리기)로 설정하고 Left, Top, Right, Bottom 값을 모두 0으로 설정하여 화면 전체를 덮도록 만듭니다.
- Image 컴포넌트 설정을 조정합니다.
- Source Image: 필수는 아닙니다.
None
으로 두거나, 기본UISprite
또는 직접 만든 단색(주로 검정 또는 회색) 1x1 픽셀 Sprite를 할당할 수 있습니다. - Color: 원하는 Dim 색상(주로 검정 또는 회색 계열)을 선택하고, Alpha(A) 값을 조절하여 반투명도를 설정합니다. (예: RGBA(0, 0, 0, 150) - 약 60% 투명도의 검정색)
- Raycast Target: 반드시 체크하여
true
로 설정합니다. 이것이 배경 입력을 차단하는 핵심 설정입니다.
- Source Image: 필수는 아닙니다.
- 팝업/메뉴가 활성화될 때 이 Dim Image 게임 오브젝트도 함께 활성화(
SetActive(true)
)하고, 팝업이 닫힐 때 비활성화(SetActive(false)
)합니다.
- 장점: 구현이 매우 직관적이고 쉽습니다.
- 단점: 팝업 UI와 Dim 배경의 애니메이션(예: 페이드 인/아웃)을 동기화하거나 그룹 단위로 제어하기가 다소 번거로울 수 있습니다.
3. 구현 방법 2: Canvas Group 활용
팝업/메뉴와 Dim 배경을 하나의 그룹으로 묶어 제어하는 더 유연한 방법입니다.
- 구현 방법:
- 빈 GameObject를 생성하여 팝업/메뉴 그룹의 루트(Root)로 사용합니다 (예:
PopupWindowGroup
). - 이 그룹 GameObject 아래에 위 2번 방법에서 설명한 Dim 배경 Image 게임 오브젝트를 자식으로 생성하고 설정합니다 (
Raycast Target
포함). - 마찬가지로 그룹 GameObject 아래에 실제 팝업/메뉴 콘텐츠를 담는 다른 UI 요소들(패널, 텍스트, 버튼 등)을 Dim 배경보다 Hierarchy 상 위에 (즉, 앞쪽에 그려지도록) 배치합니다.
- 루트 그룹 GameObject (
PopupWindowGroup
) 에Canvas Group
컴포넌트를 추가합니다. Canvas Group
컴포넌트의 속성을 활용하여 그룹 전체를 제어합니다.Alpha
: 이 값을 0 (완전 투명)에서 1 (완전 불투명) 사이로 조절하면, 그룹 내의 모든 UI 요소(Dim 배경 포함)의 투명도가 한꺼번에 조절됩니다. 페이드 인/아웃 효과 구현에 매우 편리합니다.Interactable
:false
로 설정하면 그룹 내 모든 UI 요소와의 상호작용(버튼 클릭 등)이 막힙니다. 팝업이 비활성 상태일 때 사용될 수 있습니다.Blocks Raycasts
:true
로 설정하면 이 그룹 전체가 마우스/터치 Raycast를 차단합니다. Dim 배경의Raycast Target
설정과 함께 사용되어 배경 입력 차단을 확실히 하거나, 그룹 전체의 입력 차단 상태를 제어하는 데 사용될 수 있습니다.
- 팝업/메뉴를 열고 닫을 때, 이 루트 그룹 GameObject의 활성 상태(
SetActive
)를 제어하거나, 또는 GameObject는 계속 활성 상태로 두고Canvas Group
의Alpha
,Interactable
,Blocks Raycasts
속성들을 조절하여 표시 여부와 동작을 제어합니다 (애니메이션에 더 유리).
- 빈 GameObject를 생성하여 팝업/메뉴 그룹의 루트(Root)로 사용합니다 (예:
- 장점: 팝업과 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 관련 내용 포함)