Unity의 모션 컨트롤러

HoloLens 및 몰입형 HMD에서 Unity의 응시, 손 제스처모션 컨트롤러에서 작업을 수행하는 두 가지 주요 방법이 있습니다. Unity에서 동일한 API를 통해 두 공간 입력 원본의 데이터에 액세스합니다.

Unity는 Windows Mixed Reality의 공간 입력 데이터에 액세스하는 두 가지 기본 방법을 제공합니다. 일반적인 Input.GetButton/Input.GetAxis API 는 여러 Unity XR SDK에서 작동하지만 Windows Mixed Reality와 관련된 InteractionManager/GestureRecognizer API는 전체 공간 입력 데이터 집합을 노출합니다.

Unity XR 입력 API

새 프로젝트의 경우 처음부터 새 XR 입력 API를 사용하는 것이 좋습니다.

XR API에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

Unity 단추/축 매핑 테이블

Windows Mixed Reality 모션 컨트롤러용 Unity의 Input Manager는 Input.GetButton/GetAxis API를 통해 아래에 나열된 단추 및 축 ID를 지원합니다. "Windows MR 관련" 열은 InteractionSourceState 형식에서 사용할 수 있는 속성을 나타냅니다. 이러한 각 API는 아래 섹션에서 자세히 설명합니다.

Windows Mixed Reality의 단추/축 ID 매핑은 일반적으로 오큘러스 단추/축 ID와 일치합니다.

Windows Mixed Reality에 대한 단추/축 ID 매핑은 다음 두 가지 방법으로 OpenVR의 매핑과 다릅니다.

  1. 매핑은 엄지스틱과 구별되는 터치 패드 ID를 사용하여 엄지스틱과 터치 패드가 모두 있는 컨트롤러를 지원합니다.
  2. 매핑은 메뉴 단추에 대한 A 및 X 단추 ID를 오버로드하여 실제 ABXY 단추에 사용할 수 있도록 하는 것을 방지합니다.
입력 일반 Unity API
(Input.GetButton/GetAxis)
Windows MR 관련 입력 API
(XR. WSA. 입력)
왼손 오른손
누른 트리거 선택 축 9 = 1.0 축 10 = 1.0 selectPressed
트리거 아날로그 값 선택 축 9 축 10 selectPressedAmount
부분적으로 누른 트리거 선택 단추 14 (게임 패드 호환성) 단추 15 (게임 패드 호환성) selectPressedAmount > 0.0
메뉴 단추를 눌렀습니다. 단추 6* 단추 7* menuPressed
그립 단추를 눌렀습니다. 축 11 = 1.0(아날로그 값 없음)
단추 4 (게임 패드 호환성)
축 12 = 1.0(아날로그 값 없음)
단추 5 (게임 패드 호환성)
파악
Thumbstick X (왼쪽: -1.0, 오른쪽: 1.0) 축 1 축 4 thumbstickPosition.x
썸스틱 Y (위쪽: -1.0, 아래쪽: 1.0) 축 2 축 5 thumbstickPosition.y
엄지스틱 누름 단추 8 단추 9 thumbstickPressed
터치 패드 X (왼쪽: -1.0, 오른쪽: 1.0) 축 17* 축 19* touchpadPosition.x
터치 패드 Y (위쪽: -1.0, 아래쪽: 1.0) 축 18* 축 20* touchpadPosition.y
터치 패드 터치 단추 18* 단추 19* touchpadTouched
터치 패드 누름 단추 16* 단추 17* touchpadPressed
6DoF 그립 포즈 또는 포인터 포즈 그립 포즈만: XR. InputTracking.GetLocalPosition
XR. InputTracking.GetLocalRotation
그립 또는 포인터를 인수로 전달: sourceState.sourcePose.TryGetPosition
sourceState.sourcePose.TryGetRotation
추적 상태 MR 관련 API를 통해서만 사용할 수 있는 위치 정확도 및 원본 손실 위험 sourceState.sourcePose.positionAccuracy
sourceState.properties.sourceLossRisk

참고 항목

이러한 단추/축 ID는 게임 패드, 오큘러스 터치 및 OpenVR에서 사용하는 매핑의 충돌로 인해 Unity가 OpenVR에 사용하는 ID와 다릅니다.

OpenXR

