포인터

포인터

이 문서에서는 포인터 아키텍처 와 비교 하 여 실제로 포인터 입력을 구성 하 고 응답 하는 방법을 설명 합니다.

새 컨트롤러를 검색 하면 런타임에 포인터가 자동으로 인스턴스 됩니다. 하나 이상의 포인터를 컨트롤러에 연결할 수 있습니다. 예를 들어 기본 포인터 프로필을 사용 하는 경우 Windows Mixed Reality 컨트롤러는 각각 일반 선택 및 teleportation에 대 한 줄과 포물선 포인터를 모두 가져옵니다.

포인터 구성

포인터는를 통해 MRTK의 입력 시스템의 일부로 구성 됩니다 MixedRealityPointerProfile . 이 유형의 프로필은 MixedRealityInputSystemProfile MRTK 구성 검사기에서에 할당 됩니다. 포인터 프로필은 커서, 런타임에 사용할 수 있는 포인터의 형식 및 해당 포인터가 서로 통신 하 여 활성화 된 항목을 결정 하는 방법을 결정 합니다.

  • 방향 범위 -포인터가 GameObject와 상호 작용할 수 있는 최대 거리를 정의 합니다.

  • Raycast 계층 마스크 가리키기 -지정 된 포인터가 상호 작용할 수 있는 가능한 gameobject와 상호 작용 하는 순서를 결정 하는 LayerMasks의 우선 순위가 지정 된 배열입니다. 이는 포인터가 다른 장면 개체 보다 먼저 UI 요소와 상호 작용 하는지 확인 하는 데 유용할 수 있습니다. 포인터 프로필 예

포인터 옵션 구성

기본 MRTK 포인터 프로필 구성에는 다음 포인터 클래스 및 연결 된 prefabs이 포함 되어 있습니다. 런타임에 시스템에서 사용할 수 있는 포인터 목록은 포인터 프로필의 포인터 옵션 에 정의 되어 있습니다. 개발자는이 목록을 사용 하 여 기존 포인터를 다시 구성 하거나 새 포인터를 추가 하거나 삭제할 수 있습니다.

포인터 옵션 프로필 예

각 포인터 항목은 다음 데이터 집합에 의해 정의 됩니다.

  • 컨트롤러 유형 -포인터가 유효한 컨트롤러 집합입니다.

    • 예를 들어 Pokepointer 는 손가락을 사용 하는 "poking" 개체를 담당 하며, 기본적으로는 트레일러 컨트롤러 유형만 지원 하도록 표시 됩니다. 포인터는 컨트롤러를 사용할 수 있게 되는 경우에만 인스턴스화되고 특히, 컨트롤러 유형 에서는이 포인터 prefab를 사용 하 여 만들 수 있는 컨트롤러를 정의 합니다.
  • 사용-포인터 를 특정 손 (왼쪽/오른쪽)에 대해서만 인스턴스화할 수 있습니다.

참고

포인터 항목의 속성을 없음 으로 설정 하면 목록에서 해당 포인터를 제거 하는 대신 시스템에서 효과적으로 사용 하지 않도록 설정 됩니다.

  • 포인터 Prefab -이 Prefab 자산은 지정 된 컨트롤러 유형과 일치 하는 컨트롤러가 추적 되기 시작 하면 인스턴스화됩니다.

컨트롤러와 연결 된 여러 개의 포인터가 있을 수 있습니다. 예를 들어 DefaultHoloLens2InputSystemProfile (asset/MRTK/SDK/Profiles/HoloLens2/)에서 트레일러 컨트롤러는 DefaultHoloLens2InputSystemProfile, GrabPointerdefaultcontrollerpointer (즉, 광선)와 연결 됩니다.

참고

MRTK는 asset /MRTK/SDK/Features/UX/prefabs/포인터에 prefabs 포인터 집합을 제공 합니다. 자산/m RTK/SDK/Features/UX/scripts/포인터나 기타 스크립트의 포인터 스크립트 중 하나를 포함 하는 경우 새 사용자 지정 prefab을 빌드할 수 있습니다 .

커서 구성

응시 커서는 편집기 내에서의 속성을 통해 직접 구성할 수 GazeCursorPrefabMixedRealityInputSystemProfile 있습니다. 다른 포인터에 사용 되는 커서를 구성 하려면 해당의 필드에 사용 된 prefab을 변경 해야 합니다 CursorPrefabBaseControllerPointer . 커서를 프로그래밍 방식으로 변경 하려면 BaseCursor 해당 동작에 대 한 속성을 수정 IMixedRealityPointer 합니다.

