다음을 통해 공유


UI 탐색 컨트롤러

이 페이지에서는 UWP(유니버설 Windows 플랫폼)용 Windows.Gaming.Input.UINavigationController 및 관련 API를 사용하여 UI 탐색 디바이스에 대한 프로그래밍 기본 사항에 대해 설명합니다.

이 페이지를 읽으면 다음을 알게 됩니다.

  • 연결된 UI 탐색 디바이스 및 해당 사용자 목록의 수집 방법
  • 탐색 디바이스가 추가 또는 제거되었음을 감지하는 방법
  • 하나 이상의 UI 탐색 디바이스에서 입력을 읽는 방법
  • 게임 패드와 아케이드 스틱이 내비게이션 장치로 작동하는 방식

UI 탐색 컨트롤러 개요

거의 모든 게임에는 게임 전 메뉴 또는 게임 내 대화 상자가 있더라도 게임 플레이와는 별개인 사용자 인터페이스가 있습니다. 플레이어는 선택한 입력 장치를 사용하여 이 UI를 탐색할 수 있어야 하지만, 개발자는 각 종류의 입력 장치에 대한 특정 지원을 추가해야 하며 게임과 입력 디바이스가 불일치해 플레이어를 혼동하게 할 수 있습니다. 이러한 이유로 UINavigationController API가 생성되었습니다.

UI 탐색 컨트롤러는 다양한 물리적 입력 디바이스에서 지원될 수 있는 일반적인 UI 탐색 명령의 어휘를 제공하기 위해 존재하는 논리적 입력 디바이스입니다. UI 탐색 컨트롤러는 물리적 입력 디바이스를 보는 다른 방법입니다. 탐색 디바이스를 사용하여 탐색 컨트롤러로 표시되는 물리적 입력 디바이스를 참조합니다. 개발자는 특정 입력 디바이스가 아닌 탐색 디바이스에 프로그래밍하여 다른 입력 디바이스를 지원하는 부담을 피하고 기본적으로 일관성을 이루어냅니다.

각 입력 디바이스에서 지원하는 컨트롤의 수와 다양성은 매우 다를 수 있으며 특정 입력 디바이스가 보다 풍부한 탐색 명령 집합을 지원하려고 할 수 있기 때문에 탐색 컨트롤러 인터페이스는 명령의 어휘를 가장 일반적이고 필수적인 명령이 포함된 필수 집합으로 나누고 편리하지만 불필요한 명령을 포함하는 선택적 집합으로 나눕니다. 모든 탐색 디바이스는 필수 집합의 모든 명령을 지원하며 선택적 집합의 모든 명령, 일부 또는 없음 명령을 지원할 수 있습니다.

필수 집합

탐색 디바이스는 필수 집합의 모든 탐색 명령을 지원해야 합니다. 방향(위쪽, 아래쪽, 왼쪽 및 오른쪽), 보기, 메뉴, 수락, 취소 명령입니다.

방향 명령은 단일 UI 요소 간의 기본 XY 포커스 탐색을 위한 것입니다. 보기 및 메뉴 명령은 게임 플레이 정보를 종종 일시적으로, 때로는 모듈식으로 표시하고 게임 플레이와 메뉴 컨텍스트를 각각 전환하기 위한 것입니다. 수락 및 취소 명령은 각각 긍정(예) 및 부정(아니요) 응답을 위한 것입니다.

다음 표에는 이러한 명령과 해당 명령의 용도와 예제가 요약되어 있습니다. | 명령 | 용도 | -------:| --------------- | Up | XY 포커스 위로 탐색 | Down | XY 포커스 아래로 탐색 | Left | XY 포커스 왼쪽으로 탐색 | Right | XY 포커스 오른쪽으로 탐색 | View | 게임 플레이 정보 표시(스코어보드, 게임 통계, 목표, 세계 또는 지역 지도) | Menu | 주 메뉴/일시 중지(설정, 상태, 장비, 인벤토리, 일시 중지) | Accept | 긍정 응답(수락, 정방향, 확인, 시작, 예) | Cancel | 부정 응답(거부, 역방향, 거절, 중지, 아니요)

