유니티에서 UI를 개발할 때 여러 개의 입력 필드(InputField 또는 TMP_InputField)를 사용하는 경우, 사용자가 Tab 키를 눌러 필드 간 탐색할 수 있는 기능이 필요할 때가 있습니다.
- Tab 키로 다음 입력 필드로 이동
- Shift + Tab 키로 이전 입력 필드로 이동
- 순환 탐색(Circular Navigation) 지원 여부 설정 가능
- 입력 필드의 interactable 상태 확인 후 이동
using UnityEngine;
using UnityEngine.EventSystems;
using TMPro;
public class InputFieldTabNavigation : MonoBehaviour
{
[SerializeField]
private bool enableCircularNavigation = true; // 순환 탐색 허용 여부
private TMP_InputField[] _inputFields;
private int _currentIndex = -1; // 현재 선택된 입력 필드의 인덱스
private void Awake()
{
// 시작 시 모든 입력 필드를 캐시
_inputFields = GetComponentsInChildren<TMP_InputField>();
}
private void Update()
{
if (!Input.GetKeyDown(KeyCode.Tab)) return;
HandleTabNavigation();
}
private void HandleTabNavigation()
{
GameObject currentObject = EventSystem.current.currentSelectedGameObject;
if (ReferenceEquals(currentObject, null)) return;
currentObject.TryGetComponent(out TMP_InputField currentInputField);
if (ReferenceEquals(currentInputField, null)) return;
// 현재 인덱스 찾기
_currentIndex = System.Array.IndexOf(_inputFields, currentInputField);
if (_currentIndex == -1) return;
// 다음 인덱스 계산
int nextIndex = CalculateNextIndex();
// 다음 입력 필드로 이동
SelectInputField(nextIndex);
}
private int CalculateNextIndex()
{
bool isShiftPressed = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
int direction = isShiftPressed ? -1 : 1;
int nextIndex = _currentIndex + direction;
if (enableCircularNavigation)
{
// 순환 탐색 처리
if (nextIndex >= _inputFields.Length)
{
nextIndex = 0;
}
else if (nextIndex < 0)
{
nextIndex = _inputFields.Length - 1;
}
}
else
{
// 범위 제한
nextIndex = Mathf.Clamp(nextIndex, 0, _inputFields.Length - 1);
}
return nextIndex;
}
private void SelectInputField(int index)
{
if (index < 0 || index >= _inputFields.Length) return;
var nextInputField = _inputFields[index];
if (!ReferenceEquals(nextInputField, null) && nextInputField.interactable)
{
nextInputField.Select();
nextInputField.ActivateInputField();
// 텍스트 전체 선택 (선택적 기능)
nextInputField.SetTextWithoutNotify(nextInputField.text);
}
}
// 시작할 때, 자동으로 첫 번째 필드 선택
private void SelectFirstInputField()
{
if (_inputFields != null && _inputFields.Length > 0)
{
SelectInputField(0);
}
}
}
- Update() 메서드에서 Tab 키 입력을 감지하고, 입력 필드의 현재 위치를 기준으로 탐색 방향을 계산합니다. Shift 키가 눌린 경우 역방향 탐색(-1), 그렇지 않으면 순방향 탐색(+1)을 수행합니다.
- enableCircularNavigation 플래그를 통해 순환 탐색 여부를 제어합니다. 순환 탐색이 활성화된 경우, 끝에서 다시 처음으로 돌아가거나 반대로 작동합니다.