Cursor Prefab 속성

커서 동작 구현에 대 한 예는 asset /MRTK/SDK/Features/UX/prefabs/cursor 의 커서 prefabs를 참조 하세요. 특히 DefaultGazeCursor 는 컨텍스트 상태에 따라 커서의 그래픽을 변경 하는 강력한 구현을 제공 합니다.

기본 포인터 클래스

다음 클래스는 위에 설명 된 기본 Mrtk 포인터 프로필 에서 사용 가능 하 고 정의 된 기본 MRTK 포인터입니다. 자산/m a RTK/SDK/Features/UX/Prefabs/포인터 아래에 제공 되는 각 포인터 prefab는 연결 된 포인터 구성 요소 중 하나를 포함 합니다.

MRTK 기본 포인터

먼 포인터

LinePointer

기본 포인터 클래스인 Linepointer는 포인터 방향으로 입력 (즉, 컨트롤러)의 원본에서 선을 그리고이 방향으로 단일 광선 캐스트를 지원 합니다. 일반적으로 일반적으로 ShellHandRayPointer 일반적인 기능을 제공 하는이 클래스 대신 및 텔레포트 포인터와 같은 자식 클래스는 인스턴스화되고 사용 됩니다 .이 클래스 대신 teleportation가 종료 되는 위치를 나타내는 줄을 그립니다.

oculus, vive 및 Windows Mixed Reality 같은 동작 컨트롤러의 경우 회전이 컨트롤러의 회전과 일치 합니다. HoloLens 2 구분 하는 것과 같은 다른 컨트롤러의 경우에는 회전이 시스템에서 제공 하는 포인팅 포즈와 일치 합니다.

MRTK 포인터 선
CurvePointer

CurvePointer 는 곡선을 따라 다중 단계 광선 캐스트를 허용 하 여 linepointer 클래스를 확장 합니다. 이 기본 포인터 클래스는 줄이 parabola로 일관 되 게 구부러지는 teleportation 포인터와 같은 곡선 인스턴스에 유용 합니다.

ShellHandRayPointer

에서 확장 되는 ShellHandRayPointer의 구현은 Mrtk 포인터 프로필에 대 한 기본값으로 사용 됩니다. Defaultcontrollerpointer prefab는 클래스를 구현 합니다 .

GGVPointer

GGV (응시/제스처/Voice) 포인터 라고도 하며, 주로 응시 및 Air 탭 또는 응시 및 음성 선택 상호 작용을 통해 1 스타일의 GGVPointer HoloLens 하 고 상호 작용을 탭 합니다. GGV 포인터의 위치와 방향은 헤드의 위치와 회전에 따라 결정 됩니다.

TouchPointer

TouchPointer 는 Unity Touch 입력 (즉, 터치 스크린) 작업을 담당 합니다. 이는 화면을 터치 하는 동작이 카메라의 광선을 장면의 잠재적 위치에 캐스팅 하기 때문에 ' 먼 상호 작용 '입니다.

MousePointer

MousePointer 는 원거리 상호 작용을 위해 전 세계 raycast로 화면을 구동 하지만 터치 대신 마우스의 경우

마우스 포인터

참고

mrtk에서는 기본적으로 마우스 지원을 사용할 수 없지만, mrtk 입력 프로필에 형식의 새 입력 Data Provider 을 추가 하 고을 MixedRealityMouseInputProfile 데이터 공급자에 할당 하 여 사용 하도록 설정할 수 있습니다.

가까운 포인터

PokePointer

Pokepointer 는 "near 인터랙션 touchable"을 지 원하는 게임 개체와 상호 작용 하는 데 사용 됩니다. 연결 된 스크립트가 있는 Gameobject입니다 NearInteractionTouchable . UnityUI의 경우이 포인터는 NearInteractionTouchableUnityUIs을 찾습니다. PokePointer는 SphereCast을 사용 하 여 가장 가까운 touchable 요소를 확인 하 고 pressable 단추와 같은 기능을 수행 하는 데 사용 됩니다.

구성 요소를 사용 하 여 GameObject를 구성 하는 경우 NearInteractionTouchableNearInteractionTouchable 매개 변수를 구성 하 여 단추나 touchable로 설정 해야 하는 다른 개체의 맨 앞을 가리키도록 해야 합니다. 또한 touchable의 경계가 touchable 개체의 범위와 일치 하는지 확인 합니다.