Unity의 혼합 현실 상호 작용에 대한 기본 사항을 알아보려면 Unity XR 입력에 대한 Unity 설명서를 방문 하세요. 이 Unity 설명서에서는 컨트롤러별 입력에서 보다 일반화된 InputFeatureUsage로의 매핑, 사용 가능한 XR 입력을 식별하고 분류하는 방법, 이러한 입력에서 데이터를 읽는 방법 등에 대해 설명합니다.

Mixed Reality OpenXR 플러그 인은 아래에 설명된 대로 표준 InputFeatureUsage에 매핑된 추가 입력 상호 작용 프로필을 제공합니다.

InputFeatureUsage HP Reverb G2 컨트롤러(OpenXR) HoloLens Hand(OpenXR)
primary2DAxis 조이스틱
primary2DAxisClick 조이스틱 - 클릭
트리거 트리거
그립 그립 에어 탭 또는 짜기
primaryButton [X/A] - 누르기 에어 탭
secondaryButton [Y/B] - 누르기
gripButton 그립 - 누르기
triggerButton 트리거 - 누르기
menuButton 메뉴

그립 포즈와 포인팅 포즈

Windows Mixed Reality는 다양한 폼 팩터에서 모션 컨트롤러를 지원합니다. 각 컨트롤러의 디자인은 사용자의 손 위치와 앱이 컨트롤러를 렌더링할 때 가리키는 데 사용해야 하는 자연스러운 "앞으로" 방향 간의 관계에 따라 다릅니다.

이러한 컨트롤러를 더 잘 나타내기 위해 각 상호 작용 소스, 그립 포즈 및 포인터 포즈에 대해 조사할 수 있는 두 가지 종류의 포즈있습니다. 그립 포즈와 포인터 포즈 좌표는 모두 글로벌 Unity 월드 좌표의 모든 Unity API에 의해 표현됩니다.

그립 포즈

그립 포즈HoloLens에서 감지하거나 모션 컨트롤러를 들고 있는 사용자 손바닥의 위치를 나타냅니다.

몰입형 헤드셋에서 그립 포즈는 사용자의 손이나 사용자의 손에 들고 있는 개체를 렌더링하는 데 가장 적합합니다. 그립 포즈는 모션 컨트롤러를 시각화할 때도 사용됩니다. 동작 컨트롤러에 대해 Windows에서 제공하는 렌더링 가능한 모델은 그립 포즈를 회전의 원점 및 중심으로 사용합니다.

그립 포즈는 다음과 같이 구체적으로 정의됩니다.

  • 그립 위치: 컨트롤러를 자연스럽게 잡을 때 손바닥 중심, 그립 내의 위치를 가운데에 맞게 왼쪽 또는 오른쪽으로 조정합니다. Windows Mixed Reality 모션 컨트롤러에서 이 위치는 일반적으로 확인 단추에 맞춥니다.
  • 그립 방향의 오른쪽 축: 평평한 5 손가락 포즈를 형성하기 위해 손을 완전히 열면 손바닥에 정상적인 광선 (왼쪽 손바닥에서 앞으로, 오른쪽 손바닥에서 뒤로)
  • 그립 방향의 앞으로 축: 손을 부분적으로 닫을 때(컨트롤러를 들고 있는 것처럼) 엄지 손가락이 아닌 손가락으로 형성된 튜브를 통해 "앞으로" 가리키는 광선입니다.
  • 그립 방향의 위쪽 축: 오른쪽 및 앞으로 정의에 내포된 위쪽 축입니다.

Unity의 XR(공급업체 간 입력 API)을 통해 그립 포즈에 액세스할 수 있습니다. InputTracking. GetLocalPosition/Rotation) 또는 Windows MR 관련 API를 통해(sourceState.sourcePose.TryGetPosition/Rotation, 그립 노드에 대한 포즈 데이터 요청)

포인터 포즈

포인터 포즈앞으로 가리키는 컨트롤러의 끝을 나타냅니다.