선택적 집합

탐색 디바이스는 선택적 집합의 모든 탐색 명령, 일부 또는 없음을 지원할 수도 있습니다. 페이징(위쪽, 아래쪽, 왼쪽 및 오른쪽), 스크롤(위쪽, 아래쪽, 왼쪽 및 오른쪽) 및 상황에 맞는 명령(컨텍스트 1-4)입니다.

컨텍스트 명령은 명시적인 애플리케이션별 명령 및 탐색 바로 가기용입니다. 페이징 및 스크롤 명령은 각각 페이지 또는 UI 요소 그룹 간의 빠른 탐색과 UI 요소 내의 세분화된 탐색을 위한 것입니다.

다음 표에는 이러한 명령 및 해당 명령의 용도와 예제가 요약되어 있습니다. | 명령 | 용도 | -----------:| ------------ | PageUp | 위로 이동(위쪽/이전 세로 페이지 또는 그룹으로) | PageDown | 아래로 이동(왼쪽/이전 가로 페이지 또는 그룹으로) | PageLeft | 왼쪽으로 이동(왼쪽/이전 가로 페이지 또는 그룹으로) | PageRight | 오른쪽으로 이동(오른쪽/다음 가로 페이지 또는 그룹으로) | ScrollUp | 위로 스크롤(포커스가 있는 UI 요소 또는 스크롤 가능한 그룹 내에서) | ScrollDown | 아래로 스크롤(포커스가 있는 UI 요소 또는 스크롤 가능한 그룹 내에서) | ScrollLeft | 왼쪽으로 스크롤(포커스가 있는 UI 요소 또는 스크롤 가능한 그룹 내에서) | ScrollRight | 오른쪽으로 스크롤(포커스가 있는 UI 요소 또는 스크롤 가능한 그룹 내에서) | Context1 | 기본 컨텍스트 작업 | Context2 | 두 번째 컨텍스트 작업 | Context3 | 세 번째 컨텍스트 작업 | Context4 | 네 번째 컨텍스트 작업

참고 게임은 용도와 다른 실제 함수가 있는 명령에 자유롭게 반응하지만 예기치 않은 동작은 피해야 합니다. 특히 의도한 대로 사용해야 하는 경우, 명령의 실제 함수를 변경하지 말고, 가장 적합한 명령에 새 함수를 할당하고, PageUp/PageDown과 같은 해당 명령에 대응 함수를 할당합니다. 마지막으로 각 종류의 입력 디바이스에서 지원되는 명령과 매핑되는 컨트롤을 고려하여 모든 디바이스에서 중요한 명령에 액세스할 수 있는지 확인합니다.

게임 패드, 아케이드 스틱, 레이싱 휠 탐색

Windows.Gaming.Input 네임스페이스에서 지원하는 모든 입력 디바이스는 UI 탐색 장치입니다.

다음 표에서는 탐색 명령의 필수 집합이 다양한 입력 디바이스에 매핑되는 방법을 요약합니다.

탐색 명령 게임 패드 입력 아케이드 스틱 입력 레이싱 휠 입력
위로 왼쪽 엄지스틱 위로 / D 패드 위로 스틱 위로 D 패드 위로
아래로 왼쪽 엄지스틱 아래로 / D 패드 아래로 스틱 아래로 D 패드 아래로
Left 왼쪽 엄지스틱 왼쪽으로 /D 패드 왼쪽으로 스틱 왼쪽으로 D 패드 왼쪽으로
Right 왼쪽 엄지스틱 오른쪽으로 / D 패드 오른쪽으로 스틱 오른쪽으로 D 패드 오른쪽으로
보기 보기 버튼 보기 버튼 보기 버튼
메뉴 메뉴 버튼 메뉴 버튼 메뉴 버튼
수락 A button 작업 1 버튼 A button
취소 B 버튼 작업 2 버튼 B 버튼