유용한 Poke 포인터 속성:

  • TouchableDistance: touchable 표면을 상호 작용할 수 있는 최대 거리입니다.
  • 시각적개체: 손가락 팁 시각적 개체를 렌더링 하는 데 사용 되는 Game 개체 (기본적으로 손가락의 고리)입니다.
  • Line: fingertip에서 활성 입력 화면으로 그리기 위한 선택적 줄입니다.
  • Poke 계층 마스크 -LayerMasks의 우선 순위가 지정 된 배열을 사용 하 여 포인터와 상호 작용할 수 있는 gameobject와 시도 하는 상호 작용 순서를 결정 합니다. NearInteractionTouchablePoke 포인터와 상호 작용 하려면 GameObject에도 구성 요소가 있어야 합니다.
Poke 포인터
SpherePointer

SpherePointerOverlapSphere 를 사용 하 여 상호 작용에 가장 가까운 개체를 식별 합니다 .이는와 같은 "grabbable" 입력에 유용 합니다. PokePointer/NearInteractionTouchable 함수 쌍과 마찬가지로, 구 포인터로 interactable 하기 위해 game 개체는 스크립트인 구성 요소를 포함 해야 합니다 NearInteractionGrabbable .

잡기 포인터

유용한 구 포인터 속성:

  • 구 캐스트 반지름: grabbable 개체를 쿼리 하는 데 사용 되는 구의 반지름입니다.
  • Near 개체 여백: 개체가 포인터 근처에 있는지를 검색 하기 위한 쿼리를 위한 구에 대 한 위쪽 거리입니다. 총 개체 검색 반경은 구 캐스트 반경 + 개체 여백 가까이입니다.
  • 근거리 개체 섹터 각도: 인접 개체를 쿼리 하기 위한 포인터의 전방 축 주위 각도입니다. IsNearObject쿼리 함수를 원뿔 처럼 만듭니다. 이는 기본적으로 Hololens 2 동작과 일치 하도록 66도로 설정 됩니다.

앞으로 개체에 대해서만 쿼리하도록 수정 된 구 포인터

  • 거의 개체 다듬기 요소: 근접 개체 검색에 대 한 다듬기 비율입니다. 개체가 가까운 개체 반경에서 검색 되는 경우에는 쿼리 된 반지름이 개체 Radius * (1 + 근처 개체 다듬기 요소) 근처에 있으므로 민감도를 줄이고 개체가 검색 범위를 벗어날 수 있습니다.
  • 잡기 계층 마스크 -LayerMasks의 우선 순위를 지정 하 여 포인터와 상호 작용할 수 있는 gameobject와 시도 하는 상호 작용 순서를 결정 합니다. NearInteractionGrabbableSpherePointer와 상호 작용 하려면 GameObject에도 있어야 합니다.

    참고

    공간 인식 계층은 MRTK에서 제공 하는 기본 GrabPointer prefab에서 사용 하지 않도록 설정 됩니다. 이는 공간 메시를 사용 하 여 구와 겹치는 쿼리를 수행 하는 경우의 성능 영향을 줄이기 위해 수행 됩니다. GrabPointer prefab를 수정 하 여이 기능을 사용 하도록 설정할 수 있습니다.

  • Colliders Not 무시 -포인터 근처에 있을 수 있지만 실제로 시각적 FOV에는 없을 수 있는 Colliders를 무시할지 여부를 나타냅니다. 이로 인해 실수로 인 한 가져와가 발생 하지 않을 수 있으며, grabbable 근처에 있을 수 있지만 볼 수 없는 경우에도 핸드 광선을 켤 수 있습니다. 시각적 FOV 는 성능상의 이유로 일반적인 대/시야 대신 원추를 통해 정의 됩니다. 이 원뿔을 중심으로 하는 카메라의 2, 절반 표시 높이 (또는 세로 FOV)와 동일 합니다.
구 포인터

텔레포트 포인터

  • TeleportPointer 사용자를 이동 하기 위해 작업을 수행할 때 (예: 텔레포트 단추가 누름) 텔레포트 요청이 발생 합니다.
  • ParabolicTeleportPointer 는 사용자를 이동 하기 위해 포물선 line raycast를 사용 하 여 작업을 수행할 때 (예: 텔레포트 단추가 누름) 텔레포트 요청을 발생 시킵니다.
포인터 포물선

혼합 현실 플랫폼에 대 한 포인터 지원