시스템 제공 포인터 포즈는 컨트롤러 모델 자체를 렌더링할 때 레이캐스트하는 데 가장 적합합니다. 컨트롤러 대신 가상 총과 같은 다른 가상 개체를 렌더링하는 경우 앱 정의 총 모델의 배럴을 따라 이동하는 광선과 같이 해당 가상 개체에 가장 자연스러운 광선을 가리킬 수 있습니다. 사용자는 실제 컨트롤러가 아닌 가상 개체를 볼 수 있으므로 앱을 사용하는 사용자에게는 가상 개체를 가리키는 것이 더 자연스러울 수 있습니다.

현재 포인터 포즈는 Windows MR 관련 API인 sourceState.sourcePose.TryGetPosition/Rotation을 통해서만 Unity에서 사용할 수 있으며 InteractionSourceNode.Pointer 를 인수로 전달합니다.

OpenXR

OpenXR 입력 상호 작용을 통해 두 가지 포즈 집합에 액세스할 수 있습니다.

  • 손에 있는 개체를 렌더링하기 위한 그립 포즈
  • 목표는 세계를 가리키는 포즈.

이 디자인과 두 포즈의 차이점에 대한 자세한 내용은 OpenXR 사양 - 입력 하위 경로에서 찾을 수 있습니다.

InputFeatureUsages DevicePosition, DeviceRotation, DeviceVelocity 및 DeviceAngularVelocity에서 제공하는 포즈는 모두 OpenXR 그립 포즈를 나타냅니다. 그립 포즈와 관련된 InputFeatureUsage는 Unity의 CommonUsages에 정의되어 있습니다.

InputFeatureUsages PointerPosition, PointerRotation, PointerVelocity 및 PointerAngularVelocity에서 제공하는 포즈는 모두 OpenXR 목표 포즈를 나타냅니다. 이러한 InputFeatureUsages는 포함된 C# 파일에 정의되지 않으므로 다음과 같이 사용자 고유의 InputFeatureUsages를 정의해야 합니다.

public static readonly InputFeatureUsage<Vector3> PointerPosition = new InputFeatureUsage<Vector3>("PointerPosition");

햅 틱

Unity의 XR 입력 시스템에서 촉각을 사용하는 방법에 대한 자세한 내용은 Unity XR 입력 - 촉각에 대한 Unity 설명서에서 확인할 수 있습니다.

컨트롤러 추적 상태

헤드셋과 마찬가지로 Windows Mixed Reality 모션 컨트롤러에는 외부 추적 센서를 설치할 필요가 없습니다. 대신 컨트롤러는 헤드셋 자체의 센서에 의해 추적됩니다.

사용자가 컨트롤러를 헤드셋의 시야 밖으로 이동하면 Windows는 대부분의 경우 컨트롤러 위치를 계속 유추합니다. 컨트롤러가 시각적 추적을 오랫동안 손실하면 컨트롤러의 위치는 근사 정확도 위치로 떨어집니다.

이 시점에서 시스템은 내부 방향 센서를 사용하여 컨트롤러의 실제 방향을 노출하면서 이동하면서 사용자의 위치를 추적하여 사용자에게 컨트롤러를 본문 잠금합니다. 컨트롤러를 사용하여 UI 요소를 가리키고 활성화하는 많은 앱은 사용자가 눈치채지 못한 채 대략적인 정확도로 정상적으로 작동할 수 있습니다.

명시적으로 상태 추적에 대한 추론

추적 상태에 따라 위치를 다르게 처리하려는 앱은 더 나아가서 SourceLossRisk 및 PositionAccuracy같은 컨트롤러 상태의 속성을 검사할 수 있습니다.

추적 상태 SourceLossRisk PositionAccuracy TryGetPosition
높은 정확도 < 1.0 높다 true
높은 정확도(손실 위험) == 1.0 높다 true
대략적 정확도 == 1.0 대략적인 true
위치 없음 == 1.0 대략적인 false

