포인터

포인터

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

새 컨트롤러를 검색 하면 런타임에 포인터가 자동으로 인스턴스 됩니다. 하나 이상의 포인터를 컨트롤러에 연결할 수 있습니다. 예를 들어 기본 포인터 프로필을 사용 하는 경우 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을 빌드할 수 있습니다 .

기본 포인터 클래스

다음 클래스는 위에 설명 된 기본 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에 Sphere 포인터 또는 Sphere 포인터를 추가할 수 있습니다. 또한 게임 패드가 있는 VR 디바이스는 GGV 포인터를 사용할 수 있습니다.

포인터 OpenVR Windows Mixed Reality HoloLens 1 HoloLens 2
ShellHandRayPointer Valid Valid Valid
TeleportPointer Valid Valid
GGVPointer Valid
SpherePointer Valid
2016년 10월 Valid

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

포인터 이벤트 인터페이스

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

이벤트 Description Handler
포커스가 변경되기 전/포커스가 변경되기 전 포인터가 포커스를 변경할 때마다 게임 개체가 포커스를 잃을 때마다 발생합니다. IMixedRealityFocusChangedHandler
포커스 입력/종료 첫 번째 포인터가 들어가고 마지막 포인터가 포커스를 벗어나면 포커스를 잃을 때 게임 개체에서 포커스를 얻습니다. IMixedRealityFocusHandler
포인터 아래로/끌어서/위로/클릭 포인터를 누르고 끌어서 놓기 위해 발생합니다. IMixedRealityPointerHandler
Touch Started/Updated/Completed 터치 동작을 보고하는 등의 터치 인식 포인터에 의해 PokePointer 발생합니다. IMixedRealityTouchHandler

참고

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

동작의 포인터 입력 이벤트

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

  1. MRTK 입력 시스템에서 입력 이벤트가 발생했음을 인식합니다.
  2. MRTK 입력 시스템은 등록된 모든 전역 입력 처리기에 입력 이벤트에 대한 관련 인터페이스 함수를 발생합니다.
  3. 입력 시스템은 이벤트를 발생시킨 포인터에 포커스가 있는 GameObject를 결정합니다.
    1. 입력 시스템은 Unity의 이벤트 시스템을 활용하여 포커스가 있는 GameObject에서 일치하는 모든 구성 요소에 대한 관련 인터페이스 함수를 시작합니다.
    2. 입력 이벤트가 사용된 것으로 표시된경우 프로세스가 종료되고 더 이상 GameObjects에서 콜백을 수신하지 않습니다.
      • 예제: 인터페이스를 구현하는 구성 요소는 IMixedRealityFocusHandler GameObject를 검색하거나 포커스를 잃습니다.
      • 참고: Unity 이벤트 시스템은 현재 GameObject에서 원하는 인터페이스와 일치하는 구성 요소가 없으면 부모 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(Assets/MRTK/Examples/Demos/Input/Scenes/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장면(Assets/MRTK/Examples/Demos/Input/Scenes/PointerResult/PointerResultExample.unity)은 포인터를 사용하여 Result 적중 위치에서 개체를 생성하는 방법을 보여줍니다.

포인터 결과

포인터 사용 안 함

포인터를 사용하거나 사용하지 않도록 설정하려면(예: 손 광선을 사용하지 않도록 설정하려면) 를 통해 지정된 포인터 형식에 대한 를 PointerBehaviorPointerUtils 설정합니다.

// 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);
}

PointerUtils자세한 TurnPointersOnOff 예제는 및 를 참조하세요.

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

에서 처리하는 포인터 이벤트의 경우 IMixedRealityPointerHandler MRTK는 Unity 이벤트를 통해 포인터 이벤트를 직접 처리할 수 있는 구성 요소 형식의 추가 편의를 PointerHandler 제공합니다.

포인터 처리기

포인터 익스텐트

원거리 포인터에는 장면의 다른 개체를 광선 캐스팅하고 상호 작용하는 정도를 제한하는 설정이 있습니다. 기본적으로 이 값은 10미터로 설정됩니다. 이 값은 HoloLens 셸의 동작과 일관성을 유지하기 위해 선택되었습니다.

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

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

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

참고 항목