728x90
반응형
- 개요
https://www.youtube.com/watch?v=GdjP5pggaHw&list=PLX2vGYjWbI0RpLvO3B7aH-ObfcOifMD20&index=4
유니티의 UI ToolKit은 언리얼 엔진의 Rich Text와 유사하게
HTML의 태그와 같은 마크업을 사용하여 UI를 구성할 수 있도록 지원한다
UI Toolkit의 핵심 요소인 UIDocument를 통해 조작할 수 있으며
UIDocument에서 기본 빌딩 블록인 VisualElement를 가져와 태그를 설정할 수 있다

UI의 구성은 위와 같다
프로젝트의 기본 구성은 다음과 같이 이루어져 있다
- 하나의 UI 그룹에서는 WASD를 통해 이동 + UI를 클릭하면 이벤트 함수 호출
- 왼쪽 UI 그룹을 활성화하기 위해서는 Q 키를 입력 + 오른쪽 UI 그룹을 활성화하기 위해서는 E 키를 입력
- UIScript 스크립트의 구성
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.InputSystem;
public class UIScript : MonoBehaviour
{
// Action Map에 따른 Input Action들을 저장한 Input Action Asset
public InputActionAsset InputActions;
// 왼쪽 UI 그룹에 속해있는 버튼 UI
Button m_swordButton;
Button m_axeButton;
Button m_magicButton;
Button m_stealthButton;
// 오른쪽 UI 그룹에 속해있는 버튼 UI
Button m_earthButton;
Button m_monsterButton;
Button m_healButton;
Button m_rageButton;
// 각 UI 그룹의 UI들을 저장할 배열
Button[] m_buttonSet1 = new Button[4];
Button[] m_buttonSet2 = new Button[4];
private void Awake()
{
// UIDocument - VisualElement에 접근하여 마크업 태그를 통한 조작
VisualElement root = GetComponent<UIDocument>().rootVisualElement;
// 왼쪽 UI 그룹에서 Button에 해당하는 UI들을 가져오고 배열에 저장
m_swordButton = root.Q<Button>("sword-icon__button");
m_axeButton = root.Q<Button>("axe-icon__button");
m_magicButton = root.Q<Button>("magic-icon__button");
m_stealthButton = root.Q<Button>("stealth-icon__button");
m_buttonSet1[0] = m_swordButton;
m_buttonSet1[1] = m_axeButton;
m_buttonSet1[2] = m_magicButton;
m_buttonSet1[3] = m_stealthButton;
// 오른쪽 UI 그룹에서 Button에 해당하는 UI들을 가져오고 배열에 저장
m_earthButton = root.Q<Button>("earth-icon__button");
m_monsterButton = root.Q<Button>("monster-icon__button");
m_healButton = root.Q<Button>("heal-icon__button");
m_rageButton = root.Q<Button>("rage-icon__button");
m_buttonSet2[0] = m_earthButton;
m_buttonSet2[1] = m_monsterButton;
m_buttonSet2[2] = m_healButton;
m_buttonSet2[3] = m_rageButton;
}
private void OnEnable()
{
ButtonActionSubscribe();
ButtonSelection();
InputActions.FindActionMap("UI").Enable();
InputSwitch();
}
private void OnDisable()
{
ButtonActionUnsubscribe();
InputActions.FindActionMap("UI").Disable();
InputSwitchDisable();
}
// 각 UI 그룹의 버튼 UI들의 clicked 이벤트에 콜백 함수들을 연결
void ButtonActionSubscribe()
{
m_swordButton.clicked += onSwordButtonClicked;
m_axeButton.clicked += onAxeButtonClicked;
m_magicButton.clicked += onMagicButtonClicked;
m_stealthButton.clicked += onStealthButtonClicked;
m_earthButton.clicked += onEarthButtonClicked;
m_monsterButton.clicked += on_MonsterButtonClicked;
m_healButton.clicked += onHealButtonClicked;
m_rageButton.clicked += onRageButtonClicked;
}
// 각 UI 그룹의 버튼 UI들의 clicked 이벤트에 연결된 콜백 함수들을 제거
void ButtonActionUnsubscribe()
{
m_swordButton.clicked -= onSwordButtonClicked;
m_axeButton.clicked -= onAxeButtonClicked;
m_magicButton.clicked -= onMagicButtonClicked;
m_stealthButton.clicked -= onStealthButtonClicked;
m_earthButton.clicked -= onEarthButtonClicked;
m_monsterButton.clicked -= on_MonsterButtonClicked;
m_healButton.clicked -= onHealButtonClicked;
m_rageButton.clicked -= onRageButtonClicked;
}
// 콜백함수들의 구성
void onSwordButtonClicked() => InventoryButtonClicked("Sword");
void onAxeButtonClicked() => InventoryButtonClicked("Axe");
void onMagicButtonClicked() => InventoryButtonClicked("Magic");
void onStealthButtonClicked() => InventoryButtonClicked("Stealth");
void onEarthButtonClicked() => InventoryButtonClicked("Earth");
void on_MonsterButtonClicked() => InventoryButtonClicked("Monster");
void onHealButtonClicked() => InventoryButtonClicked("Heatlh");
void onRageButtonClicked() => InventoryButtonClicked("Rage");
// 인자로 전달받은 message + clicked !!!의 문자열을 출력
void InventoryButtonClicked(string message)
{
Debug.Log(message + " clicked !!!");
}
// OnEnable 함수에서 최초로 한번 호출되며, 기본적으로 왼쪽 UI 그룹을 활성화하고 첫 번째 인덱스의 버튼을 선택
void ButtonSelection()
{
for (int i = 0; i < m_buttonSet2.Length; i++)
{
m_buttonSet2[i].SetEnabled(false);
// m_ButtonSet2[i].style.display = DisplayStyle.None;
}
m_buttonSet1[0].Focus();
}
// UI 액션 맵의 RightButtons 액션과 LeftButtons 액션의 performed 이벤트에 콜백 함수들을 연결
void InputSwitch()
{
InputActions.FindAction("UI/ShowRightButtons").performed += RightButtons;
InputActions.FindAction("UI/ShowLeftButtons").performed += LeftButtons;
}
// UI 액션 맵의 RightButtons 액션과 LeftButtons 액션의 performed 이벤트에 연결된 콜백 함수들을 제거
void InputSwitchDisable()
{
InputActions.FindAction("UI/ShowRightButtons").performed -= RightButtons;
InputActions.FindAction("UI/ShowLeftButtons").performed -= LeftButtons;
}
// InputAction.CallbackContext : InputAction의 상태가 변경될 때 발생하는 이벤트에 대한 모든 정보를 담고 있는 구조체
// 현재 performed 이벤트에 콜백함수를 바인드하였으므로 입력 이벤트 단계를 확인하기 위해 해당 인자 사용
// 왼쪽 UI 그룹을 활성화하는 함수
void LeftButtons(InputAction.CallbackContext context)
{
for (int i = 0; i < m_buttonSet1.Length; i++)
{
m_buttonSet1[i].SetEnabled(true);
// m_ButtonSet1[i].style.display = DisplayStyle.Flex;
}
for (int i = 0; i < m_buttonSet2.Length; i++)
{
m_buttonSet2[i].SetEnabled(false);
// m_ButtonSet2[i].style.display = DisplayStyle.None;
}
m_buttonSet1[0].Focus();
}
// 오른쪽 UI 그룹을 활성화하는 함수
void RightButtons(InputAction.CallbackContext context)
{
for (int i = 0; i < m_buttonSet1.Length; i++)
{
m_buttonSet1[i].SetEnabled(false);
// m_ButtonSet1[i].style.display = DisplayStyle.None;
}
for (int i = 0; i < m_buttonSet2.Length; i++)
{
m_buttonSet2[i].SetEnabled(true);
// m_ButtonSet2[i].style.display = DisplayStyle.Flex;
}
m_buttonSet2[0].Focus();
}
}
코드의 구성은 위와 같다
중요하게 알아볼 점은 다음과 같다
- UIToolKit을 사용하여 구성한 UI에서는 UIDocument - VisualElement를 통해 접근하여 조작
- Input Action의 입력 단계에 따라 콜백 함수를 다르게 호출해야 하는 경우
- 콜백 함수의 인자로 InputAction.CallbackContext 사용
- 최종 실행 결과
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
728x90
반응형
'유니티 엔진 > 입력 처리 심화' 카테고리의 다른 글
| 유니티 6에서의 입력 처리 - (6) Player Input Component (0) | 2025.11.25 |
|---|---|
| 유니티 6에서의 입력 처리 - (5) 입력키 재할당 (0) | 2025.11.19 |
| 유니티 6에서의 입력 처리 - (3) 모바일에서의 Input System 사용 (0) | 2025.11.16 |
| 유니티 6에서의 입력 처리 - (2) Input System 스크립팅 (0) | 2025.11.11 |
| 유니티 6에서의 입력 처리 - (1) Input Actions Editor의 구성요소 (0) | 2025.11.09 |