이러한 모션 컨트롤러 추적 상태는 다음과 같이 정의됩니다.

  • 높은 정확도: 모션 컨트롤러는 헤드셋의 시야 내에 있지만 일반적으로 시각적 추적에 따라 높은 정확도 위치를 제공합니다. 순간적으로 시야를 떠나거나 헤드셋 센서(예: 사용자의 다른 손에 의해)에서 순간적으로 가려지는 움직이는 컨트롤러는 컨트롤러 자체의 관성 추적에 따라 짧은 시간 동안 높은 정확도 포즈를 계속 반환합니다.
  • 높은 정확도(손실 위험): 사용자가 헤드셋의 시야 가장자리를 지나 모션 컨트롤러를 이동하면 헤드셋이 곧 컨트롤러의 위치를 시각적으로 추적할 수 없게 됩니다. 앱은 SourceLossRisk가 1.0에 도달하는 것을 확인하여 컨트롤러가 이 FOV 경계에 도달한 시기를 알고 있습니다. 이 시점에서 앱은 고품질 포즈의 꾸준한 스트림이 필요한 컨트롤러 제스처를 일시 중지하도록 선택할 수 있습니다.
  • 대략적인 정확도: 컨트롤러가 시각적 추적을 오랫동안 손실하면 컨트롤러의 위치가 근사 정확도 위치로 떨어집니다. 이 시점에서 시스템은 내부 방향 센서를 사용하여 컨트롤러의 실제 방향을 노출하면서 이동하면서 사용자의 위치를 추적하여 사용자에게 컨트롤러를 본문 잠금합니다. 컨트롤러를 사용하여 UI 요소를 가리키고 활성화하는 많은 앱은 사용자가 눈치채지 못한 채 대략적인 정확도로 정상적으로 작동할 수 있습니다. 입력 요구 사항이 더 많은 앱은 PositionAccuracy 속성을 검사하여 높은 정확도에서 근사치 정확도로 이 드롭을 감지하도록 선택할 수 있습니다. 예를 들어 이 시간 동안 사용자에게 화면 외 대상에 더 관대한 적중함을 제공할 수 있습니다.
  • 위치 없음: 컨트롤러는 오랜 시간 동안 대략적인 정확도로 작동할 수 있지만, 때로는 시스템에서 신체가 잠긴 위치조차도 현재 의미가 없다는 것을 알고 있습니다. 예를 들어 켜진 컨트롤러가 시각적으로 관찰되지 않았거나 사용자가 다른 사용자가 선택한 컨트롤러를 내려 놓을 수 있습니다. 이때 시스템은 앱에 어떤 위치도 제공하지 않으며 TryGetPosition 은 false를 반환합니다.

Common Unity API(Input.GetButton/GetAxis)

네임스페이스: UnityEngine, UnityEngine.XR
형식: 입력, XR. InputTracking

Unity는 현재 일반 Input.GetButton/Input.GetAxis API를 사용하여 손 및 모션 컨트롤러를 포함하여 Oculus SDK, OpenVR SDK 및 Windows Mixed Reality에 대한 입력을 노출합니다. 앱에서 이러한 API를 입력에 사용하는 경우 Windows Mixed Reality를 비롯한 여러 XR SDK에서 모션 컨트롤러를 쉽게 지원할 수 있습니다.

논리 단추의 누름 상태 가져오기

일반적인 Unity 입력 API를 사용하려면 일반적으로 단추와 축을 Unity 입력 관리자의 논리적 이름에 연결하고 단추 또는 축 ID를 각 이름에 바인딩하는 것으로 시작합니다. 그런 다음 논리 단추/축 이름을 참조하는 코드를 작성할 수 있습니다.

예를 들어 왼쪽 동작 컨트롤러의 트리거 단추를 제출 작업에 매핑하려면 Unity 내에서 프로젝트 설정 입력 편집 > 으로 이동하고 축 아래의 제출 섹션의 속성을 확장합니다.> 다음과 같이 Positive Button 또는 Alt Positive Button 속성을 변경하여 조이스틱 단추 14를 읽습니다.

Unity의 InputManager
Unity InputManager

그러면 스크립트에서 Input.GetButton을 사용하여 제출 작업을 확인할 수 있습니다.

if (Input.GetButton("Submit"))
{
  // ...
}

축에서 Size 속성을 변경하여 논리 단추를 더 추가할 수 있습니다.

실제 단추의 누름 상태 직접 가져오기

Input.GetKey를 사용하여 정규화된 이름으로 단추에 수동으로 액세스할 수도 있습니다.

if (Input.GetKey("joystick button 8"))
{
  // ...
}

손 또는 모션 컨트롤러의 포즈 가져오기

XR을 사용하여 컨트롤러의 위치 및 회전에 액세스할 수 있습니다. InputTracking:

Vector3 leftPosition = InputTracking.GetLocalPosition(XRNode.LeftHand);
Quaternion leftRotation = InputTracking.GetLocalRotation(XRNode.LeftHand);