다음 표에서는 MRTK의 일반 플랫폼에 일반적으로 사용 되는 포인터 형식에 대해 자세히 설명 합니다. 참고: 이러한 플랫폼에 다른 포인터 형식을 추가할 수 있습니다. 예를 들어 VR에 Poke 포인터 또는 구 포인터를 추가할 수 있습니다. 또한 게임을 포함 하는 VR 장치는 GGV 포인터를 사용할 수 있습니다.

포인터 OpenVR Windows Mixed Reality HoloLens 1 HoloLens 2
ShellHandRayPointer Valid Valid Valid
TeleportPointer Valid Valid
GGVPointer Valid
SpherePointer Valid
PokePointer Valid

코드를 통한 포인터 상호 작용

포인터 이벤트 인터페이스

다음 인터페이스 중 하나 이상을 구현 하 고를 사용 하 여 GameObject에 할당 된 MonoBehaviours는 Collider 연결 된 인터페이스에서 정의 된 대로 포인터 상호 작용 이벤트를 수신 합니다.

이벤트 Description Handler
포커스 변경/포커스가 변경 되기 전에 포커스가 손실 되는 게임 개체와 포인터가 포커스를 변경할 때마다 발생 합니다. IMixedRealityFocusChangedHandler
포커스 입력/종료 첫 번째 포인터가 포커스를 벗어나면 마지막 포인터가 포커스를 잃을 때 포커스를 얻는 게임 개체에서 발생 합니다. IMixedRealityFocusHandler
포인터 아래로/아래로/위로/클릭 보고서 포인터를 끌어서 놓으면 발생 합니다. IMixedRealityPointerHandler
터치 시작/업데이트 됨/완료 됨 터치 활동을 보고 하는 것과 같은 터치 인식 포인터에 의해 발생 PokePointer 합니다. IMixedRealityTouchHandler

참고

IMixedRealityFocusChangedHandler 및는 발생 하는 IMixedRealityFocusHandler 개체에서 처리 되어야 합니다. 포커스 이벤트를 전역적으로 받을 수 있지만 다른 입력 이벤트와 달리 전역 이벤트 처리기는 포커스를 기준으로 이벤트 수신을 차단 하지 않습니다 (이벤트는 전역 처리기와 포커스의 해당 개체에서 수신 됨).

작업 중인 포인터 입력 이벤트

포인터 입력 이벤트는 일반 입력 이벤트와 비슷한 방식으로 MRTK 입력 시스템에서 인식 되 고 처리 됩니다. 포인터 입력 이벤트는 입력 이벤트를 발생 시킨 포인터 뿐만 아니라 전역 입력 처리기에의 한 GameObject만 처리 됩니다. 일반 입력 이벤트는 모든 활성 포인터에 대해 Gameobject에 의해 처리 됩니다.

  1. MRTK 입력 시스템에서 입력 이벤트를 인식 했습니다.
  2. MRTK 입력 시스템은 등록 된 모든 전역 입력 처리기에 입력 이벤트에 대 한 관련 인터페이스 함수를 발생 시킵니다.
  3. 입력 시스템은 이벤트를 발생 시킨 포인터에 대해 포커스가 있는 GameObject를 결정 합니다.
    1. 입력 시스템은 Unity의 이벤트 시스템 을 활용 하 여 포커스가 있는 GameObject에서 일치 하는 모든 구성 요소에 대해 관련 인터페이스 함수를 실행 합니다.
    2. 어떤 지점에서 든 입력 이벤트가 사용 된 것으로 표시되 면 프로세스가 종료 되 고 추가 gameobject가 콜백을 수신할 수 없습니다.
      • 예: 인터페이스를 구현 하는 구성 요소는 IMixedRealityFocusHandler GameObject의 이득을 검색 하거나 포커스를 잃을 수 있습니다.
      • 참고: 현재 GameObject에서 원하는 인터페이스와 일치 하는 구성 요소가 없는 경우 Unity 이벤트 시스템은 부모 GameObject를 검색 하기 위해 버블링 됩니다.
  4. 전역 입력 처리기를 등록 하지 않고 일치 하는 구성 요소/인터페이스를 사용 하 여 GameObject를 찾을 수 없는 경우 입력 시스템은 각 대체 등록 된 입력 처리기를 호출 합니다.

예제

다음은 포인터가 포커스를 하거나 포커스를 벗어나거나 포인터가 개체를 선택할 때 연결 된 렌더러의 색을 변경 하는 예제 스크립트입니다.

public class ColorTap : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityPointerHandler
{
    private Color color_IdleState = Color.cyan;
    private Color color_OnHover = Color.white;
    private Color color_OnSelect = Color.blue;
    private Material material;

