핵심 정리
| 항목 | 내용 |
|---|---|
| 역할 | 클릭 가능한 선택 UI와 상태 전이, onClick 이벤트 발행 |
| 언제 쓰는가 | 메뉴, 설정, 인벤토리, 확인/취소, 탭 전환처럼 명시적 입력을 받아야 할 때 |
| 기준 버전 | Unity 6.5 (6000.5) |
| 핵심 Inspector | Interactable, Transition, Navigation, Target Graphic, On Click |
| 자주 연결되는 API | onClick, interactable, Select(), OnPointerClick 관련 이벤트 |
Inspector 설정
| 설정값 | 언제 바꾸는가 | 잘못 맞추면 생기는 문제 |
|---|---|---|
| Interactable | 실제 클릭 가능 여부를 바꿀 때 | 회색인데 눌리거나, 반대로 보이는데 안 눌림 |
| Target Graphic | 상태 전이가 적용될 그래픽을 지정할 때 | 하이라이트가 엉뚱한 자식에만 적용됨 |
| Transition | 색상/스프라이트/애니메이션 전환 방식을 정할 때 | 화려한 전환을 위해 Animator까지 과하게 늘어남 |
| Color Block / Sprite State / Animation | 상태별 시각 표현을 세밀하게 바꿀 때 | 눌림/포커스/비활성 상태 구분이 사라짐 |
| Navigation | 키보드·패드 포커스 이동을 제어할 때 | 자동 탐색이 꼬여 포커스가 튐 |
| On Click | 인스펙터에서 빠르게 함수 연결할 때 | 코드 등록과 혼용해 중복 실행되기 쉬움 |
Interactable, Target Graphic
Interactable은 입력 가능 여부입니다. 비활성화처럼 보이게만 하고 싶을 때도 실제 클릭 차단은 이 값이 맡습니다. Target Graphic은 색상 전이나 스프라이트 전환이 적용될 그래픽을 가리킵니다.
Target Graphic 연결이 틀리면 버튼은 눌리는데 하이라이트가 안 바뀌거나, 반대로 텍스트만 색이 바뀌는 어색한 결과가 나옵니다.
Transition
Color Tint는 가장 흔한 기본값이고, Sprite Swap은 상태별 스프라이트가 준비된 경우, Animation은 전환 연출을 세밀하게 만들고 싶을 때 씁니다. 빠른 UI에서는 Color Tint가 충분하지만, 콘솔식 포커스 강조나 화려한 메뉴는 Animation이 더 명확할 수 있습니다.
Transition을 Animation으로 바꾸면 Animator 상태와 파라미터까지 같이 관리해야 합니다. 버튼 수가 많으면 관리 비용이 빠르게 커집니다.
| 값 | 언제 고르는가 | 주의할 점 |
|---|---|---|
None | 상태 변화가 거의 없는 미니멀 UI, 완전 커스텀 렌더링 | 포커스와 눌림 피드백이 약해질 수 있음 |
Color Tint | 가장 일반적인 메뉴, 설정창, HUD 버튼 | Target Graphic이 잘못 연결되면 아무 반응이 없어 보임 |
Sprite Swap | 상태별 이미지가 확실히 달라야 하는 콘솔 메뉴, 아이콘 버튼 | 상태 스프라이트를 모두 준비해야 하고 해상도 관리가 필요 |
Animation | 선택/눌림/포커스 연출을 Animator로 세밀하게 만들 때 | 버튼 수가 많아지면 Animator 관리 비용과 디버깅 비용이 커짐 |
Navigation, On Click
Navigation은 키보드/패드 포커스 이동입니다. PC 마우스만 보는 프로젝트에서는 체감이 적지만, 게임패드 메뉴나 접근성 고려가 있으면 중요합니다. 자동 탐색이 꼬이면 명시적 네비게이션으로 바꿔야 합니다.
On Click은 인스펙터에서 호출할 함수를 연결하는 곳입니다. 프로토타이핑에는 빠르지만, 대규모 화면에서는 코드 등록과 혼용할 때 중복 호출이 생기기 쉽습니다.
| 값 | 언제 고르는가 | 주의할 점 |
|---|---|---|
Navigation = None | 마우스/터치 전용 UI | 패드나 키보드 포커스 이동이 완전히 막힘 |
Navigation = Horizontal | 탭 바, 좌우 캐러셀, 슬라이더 행 | 세로 이동이 필요한 메뉴에는 답답함 |
Navigation = Vertical | 설정 목록, 일반 메뉴 리스트 | 좌우 보조 버튼이 있으면 이동 흐름이 끊길 수 있음 |
Navigation = Automatic | 간단한 격자/목록에서 빠르게 기본 탐색을 만들 때 | 레이아웃이 복잡하면 예상과 다른 버튼으로 점프함 |
Navigation = Explicit | 게임패드 메뉴, 팝업, 복잡한 포커스 흐름을 직접 고정할 때 | 이웃 버튼 참조를 바꿀 때마다 같이 유지보수해야 함 |
스크립트 연결
| 필드/프로퍼티 | 언제 읽거나 쓰는가 | 주의할 점 |
|---|---|---|
interactable | 조건에 따라 버튼 활성/비활성 전환 | 시각만이 아니라 실제 입력 차단도 함께 담당 |
onClick | 클릭 이벤트 구독 관리 | 인스펙터 연결과 중복 여부 확인 필요 |
| 메서드 | 언제 쓰는가 | 연결 지점 |
|---|---|---|
AddListener() | 코드에서 클릭 이벤트 등록 | Awake, OnEnable |
RemoveListener() | 동적 UI의 중복 등록 방지 | OnDisable, 해제 함수 |
RemoveAllListeners() | 풀링 버튼을 재사용할 때 초기화 | 바인딩 직전 |
Select() | 기본 포커스를 코드로 옮길 때 | 팝업 오픈, 패드 내비게이션 |
버튼은 상태 제어와 이벤트 등록이 핵심입니다.
using UnityEngine;
using UnityEngine.UI;
public class ConfirmDialog : MonoBehaviour
{
[SerializeField] private Button confirmButton;
private void OnEnable()
{
confirmButton.onClick.AddListener(HandleConfirm);
}
private void OnDisable()
{
confirmButton.onClick.RemoveListener(HandleConfirm);
}
private void HandleConfirm()
{
Debug.Log("확인 클릭");
}
}동적 활성화 UI는 OnEnable/OnDisable, 초기화 한 번만 필요한 메뉴는 Awake가 흔한 연결 지점입니다.
자주 틀리는 부분
On Click인스펙터 연결과AddListener를 동시에 써서 한 번 클릭에 두 번 실행되기 쉽습니다.Interactable = false인데도 부모의CanvasGroup이나 블록 레이캐스트 상태를 함께 안 보면 원인을 놓칠 수 있습니다.- Navigation 자동 탐색이 예상과 다르게 잡히면 패드 조작이 꼬입니다.
- 시각 전환만 바꾸고 실제 클릭 차단은 안 해서 "회색인데 눌리는 버튼"이 생길 수 있습니다.
관련 컴포넌트
Canvas, Image, TextMeshPro, Animator, Unity UI Button 이벤트 기본
참고 링크
2 sources