참고 항목

위의 코드는 컨트롤러의 그립 포즈(사용자가 컨트롤러를 보유하는 위치)를 나타내며, 이는 사용자의 손에 칼이나 총을 렌더링하거나 컨트롤러 자체의 모델을 렌더링하는 데 유용합니다.

이 그립 포즈와 포인터 포즈(컨트롤러의 팁이 가리키는 위치) 간의 관계는 컨트롤러 간에 다를 수 있습니다. 현재 컨트롤러의 포인터 포즈에 액세스하는 것은 아래 섹션에 설명된 MR 관련 입력 API를 통해서만 가능합니다.

Windows 전용 API(XR) WSA. 입력)

주의

프로젝트에서 XR을 사용하는 경우 WSA API는 향후 Unity 릴리스에서 XR SDK를 위해 단계적으로 폐지되고 있습니다. 새 프로젝트의 경우 처음부터 XR SDK를 사용하는 것이 좋습니다. XR 입력 시스템 및 API에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

네임스페이스: UnityEngine.XR.WSA.Input
형식: InteractionManager, InteractionSourceState, InteractionSource, InteractionSourceProperties, InteractionSourceKind, InteractionSourceLocation

Windows Mixed Reality 손 입력(HoloLens용) 및 모션 컨트롤러에 대한 자세한 정보를 보려면 UnityEngine.XR.WSA.Input 네임스페이스에서 Windows 관련 공간 입력 API를 사용하도록 선택할 수 있습니다. 이렇게 하면 위치 정확도 또는 원본 종류와 같은 추가 정보에 액세스하여 손과 컨트롤러를 구분할 수 있습니다.

손 및 모션 컨트롤러의 상태에 대한 폴링

GetCurrentReading 메서드를 사용하여 각 상호 작용 원본(손 또는 모션 컨트롤러)에 대해 이 프레임의 상태를 폴링할 수 있습니다 .

var interactionSourceStates = InteractionManager.GetCurrentReading();
foreach (var interactionSourceState in interactionSourceStates) {
    // ...
}

다시 가져오는 각 InteractionSourceState 는 현재 시점의 상호 작용 원본을 나타냅니다. InteractionSourceState다음과 같은 정보를 노출합니다.

  • 어떤 종류의 누름 이 발생하는지(선택/메뉴/손아귀/터치 패드/엄지스틱)

    if (interactionSourceState.selectPressed) {
         // ...
    }
    
  • 터치 패드 및/또는 엄지스틱의 XY 좌표 및 터치 상태와 같은 모션 컨트롤러와 관련된 기타 데이터

    if (interactionSourceState.touchpadTouched && interactionSourceState.touchpadPosition.x > 0.5) {
         // ...
    }
    
  • 소스가 손인지 또는 모션 컨트롤러인지를 알 수 있는 InteractionSourceKind

    if (interactionSourceState.source.kind == InteractionSourceKind.Hand) {
         // ...
    }
    

앞으로 예측된 렌더링 포즈에 대한 폴링

  • 손과 컨트롤러의 상호 작용 원본 데이터를 폴링할 때 이 프레임의 광자가 사용자의 눈에 도달하는 순간에 대해 앞으로 예측된 포즈가 됩니다. 정방향 예측 포즈는 각 프레임마다 컨트롤러 또는 보류된 개체를 렌더링하는 데 가장 적합합니다. 컨트롤러를 사용하여 지정된 보도 또는 릴리스를 대상으로 하는 경우 아래에 설명된 기록 이벤트 API를 사용하는 경우 가장 정확합니다.

    var sourcePose = interactionSourceState.sourcePose;
    Vector3 sourceGripPosition;
    Quaternion sourceGripRotation;
    if ((sourcePose.TryGetPosition(out sourceGripPosition, InteractionSourceNode.Grip)) &&
         (sourcePose.TryGetRotation(out sourceGripRotation, InteractionSourceNode.Grip))) {
         // ...
    }
    
  • 또한 이 현재 프레임에 대해 앞으로 예측된 헤드 포즈를 얻을 수 있습니다. 원본 포즈와 마찬가지로, 아래에 설명된 기록 이벤트 API를 사용하는 경우 지정된 보도 자료 또는 릴리스를 대상으로 지정하는 것이 가장 정확하지만 커서를 렌더링하는 데 유용합니다.

    var headPose = interactionSourceState.headPose;
    var headRay = new Ray(headPose.position, headPose.forward);
    RaycastHit raycastHit;
    if (Physics.Raycast(headPose.position, headPose.forward, out raycastHit, 10)) {
         var cursorPos = raycastHit.point;
         // ...
    }
    