다음 표에서는 탐색 명령의 선택적 집합이 다양한 입력 디바이스에 매핑되는 방법을 요약합니다.

탐색 명령 게임 패드 입력 아케이드 스틱 입력 레이싱 휠 입력
PageUp 왼쪽 트리거 지원되지 않음 다양함
PageDown 오른쪽 트리거 지원되지 않음 다양함
페이지 왼쪽 왼쪽 범퍼 지원되지 않음 다양함
페이지 오른쪽 오른쪽 범퍼 지원되지 않음 다양함
ScrollUp 오른쪽 엄지스틱 위로 지원되지 않음 다양함
ScrollDown 오른쪽 엄지스틱 아래로 지원되지 않음 다양함
ScrollLeft 오른쪽 엄지스틱 왼쪽으로 지원되지 않음 다양함
ScrollRight 오른쪽 엄지스틱 오른쪽으로 지원되지 않음 다양함
컨텍스트1 X 버튼 지원되지 않음 X 버튼(일반적으로)
컨텍스트2 Y 버튼 지원되지 않음 Y 버튼(일반적으로)
컨텍스트3 왼쪽 엄지 스틱을 누름 지원되지 않음 다양함
컨텍스트4 오른쪽 엄지 스틱 누름 지원되지 않음 다양함

UI 탐색 컨트롤러 검색 및 추적

UI 탐색 컨트롤러는 논리적 입력 디바이스이지만 물리적 디바이스를 나타내며 시스템에서 동일한 방식으로 관리됩니다. 생성하거나 초기화할 필요가 없습니다. 시스템은 연결된 UI 탐색 컨트롤러 및 이벤트 목록을 제공하여 UI 탐색 컨트롤러가 추가되거나 제거될 때 사용자에게 알립니다.

UI 탐색 컨트롤러 목록

UINavigationController 클래스는 현재 연결된 UI 탐색 디바이스의 읽기 전용 목록인 정적 속성인 UINavigationControllers를 제공합니다. 연결된 탐색 장치 중 일부에만 관심이 있을 수 있으므로 UINavigationControllers 속성을 통해 액세스하는 대신 고유한 컬렉션을 유지관리하는 것을 권장합니다.

다음 예제에서는 연결된 모든 UI 탐색 컨트롤러를 새 컬렉션에 복사합니다.

auto myNavigationControllers = ref new Vector<UINavigationController^>();

for (auto device : UINavigationController::UINavigationControllers)
{
    // This code assumes that you're interested in all navigation controllers.
    myNavigationControllers->Append(device);
}

UI 탐색 컨트롤러 추가 및 제거

UI 탐색 컨트롤러가 추가되거나 제거되면 UINavigationControllerAddedUINavigationControllerRemoved 이벤트가 발생합니다. 이러한 이벤트에 대한 이벤트 처리기를 등록하여 현재 연결된 탐색 디바이스를 추적할 수 있습니다.

다음 예제에서는 추가된 UI 탐색 디바이스의 추적을 시작합니다.

UINavigationController::UINavigationControllerAdded += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
    // This code assumes that you're interested in all new navigation controllers.
    myNavigationControllers->Append(args);
}

다음 예제에서는 제거된 아케이드 스틱의 추적을 중단합니다.

UINavigationController::UINavigationControllerRemoved += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
    unsigned int indexRemoved;

    if(myNavigationControllers->IndexOf(args, &indexRemoved))
	{
        myNavigationControllers->RemoveAt(indexRemoved);
    }
}

사용자 및 헤드셋

각 탐색 디바이스를 사용자 계정과 연결하여 ID를 입력에 연결할 수 있으며, 음성 채팅 또는 탐색 기능을 용이하게 하기 위해 헤드셋을 연결할 수 있습니다. 사용자 및 헤드셋 작업에 대한 자세한 내용은 사용자 및 장치 추적헤드셋을 참조하세요.