    private void Awake()
    {
        material = GetComponent<Renderer>().material;
    }

    void IMixedRealityFocusHandler.OnFocusEnter(FocusEventData eventData)
    {
        material.color = color_OnHover;
    }

    void IMixedRealityFocusHandler.OnFocusExit(FocusEventData eventData)
    {
        material.color = color_IdleState;
    }

    void IMixedRealityPointerHandler.OnPointerDown(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerDragged(
         MixedRealityPointerEventData eventData) { }

    void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
    {
        material.color = color_OnSelect;
    }
}

쿼리 포인터

사용 가능한 입력 원본 (즉, 사용 가능한 컨트롤러 및 입력)을 반복 하 여 현재 활성화 된 모든 포인터를 수집 하 여 연결 된 포인터를 검색할 수 있습니다.

var pointers = new HashSet<IMixedRealityPointer>();

// Find all valid pointers
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
    foreach (var pointer in inputSource.Pointers)
    {
        if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
        {
            pointers.Add(pointer);
        }
    }
}

기본 포인터

개발자는 포커스의 기본 포인터가 변경 될 때 알림을 받도록 FocusProviders PrimaryPointerChanged 이벤트를 구독할 수 있습니다. 이는 사용자가 현재 응시를 통해 장면 또는 손 모양 또는 다른 입력 소스와 상호 작용 하 고 있는지 확인 하는 데 매우 유용할 수 있습니다.

private void OnEnable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}

private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
    ...
}

private void OnDisable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);

    // This flushes out the current primary pointer
    OnPrimaryPointerChanged(null, null);
}

PrimaryPointerExample(자산/m a RTK/예제/데모/입력/장면/PrimaryPointer) 장면에서는 이벤트에 대해를 사용 하 여 PrimaryPointerChangedHandler 새 기본 포인터에 응답 하는 방법을 보여 줍니다.

기본 포인터 예제

포인터 결과

포인터 속성에는 Result 포커스가 있는 개체를 확인 하는 데 사용 되는 장면 쿼리의 현재 결과가 포함 됩니다. 동작 컨트롤러에 대해 기본적으로 생성 된 것과 같은 raycast 포인터의 경우, 입력 및 손 광선의 위치와 정상적인 위치를 포함 합니다.

private void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
    var result = eventData.Pointer.Result;
    var spawnPosition = result.Details.Point;
    var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
    Instantiate(MyPrefab, spawnPosition, spawnRotation);
}

PointerResultExample장면 (asset/MRTK/example/데모가/Input/장면이/PointerResult/PointerResultExample)은 포인터를 사용 하 여 Result 적중 위치에서 개체를 생성 하는 방법을 보여 줍니다.

포인터 결과

포인터 사용 안 함

포인터를 사용 하거나 사용 하지 않도록 설정 하려면 (예: 손 모양 사용 안 함)를 PointerBehavior 통해 지정 된 포인터 형식에 대해를 설정 PointerUtils 합니다.

// Disable the hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Disable hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

// Disable the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

// Set the behavior to match HoloLens 1
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
public void SetHoloLens1()
{
    PointerUtils.SetPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGGVBehavior(PointerBehavior.Default);
}

PointerUtilsTurnPointersOnOff 더 많은 예제는 및를 참조 하세요.

편집기를 통한 포인터 상호 작용

에서 처리 하는 포인터 이벤트의 경우 IMixedRealityPointerHandler mrtk는 구성 요소의 형태로 더 편리 하 PointerHandler 게 사용할 수 있으므로 Unity 이벤트를 통해 포인터 이벤트를 직접 처리할 수 있습니다.

포인터 처리기

포인터 익스텐트

Far 포인터에는이를 사용 하 여 장면의 다른 개체와 상호 작용 하는 정도를 제한 하는 설정이 있습니다. 기본적으로이 값은 10 미터로 설정 됩니다. 이 값은 HoloLens 셸의 동작과 일관 되 게 유지 되도록 선택 되었습니다.

DefaultControllerPointerPrefab의 구성 요소 필드를 업데이트 하 여 변경할 수 있습니다 ShellHandRayPointer .

포인터 익스텐트 -포인터가 상호 작용 하는 최대 거리를 제어 합니다.

기본 포인터 익스텐트 -포인터가 무엇이 든 상호 작용 하지 않을 때 렌더링 되는 포인터 광선/선의 길이를 제어 합니다.

추가 정보