상호 작용 원본 이벤트 처리

정확한 기록 포즈 데이터에서 발생하는 입력 이벤트를 처리하려면 폴링 대신 상호 작용 원본 이벤트를 처리할 수 있습니다.

상호 작용 원본 이벤트를 처리하려면 다음을 수행합니다.

  • InteractionManager 입력 이벤트에 등록합니다. 관심 있는 상호 작용 이벤트의 각 유형에 대해 구독해야 합니다.

    InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed;
    
  • 이벤트를 처리합니다. 상호 작용 이벤트를 구독하면 적절한 경우 콜백을 받게 됩니다. SourcePressed 예제에서는 원본이 검색된 후와 소스가 해제되거나 손실되기 전이 됩니다.

    void InteractionManager_InteractionSourceDetected(InteractionSourceDetectedEventArgs args)
         var interactionSourceState = args.state;
    
         // args.state has information about:
            // targeting head ray at the time when the event was triggered
            // whether the source is pressed or not
            // properties like position, velocity, source loss risk
            // source id (which hand id for example) and source kind like hand, voice, controller or other
    }
    

이벤트 처리를 중지하는 방법

이벤트에 더 이상 관심이 없거나 이벤트를 구독한 개체를 삭제하는 경우 이벤트 처리를 중지해야 합니다. 이벤트 처리를 중지하려면 이벤트 구독을 취소합니다.

InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;

상호 작용 원본 이벤트 목록

사용 가능한 상호 작용 원본 이벤트는 다음과 같습니다.

  • InteractionSourceDetected (원본이 활성화됨)
  • InteractionSourceLost (비활성 상태가 됨)
  • InteractionSourcePressed (탭, 단추 누르기 또는 "선택" 발화)
  • InteractionSourceReleased (탭 끝, 단추 해제 또는 "선택" 발화 끝)
  • InteractionSourceUpdated (일부 상태를 이동하거나 변경)

보도 또는 보도 자료와 가장 정확하게 일치하는 기록 대상 지정 포즈에 대한 이벤트

앞에서 설명한 폴링 API는 앱에 미래 예측 포즈를 제공합니다. 이러한 예측 포즈는 컨트롤러 또는 가상 핸드헬드 개체를 렌더링하는 데 가장 적합하지만 다음 두 가지 주요 이유로 향후 포즈는 대상 지정에 적합하지 않습니다.

  • 사용자가 컨트롤러에서 단추를 누르면 시스템에서 누름을 받기 전에 Bluetooth를 통해 약 20ms의 무선 대기 시간이 있을 수 있습니다.
  • 그런 다음, 정방향 예측 포즈를 사용하는 경우 현재 프레임의 광자가 사용자의 눈에 도달하는 시간을 대상으로 하기 위해 추가로 10-20ms의 전방 예측이 적용됩니다.

즉, 폴링은 보도 또는 보도 자료가 발생했을 때 사용자의 머리와 손이 실제로 돌아온 위치에서 30-40ms 앞으로 소스 포즈 또는 머리 포즈를 제공합니다. HoloLens 손 입력의 경우 무선 전송 지연은 없지만 프레스를 감지하는 데 유사한 처리 지연이 있습니다.

손 또는 컨트롤러 누름에 대한 사용자의 원래 의도에 따라 정확하게 대상으로 지정하려면 InteractionSourcePressed 또는 InteractionSourceReleased 입력 이벤트에서 기록 소스 포즈 또는 머리 포즈를 사용해야 합니다.