UI 탐색 컨트롤러 읽기

관심 있는 UI 탐색 장치를 식별한 후에는 해당 장치에서 입력을 수집할 준비가 된 것입니다. 그러나 익숙한 다른 종류의 입력과 달리 탐색 디바이스는 이벤트를 발생시켜 상태 변경을 전달하지 않습니다. 대신, 플라이트 스틱을 직접 폴링하여 현재 상태의 규칙적인 판독값을 가져올 수 있습니다.

UI 탐색 컨트롤러 폴링

폴링은 정확한 시점에 내비게이션 장치의 스냅샷을 캡처합니다. 이러한 입력 수집 방법은 대부분의 게임에 적합합니다. 게임의 논리는 일반적으로 이벤트 기반 방식이 아닌 결정적 루프로 실행되기 때문입니다. 또한 시간을 두고 수집된 여러 단일 입력보다 한 번에 수집된 입력에서 게임 명령을 해석하는 것이 일반적으로 더 간단합니다.

UINavigationController.GetCurrentReading을 호출하여 탐색 디바이스를 폴링합니다. 이 함수는 탐색 디바이스의 상태가 포함된 UINavigationReading을 반환합니다.

auto navigationController = myNavigationControllers[0];

UINavigationReading reading = navigationController->GetCurrentReading();

버튼 읽기

각 UI 탐색 버튼은 누름(아래쪽) 또는 놓음(위쪽) 여부에 해당하는 부울 판독값을 제공합니다. 효율성을 위해 버튼 판독값은 개별 부울 값으로 표시되지 않습니다. 대신 모두 RequiredUINavigationButtonsOptionalUINavigationButtons 열거형으로 표시되는 두 비트 필드 중 하나로 압축됩니다.

필수 집합에 속하는 버튼은 UINavigationReading 구조체의 RequiredButtons 속성에서 읽습니다. 선택적 집합에 속하는 버튼은 OptionalButtons 속성에서 읽습니다. 이 속성들은 비트 필드이기 때문에 비트 마스킹은 관심 있는 버튼의 값을 격리하는 데 사용됩니다. 해당 비트가 설정된 경우에는 버튼이 눌리고(아래), 그러지 않은 경우에는 놓입니다(위).

다음 예제에서는 필수 집합의 수락 버튼을 눌렀는지 여부를 확인합니다.

if (RequiredUINavigationButtons::Accept == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
    // Accept is pressed
}

다음 예제에서는 필수 집합의 수락 버튼을 놓았는지 여부를 확인합니다.

if (RequiredUINavigationButtons::None == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
    // Accept is released (not pressed)
}

선택적 집합에서 버튼을 읽을 때 OptionalButtons 속성 및 OptionalUINavigationButtons 열거형을 사용해야 합니다.

다음 예제에서는 선택적 집합의 컨텍스트1 버튼을 눌렀는지 여부를 확인합니다.

if (OptionalUINavigationButtons::Context1 == (reading.OptionalButtons & OptionalUINavigationButtons::Context1))
{
    // Context 1 is pressed
}

버튼이 눌렸다가 놓이거나, 반대로 놓였다가 눌렸을 때 여러 개의 버튼이 눌렸거나 놓였는지 또는 일련의 버튼이 특정 방식으로 정렬되었는지(일부는 눌리고 일부는 놓임) 확인해야 하는 경우가 있습니다. 이러한 조건을 검색하는 방법에 대한 자세한 내용은 버튼 전환 감지복잡한 버튼 정렬 검색을 참조하세요.

UI 탐색 컨트롤러 샘플 실행

InputInterfacingUWP 샘플(github)은 다양한 입력 디바이스가 UI 탐색 컨트롤러로 작동하는 방식을 보여 줍니다.

참고 항목

Windows.Gaming.Input.GamepadWindows.Gaming.Input.ArcadeStickWindows.Gaming.Input.RacingWheelWindows.Gaming.Input.IGameController