사용자의 머리 또는 컨트롤러의 기록 포즈 데이터를 사용하여 보도 자료 또는 릴리스를 대상으로 지정할 수 있습니다.

  • 제스처 또는 컨트롤러 누름이 발생한 순간에 머리 포즈를 취하며, 대상 지정에 사용하여 사용자가 보고 있는 대상을 확인할 수 있습니다.

    void InteractionManager_InteractionSourcePressed(InteractionSourcePressedEventArgs args) {
         var interactionSourceState = args.state;
         var headPose = interactionSourceState.headPose;
         RaycastHit raycastHit;
         if (Physics.Raycast(headPose.position, headPose.forward, out raycastHit, 10)) {
             var targetObject = raycastHit.collider.gameObject;
             // ...
         }
    }
    
  • 소스는 사용자가 컨트롤러를 가리키는 대상을 결정하는 데 사용할 수 있는 동작 컨트롤러 누름이 발생한 시점에 포즈를 취합니다. 이는 언론을 경험한 컨트롤러의 상태입니다. 컨트롤러 자체를 렌더링하는 경우 그립 포즈가 아닌 포인터 포즈를 요청하여 사용자가 렌더링된 컨트롤러의 자연스러운 팁을 고려할 대상 광선을 촬영할 수 있습니다.

    void InteractionManager_InteractionSourcePressed(InteractionSourcePressedEventArgs args)
    {
         var interactionSourceState = args.state;
         var sourcePose = interactionSourceState.sourcePose;
         Vector3 sourceGripPosition;
         Quaternion sourceGripRotation;
         if ((sourcePose.TryGetPosition(out sourceGripPosition, InteractionSourceNode.Pointer)) &&
             (sourcePose.TryGetRotation(out sourceGripRotation, InteractionSourceNode.Pointer))) {
             RaycastHit raycastHit;
             if (Physics.Raycast(sourceGripPosition, sourceGripRotation * Vector3.forward, out raycastHit, 10)) {
                 var targetObject = raycastHit.collider.gameObject;
                 // ...
             }
         }
    }
    

이벤트 처리기 예제

using UnityEngine.XR.WSA.Input;

void Start()
{
    InteractionManager.InteractionSourceDetected += InteractionManager_InteractionSourceDetected;
    InteractionManager.InteractionSourceLost += InteractionManager_InteractionSourceLost;
    InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed;
    InteractionManager.InteractionSourceReleased += InteractionManager_InteractionSourceReleased;
    InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated;
}

void OnDestroy()
{
    InteractionManager.InteractionSourceDetected -= InteractionManager_InteractionSourceDetected;
    InteractionManager.InteractionSourceLost -= InteractionManager_InteractionSourceLost;
    InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;
    InteractionManager.InteractionSourceReleased -= InteractionManager_InteractionSourceReleased;
    InteractionManager.InteractionSourceUpdated -= InteractionManager_InteractionSourceUpdated;
}

void InteractionManager_InteractionSourceDetected(InteractionSourceDetectedEventArgs args)
{
    // Source was detected
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourceLost(InteractionSourceLostEventArgs state)
{
    // Source was lost. This will be after a SourceDetected event and no other events for this
    // source id will occur until it is Detected again
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourcePressed(InteractionSourcePressedEventArgs state)
{
    // Source was pressed. This will be after the source was detected and before it is
    // released or lost
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourceReleased(InteractionSourceReleasedEventArgs state)
{
    // Source was released. The source would have been detected and pressed before this point.
    // This event will not fire if the source is lost
    // args.state has the current state of the source including id, position, kind, etc.
}

void InteractionManager_InteractionSourceUpdated(InteractionSourceUpdatedEventArgs state)
{
    // Source was updated. The source would have been detected before this point
    // args.state has the current state of the source including id, position, kind, etc.
}

MRTK의 모션 컨트롤러

입력 관리자에서 제스처 및 모션 컨트롤러에 액세스할 수 있습니다.

안내 따르기

자세한 사용자 지정 예제가 포함된 단계별 자습서는 Mixed Reality Academy에서 사용할 수 있습니다.

MR 입력 213 - 모션 컨트롤러
MR 입력 213 - 모션 컨트롤러

다음 개발 검사점

앞에서 제시한 Unity 개발 과정을 따라가는 경우 MRTK 핵심 구성 요소를 탐색하는 중입니다. 여기에서 다음 구성 요소로 진행할 수 있습니다.

또는 Mixed Reality 플랫폼 기능 및 API로 이동합니다.

언제든지 Unity 개발 검사점으로 돌아갈 수 있습니다.

참고 항목