Unity의 동작 컨트롤러Motion controllers in Unity

HoloLens의 손으로Unity에서 작업을 수행 하는 두 가지 주요 방법, 그리고 HOLOLENS 및 몰입 형 HMD의 동작 컨트롤러 를 사용할 수 있습니다.There are two key ways to take action on your gaze in Unity, hand gestures and motion controllers in HoloLens and Immersive HMD. Unity에서 동일한 Api를 통해 두 공간 입력 원본에 대 한 데이터에 액세스할 수 있습니다.You access the data for both sources of spatial input through the same APIs in Unity.

Unity는 Windows Mixed Reality의 공간 입력 데이터에 액세스 하는 두 가지 기본 방법을 제공 합니다.Unity provides two primary ways to access spatial input data for Windows Mixed Reality. 일반적인 입력. GetButton/Input. Getbutton api는 여러 Unity XR sdk에서 작동 하는 반면, Windows Mixed Reality와 관련 된 InteractionManager/GestureRecognizer api는 전체 공간 입력 데이터 집합을 제공 합니다.The common Input.GetButton/Input.GetAxis APIs work across multiple Unity XR SDKs, while the InteractionManager/GestureRecognizer API specific to Windows Mixed Reality exposes the full set of spatial input data.

Unity XR 입력 ApiUnity XR input APIs

새 프로젝트의 경우 처음부터 새 XR 입력 Api를 사용 하는 것이 좋습니다.For new projects, we recommend using the new XR input APIs from the beginning.

XR api에 대 한 자세한 내용은 여기에서 찾을 수 있습니다.You can find more information about the XR APIs here.

Unity 단추/축 매핑 테이블Unity button/axis mapping table

Unity의 Windows Mixed Reality의 입력 관리자 동작 컨트롤러는 입력. getbutton/Getbutton api를 통해 아래에 나열 된 단추 및 축 id를 지원 합니다.Unity's Input Manager for Windows Mixed Reality motion controllers supports the button and axis IDs listed below through the Input.GetButton/GetAxis APIs. "Windows MR" 열은 InteractionSourceState 유형에 서 사용할 수 있는 속성을 나타냅니다.The "Windows MR-specific" column refers to properties available off of the InteractionSourceState type. 이러한 각 Api에 대해서는 아래 섹션에서 자세히 설명 합니다.Each of these APIs is described in detail in the sections below.

Windows Mixed Reality의 단추/축 ID 매핑은 일반적으로 Oculus 단추/축 Id와 일치 합니다.The button/axis ID mappings for Windows Mixed Reality generally match the Oculus button/axis IDs.

Windows Mixed Reality의 단추/축 ID 매핑은 다음 두 가지 방법으로 OpenVR 매핑과 다릅니다.The button/axis ID mappings for Windows Mixed Reality differ from OpenVR's mappings in two ways:

  1. 이 매핑은 thumbsticks와 터치 패드를 모두 사용 하는 컨트롤러를 지원 하기 위해 엄지 스틱과는 다른 터치 패드 Id를 사용 합니다.The mapping uses touchpad IDs that are distinct from thumbstick, to support controllers with both thumbsticks and touchpads.
  2. 매핑은 메뉴 단추의 A 및 X 단추 Id를 오버 로드 하지 않고 실제 ABXY 단추에 사용할 수 있도록 합니다.The mapping avoids overloading the A and X button IDs for the Menu buttons to leave them available for the physical ABXY buttons.
입력Input 일반 Unity APICommon Unity APIs
(입력. GetButton/Getbutton)(Input.GetButton/GetAxis)
Windows MR 특정 입력 APIWindows MR-specific Input API
XR. WSA. 입력(XR.WSA.Input)
왼쪽Left hand 오른쪽Right hand
트리거를 선택 합니다.Select trigger pressed 축 9 = 1.0Axis 9 = 1.0 축 10 = 1.0Axis 10 = 1.0 selectPressedselectPressed
아날로그 값 트리거를 선택 합니다.Select trigger analog value 축 9Axis 9 축 10Axis 10 Select보도 금액selectPressedAmount
부분적으로 누른 트리거 선택Select trigger partially pressed 단추 14 (게임 패드 호환성) Button 14 (gamepad compat) 단추 15 (게임 패드 호환성) Button 15 (gamepad compat) Select보도 Sedamount > 0.0selectPressedAmount > 0.0
메뉴 단추 누름Menu button pressed 단추 6 \*Button 6\* 단추 7 \*Button 7\* menuPressedmenuPressed
그립 단추 누름Grip button pressed 축 11 = 1.0 (아날로그 값 없음)Axis 11 = 1.0 (no analog values)
단추 4 (게임 패드 호환성) Button 4 (gamepad compat)
축 12 = 1.0 (아날로그 값 없음)Axis 12 = 1.0 (no analog values)
단추 5 (게임 패드 호환성) Button 5 (gamepad compat)
graspedgrasped
엄지 스틱 X (왼쪽:-1.0, 오른쪽: 1.0) Thumbstick X (left: -1.0, right: 1.0) 축 1Axis 1 축 4Axis 4 thumbstickPositionthumbstickPosition.x
엄지 스틱 Y (위쪽:-1.0, 아래쪽: 1.0) Thumbstick Y (top: -1.0, bottom: 1.0) 축 2Axis 2 축 5Axis 5 thumbstickPositionthumbstickPosition.y
엄지 스틱 누름Thumbstick pressed 단추 8Button 8 단추 9Button 9 thumbstickPressedthumbstickPressed
터치 패드 X (왼쪽:-1.0, 오른쪽: 1.0) Touchpad X (left: -1.0, right: 1.0) 축 17 \*Axis 17\* 축 19 \*Axis 19\* touchpadPositiontouchpadPosition.x
터치 패드 Y (위쪽:-1.0, 아래쪽: 1.0) Touchpad Y (top: -1.0, bottom: 1.0) 축 18 \*Axis 18\* 축 20 \*Axis 20\* touchpadPositiontouchpadPosition.y
터치 패드 작업Touchpad touched 단추 18 \*Button 18\* 단추 19 \*Button 19\* touchpadTouchedtouchpadTouched
터치 패드 누름Touchpad pressed 단추 16 \*Button 16\* 단추 17 \*Button 17\* touchpadPressedtouchpadPressed
6DoF 그립 포즈 또는 포인터 포즈6DoF grip pose or pointer pose 그립 포즈만: XR. InputTracking. GetLocalPositionGrip pose only: XR.InputTracking.GetLocalPosition
XR. InputTracking. GetLocalRotationXR.InputTracking.GetLocalRotation
전달 그립 또는 포인터 를 인수로 전달 합니다. sourcestate TryGetPositionPass Grip or Pointer as an argument: sourceState.sourcePose.TryGetPosition
sourceStatesourceState.sourcePose.TryGetRotation
상태 추적Tracking state MR 특정 API를 통해서만 사용할 수 있는 위치 정확도 및 원본 손실 위험 Position accuracy and source loss risk only available through MR-specific API sourceState. positionAccuracysourceState.sourcePose.positionAccuracy
sourceLossRisksourceState.properties.sourceLossRisk

참고

이러한 단추/축 Id는 gamepads, Oculus Touch 및 OpenVR에서 사용 하는 매핑의 충돌로 인해 Unity에서 OpenVR에 사용 하는 Id와 다릅니다.These button/axis IDs differ from the IDs that Unity uses for OpenVR due to collisions in the mappings used by gamepads, Oculus Touch and OpenVR.

그립 포즈 및 포인팅 포즈Grip pose vs. pointing pose

Windows Mixed Reality는 다양 한 폼 팩터에서 동작 컨트롤러를 지원 합니다.Windows Mixed Reality supports motion controllers in a variety of form factors. 각 컨트롤러의 디자인은 사용자의 손 위치와 앱이 컨트롤러를 렌더링할 때를 가리키는 데 사용 해야 하는 자연 스러운 "전달" 방향 간의 관계에 차이가 있습니다.Each controller's design differs in its relationship between the user's hand position and the natural "forward" direction that apps should use for pointing when rendering the controller.

이러한 컨트롤러를 더 잘 나타내기 위해 각 상호 작용 소스, 그립 포즈포인터 포즈 에 대해 조사할 수 있는 두 가지 종류의 포즈를 확인할 수 있습니다.To better represent these controllers, there are two kinds of poses you can investigate for each interaction source, the grip pose and the pointer pose. 그립 포즈 및 포인터 포즈 좌표는 모두 전역 Unity 세계 좌표의 모든 Unity Api에 의해 표현 됩니다.Both the grip pose and pointer pose coordinates are expressed by all Unity APIs in global Unity world coordinates.

그립 포즈Grip pose

그립 포즈 는 HoloLens에서 검색 되거나 동작 컨트롤러를 보유 하는 사용자 palm의 위치를 나타냅니다.The grip pose represents the location of the users palm, either detected by a HoloLens or holding a motion controller.

몰입 형 헤드셋에서 그립 포즈는 사용자의 손을 만들거나 사용자의 손을 보유 한 개체 를 렌더링 하는 데 가장 적합 합니다.On immersive headsets, the grip pose is best used to render the user's hand or an object held in the user's hand. 그립 포즈는 동작 컨트롤러를 시각화할 때에도 사용 됩니다.The grip pose is also used when visualizing a motion controller. 동작 컨트롤러에 대해 Windows에서 제공 하는 렌더링할 모델 은 그립 포즈를 원본 및 회전 중심으로 사용 합니다.The renderable model provided by Windows for a motion controller uses the grip pose as its origin and center of rotation.

그립 포즈는 구체적으로 다음과 같이 정의 됩니다.The grip pose is defined specifically as follows:

  • 그립 위치: 컨트롤러를 자연스럽 게 유지 하는 경우 왼쪽 또는 오른쪽으로 조정 하 여 그립 내 위치를 가운데에 맞춥니다.The grip position: The palm centroid when holding the controller naturally, adjusted left or right to center the position within the grip. Windows Mixed Reality 동작 컨트롤러에서이 위치는 일반적으로 보통 클릭 단추와 맞춥니다.On the Windows Mixed Reality motion controller, this position generally aligns with the Grasp button.
  • 그립 방향 오른쪽 축: 손 모양 5 손가락 포즈를 형성 하는 손을 완전히 열 때 palm (왼쪽 야자나무에서 오른쪽으로 뒤로)의 광선을 만듭니다.The grip orientation's Right axis: When you completely open your hand to form a flat 5-finger pose, the ray that is normal to your palm (forward from left palm, backward from right palm)
  • 그립 방향 전방 축: 핸들 을 부분적으로 (컨트롤러를 보유 하는 것 처럼) 닫는 경우 비 엄지 손가락으로 형성 된 튜브를 통해 "전달" 하는 광선이 표시 됩니다.The grip orientation's Forward axis: When you close your hand partially (as if holding the controller), the ray that points "forward" through the tube formed by your non-thumb fingers.
  • 그립 방향 up 축: 오른쪽 및 전방 정의에 의해 암시 된 위쪽 축입니다.The grip orientation's Up axis: The Up axis implied by the Right and Forward definitions.

Unity의 교차 공급 업체 입력 API (XR)를 통해 그립 포즈에 액세스할 수 있습니다 . InputTracking. GetLocalPosition/Rotation) 또는 WINDOWS MR 특정 API (sourcestate/Rotation, 그립 노드에 대 한 포즈 데이터 요청)를 통해You can access the grip pose through either Unity's cross-vendor input API (XR.InputTracking.GetLocalPosition/Rotation) or through the Windows MR-specific API (sourceState.sourcePose.TryGetPosition/Rotation, requesting pose data for the Grip node).

포인터 포즈Pointer pose

포인터 포즈 는 컨트롤러의 팁을 나타냅니다.The pointer pose represents the tip of the controller pointing forward.

시스템에서 제공 하는 포인터 포즈는 컨트롤러 모델 자체를 렌더링 하는 경우 raycast를 사용 하는 데 가장 적합 합니다.The system-provided pointer pose is best used to raycast when you're rendering the controller model itself. 컨트롤러 대신 다른 가상 개체 (예: 가상 사용자)를 렌더링 하는 경우 앱 정의 된 포 모델의 배럴을 따라 이동 하는 광선과 같이 해당 가상 개체에 가장 자연 스러운 광선을 가리켜야 합니다.If you're rendering some other virtual object in place of the controller, such as a virtual gun, you should point with a ray that's most natural for that virtual object, such as a ray that travels along the barrel of the app-defined gun model. 사용자는 가상 개체를 볼 수 있고 실제 컨트롤러는 볼 수 없으므로 가상 개체를 가리키면 앱을 사용 하는 것이 더 자연스럽 게 될 수 있습니다.Because users can see the virtual object and not the physical controller, pointing with the virtual object will likely be more natural for those using your app.

현재 포인터 포즈는 InteractionSourceNode 를 인수로 전달 하는 Windows MR 특정 API 인 TryGetPosition/Rotation 을 통해서만 Unity에서 사용할 수 있습니다.Currently, the pointer pose is available in Unity only through the Windows MR-specific API, sourceState.sourcePose.TryGetPosition/Rotation, passing in InteractionSourceNode.Pointer as the argument.

컨트롤러 추적 상태Controller tracking state

헤드셋 처럼 Windows Mixed Reality 동작 컨트롤러를 사용 하려면 외부 추적 센서를 설정 하지 않아도 됩니다.Like the headsets, the Windows Mixed Reality motion controller requires no setup of external tracking sensors. 대신, 컨트롤러는 헤드셋 자체의 센서에 의해 추적 됩니다.Instead, the controllers are tracked by sensors in the headset itself.

사용자가 헤드셋의 보기 필드에서 컨트롤러를 이동 하면 대부분의 경우 Windows에서는 계속 해 서 컨트롤러 위치를 유추 합니다.If the user moves the controllers out of the headset's field of view, Windows continues to infer controller positions in most cases. 컨트롤러에서 충분히 긴 시각적 추적을 분실 한 경우 컨트롤러의 위치는 대략적인 정확도 위치로 삭제 됩니다.When the controller has lost visual tracking for long enough, the controller's positions will drop to approximate-accuracy positions.

이 시점에서 시스템은 컨트롤러를 사용자에 게 본문 잠금을 설정 하 고, 이동 하는 동안 사용자의 위치를 추적 하 고, 내부 방향 센서를 사용 하 여 컨트롤러의 실제 방향을 계속 노출 합니다.At this point, the system will body-lock the controller to the user, tracking the user's position as they move around, while still exposing the controller's true orientation using its internal orientation sensors. 컨트롤러를 사용 하 여 UI 요소를 가리키고 활성화 하는 많은 앱이 정상적으로 작동 하 고, 사용자가 모르게 정확한 정확도를 사용할 수 있습니다.Many apps that use controllers to point at and activate UI elements can operate normally while in approximate accuracy without the user noticing.

이를 위한 가장 좋은 방법은 직접 시도해 보는 것입니다.The best way to get a feel for this is to try it yourself. 다양 한 추적 상태에서 동작 컨트롤러와 함께 작동 하는 몰입 형 콘텐츠 예제를 통해이 비디오를 확인 하세요.Check out this video with examples of immersive content that works with motion controllers across various tracking states:


명시적 추적 상태에 대 한 추론Reasoning about tracking state explicitly

추적 상태에 따라 위치를 다르게 처리 하려는 앱은 더 나아가 컨트롤러의 상태에 대 한 속성 (예: SourceLossRiskpositionaccuracy)을 검사할 수 있습니다.Apps that wish to treat positions differently based on tracking state may go further and inspect properties on the controller's state, such as SourceLossRisk and PositionAccuracy:

상태 추적Tracking state SourceLossRiskSourceLossRisk PositionAccuracyPositionAccuracy TryGetPositionTryGetPosition
높은 정확도 High accuracy < 1.0< 1.0 높은High truetrue
높은 정확도 (손실 위험) High accuracy (at risk of losing) = = 1.0== 1.0 높은High truetrue
대략적인 정확도 Approximate accuracy = = 1.0== 1.0 근사치Approximate truetrue
위치 없음 No position = = 1.0== 1.0 근사치Approximate falsefalse

이러한 동작 컨트롤러 추적 상태는 다음과 같이 정의 됩니다.These motion controller tracking states are defined as follows:

  • 높은 정확도: 동작 컨트롤러는 헤드셋의 보기 필드 내에 있지만 일반적으로 시각적 추적에 따라 정확도가 높은 위치를 제공 합니다.High accuracy: While the motion controller is within the headset's field of view, it will generally provide high-accuracy positions, based on visual tracking. 일시적으로 보기의 필드를 벗어나거나 헤드셋 센서에서 일시적으로 가려진 이동 컨트롤러 (예: 사용자)는 컨트롤러 자체의 관성 추적을 기반으로 짧은 시간 동안 계속 해 서 정확도가 높은 포즈를 반환 합니다.A moving controller that momentarily leaves the field of view or is momentarily obscured from the headset sensors (e.g. by the user's other hand) will continue to return high-accuracy poses for a short time, based on inertial tracking of the controller itself.
  • 높은 정확도 (손실 위험): 사용자가 이동 컨트롤러를 헤드셋의 보기 필드 가장자리를 지나서 이동할 때 헤드셋은 곧 컨트롤러의 위치를 시각적으로 추적할 수 없습니다.High accuracy (at risk of losing): When the user moves the motion controller past the edge of the headset's field of view, the headset will soon be unable to visually track the controller's position. 앱은 SourceLossRisk reach 1.0을 확인 하 여 컨트롤러가이 FOV 경계에 도달한 경우를 인식 합니다.The app knows when the controller has reached this FOV boundary by seeing the SourceLossRisk reach 1.0. 이 시점에서 앱은 고품질 포즈의 안정적인 스트림을 필요로 하는 컨트롤러 제스처를 일시 중지 하도록 선택할 수 있습니다.At that point, the app may choose to pause controller gestures that require a steady stream of high quality poses.
  • 대략적인 정확도: 컨트롤러에서 충분히 긴 시각적 추적을 분실 한 경우 컨트롤러의 위치는 대략적인 정확도 위치로 삭제 됩니다.Approximate accuracy: When the controller has lost visual tracking for long enough, the controller's positions will drop to approximate-accuracy positions. 이 시점에서 시스템은 컨트롤러를 사용자에 게 본문 잠금을 설정 하 고, 이동 하는 동안 사용자의 위치를 추적 하 고, 내부 방향 센서를 사용 하 여 컨트롤러의 실제 방향을 계속 노출 합니다.At this point, the system will body-lock the controller to the user, tracking the user's position as they move around, while still exposing the controller's true orientation using its internal orientation sensors. 컨트롤러를 사용 하 여 UI 요소를 가리키고 활성화 하는 많은 앱이 정상적으로 작동 하 고, 사용자가 모르게 정확한 정확도를 사용할 수 있습니다.Many apps that use controllers to point at and activate UI elements can operate as normal while in approximate accuracy without the user noticing. 입력 요구 사항이 많은 앱은 사용자에 게이 시간 동안 오프 화면 대상에 대 한 hitbox을 제공 하는 등의 방법으로 positionaccuracy 속성을 검사 하 여 정확도가 높은 정확도부터 정확도까지 이러한 삭제를 합리적으로 선택할 수 있습니다.Apps with heavier input requirements may choose to sense this drop from High accuracy to Approximate accuracy by inspecting the PositionAccuracy property, for example to give the user a more generous hitbox on off-screen targets during this time.
  • 위치 없음: 컨트롤러는 오랜 시간 동안 정확한 정확도로 작동할 수 있지만, 경우에 따라 본문 잠금 위치가 중요 하지 않은 경우에도 시스템에서 알 수 있습니다.No position: While the controller can operate at approximate accuracy for a long time, sometimes the system knows that even a body-locked position isn't meaningful at the moment. 예를 들어 설정 된 컨트롤러가 시각적으로 관찰 되지 않았거나 사용자가 다른 사용자가 선택 하는 컨트롤러를 배치할 수 있습니다.For example, a controller that was turned on may have never been observed visually, or a user may put down a controller that's then picked up by someone else. 이러한 시간에 시스템은 앱에 어떤 위치도 제공 하지 않으며 TryGetPosition 는 false를 반환 합니다.At those times, the system won't provide any position to the app, and TryGetPosition will return false.

Common Unity Api (입력. GetButton/Getbutton)Common Unity APIs (Input.GetButton/GetAxis)

네임 스페이스: unityengine, unityengine. XRNamespace: UnityEngine, UnityEngine.XR
형식: Input, XR. InputTrackingTypes: Input, XR.InputTracking

Unity는 현재 일반 입력을 사용 합니다. GetButton/Input. Getbutton api를 사용 하면 핸드 및 동작 컨트롤러를 포함 하 여 oculus Sdk, Openvr sdk 및 Windows Mixed Reality의 입력을 노출할 수 있습니다.Unity currently uses its general Input.GetButton/Input.GetAxis APIs to expose input for the Oculus SDK, the OpenVR SDK and Windows Mixed Reality, including hands and motion controllers. 앱이 입력에 이러한 Api를 사용 하는 경우 Windows Mixed Reality를 비롯 하 여 여러 XR Sdk에서 동작 컨트롤러를 쉽게 지원할 수 있습니다.If your app uses these APIs for input, it can easily support motion controllers across multiple XR SDKs, including Windows Mixed Reality.

논리적 단추의 누름 상태 가져오기Getting a logical button's pressed state

일반 Unity 입력 Api를 사용 하려면 일반적으로 Unity 입력 관리자에서 단추와 축을 논리적 이름에 연결 하 여 단추 또는 축 id를 각 이름에 바인딩하는 것으로 시작 합니다.To use the general Unity input APIs, you'll typically start by wiring up buttons and axes to logical names in the Unity Input Manager, binding a button or axis IDs to each name. 그런 다음 해당 논리적 단추/축 이름을 참조 하는 코드를 작성할 수 있습니다.You can then write code that refers to that logical button/axis name.

예를 들어 왼쪽 동작 컨트롤러의 트리거 단추를 전송 작업에 매핑하려면 > 프로젝트 설정 편집 으로 이동 하 여 Unity 내에서 입력 > 하 고 축 아래에서 제출 섹션의 속성을 확장 합니다.For example, to map the left motion controller's trigger button to the Submit action, go to Edit > Project Settings > Input within Unity, and expand the properties of the Submit section under Axes. 긍정 단추 또는 Alt 긍정 단추 속성을 다음과 같이 조이스틱 단추 14 로 변경 합니다.Change the Positive Button or Alt Positive Button property to read joystick button 14, like this:

Unity의 InputManagerUnity's InputManager
Unity InputManagerUnity InputManager

그런 다음 스크립트는 입력을 사용 하 여 전송 작업을 확인할 수 있습니다 . GetButton:Your script can then check for the Submit action using Input.GetButton:

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

에서 크기 속성을 변경 하 여 논리적 단추를 더 추가할 수 있습니다.You can add more logical buttons by changing the Size property under Axes.

물리적 단추의 누름 상태를 직접 가져오기Getting a physical button's pressed state directly

입력. GetKey 를 사용 하 여 정규화 된 이름으로 수동으로 단추에 액세스할 수도 있습니다.You can also access buttons manually by their fully qualified name, using Input.GetKey:

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

직접 또는 동작 컨트롤러의 포즈 가져오기Getting a hand or motion controller's pose

XR를 사용 하 여 컨트롤러의 위치 및 회전에 액세스할 수 있습니다 . InputTracking:You can access the position and rotation of the controller, using XR.InputTracking:

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

참고

위의 코드는 컨트롤러의 그립 포즈 (사용자가 컨트롤러를 보유 하는 위치)를 나타내며,이는 사용자 쪽에서 소드를 렌더링 하거나 컨트롤러 자체의 모델을 렌더링 하는 데 유용 합니다.The above code represents the controller's grip pose (where the user holds the controller), which is useful for rendering a sword or gun in the user's hand, or a model of the controller itself.

이 그립 포즈와 포인터 포즈 (컨트롤러의 팁) 간의 관계는 컨트롤러 마다 다를 수 있습니다.The relationship between this grip pose and the pointer pose (where the tip of the controller is pointing) may differ across controllers. 이제 컨트롤러의 포인터 포즈에 액세스 하는 것은 아래 섹션에 설명 된 MR 특정 입력 API를 통해서만 가능 합니다.At this moment, accessing the controller's pointer pose is only possible through the MR-specific input API, described in the sections below.

Windows 관련 Api (XR. WSA. 입력Windows-specific APIs (XR.WSA.Input)

주의

프로젝트에서 XR를 사용 하는 경우 WSA Api는 향후 Unity 릴리스의 XR SDK에 대 한 것입니다.If your project is using any of the XR.WSA APIs, these are being phased out in favor of the XR SDK in future Unity releases. 새 프로젝트의 경우 처음부터 XR SDK를 사용 하는 것이 좋습니다.For new projects, we recommend using the XR SDK from the beginning. XR 입력 시스템 및 api에 대 한 자세한 내용은 여기에서 찾을 수 있습니다.You can find more information about the XR Input system and APIs here.

네임 스페이스: unityengine. XRNamespace: UnityEngine.XR.WSA.Input
유형: InteractionManager, InteractionSourceState, InteractionSource, InteractionSourceProperties, InteractionSourceKind, InteractionSourceLocationTypes: InteractionManager, InteractionSourceState, InteractionSource, InteractionSourceProperties, InteractionSourceKind, InteractionSourceLocation

Windows Mixed Reality 입력 (HoloLens 용) 및 동작 컨트롤러에 대 한 자세한 정보를 보려면 Unityengine. XR 네임 스페이스에서 windows 관련 공간 입력 api를 사용 하도록 선택할 수 있습니다.To get at more detailed information about Windows Mixed Reality hand input (for HoloLens) and motion controllers, you can choose to use the Windows-specific spatial input APIs under the UnityEngine.XR.WSA.Input namespace. 이를 통해 위치 정확도 나 소스 종류와 같은 추가 정보에 액세스할 수 있으므로 실습 및 컨트롤러를 구분할 수 있습니다.This lets you access additional information, such as position accuracy or the source kind, letting you tell hands and controllers apart.

직접 및 동작 컨트롤러의 상태 폴링Polling for the state of hands and motion controllers

GetCurrentReading 메서드를 사용 하 여 각 상호 작용 소스 (직접 또는 동작 컨트롤러)에 대해이 프레임의 상태를 폴링할 수 있습니다.You can poll for this frame's state for each interaction source (hand or motion controller) using the GetCurrentReading method.

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

가져오는 각 InteractionSourceState 는 현재 시점에서 상호 작용 소스를 나타냅니다.Each InteractionSourceState you get back represents an interaction source at the current moment in time. InteractionSourceState 는 다음과 같은 정보를 노출 합니다.The InteractionSourceState exposes info such as:

  • 어떤 종류의 누름 이 발생 합니까 (선택/메뉴/-/터치 패드/엄지 스틱)Which kinds of presses are occurring (Select/Menu/Grasp/Touchpad/Thumbstick)

    if (interactionSourceState.selectPressed) {
         // ...
    }
    
  • 터치 패드 및/또는 엄지 스틱 XY 좌표 및 작업 된 상태와 같은 동작 컨트롤러에 해당 하는 기타 데이터Other data specific to motion controllers, such the touchpad and/or thumbstick's XY coordinates and touched state

    if (interactionSourceState.touchpadTouched && interactionSourceState.touchpadPosition.x > 0.5) {
         // ...
    }
    
  • InteractionSourceKind는 원본이 나 동작 컨트롤러 인지 여부를 알 수 있습니다.The InteractionSourceKind to know if the source is a hand or a motion controller

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

앞으로 예측 된 렌더링 동작에 대 한 폴링Polling for forward-predicted rendering poses

  • 손이 나 컨트롤러에서 상호 작용 원본 데이터를 폴링하는 경우이 프레임의 photons 사용자의 눈에 도달 하 게 되는 순간에 대해 앞으로 예측 하는 포즈를 얻을 수 있습니다.When polling for interaction source data from hands and controllers, the poses you get are forward-predicted poses for the moment in time when this frame's photons will reach the user's eyes. 앞으로 예측 되는 포즈는 컨트롤러를 렌더링 하거나 각 프레임에서 보유 한 개체를 렌더링 하는 데 가장 적합 합니다.Forward-predicted poses are best used for rendering the controller or a held object each frame. Controller를 사용 하 여 지정 된 보도 또는 릴리스를 대상으로 하는 경우 아래에 설명 된 기록 이벤트 Api를 사용 하는 경우 가장 정확 합니다.If you're targeting a given press or release with the controller, that will be most accurate if you use the historical event APIs described below.

    var sourcePose = interactionSourceState.sourcePose;
    Vector3 sourceGripPosition;
    Quaternion sourceGripRotation;
    if ((sourcePose.TryGetPosition(out sourceGripPosition, InteractionSourceNode.Grip)) &&
         (sourcePose.TryGetRotation(out sourceGripRotation, InteractionSourceNode.Grip))) {
         // ...
    }
    
  • 이 현재 프레임에 대해 앞으로 예측 한 헤드 포즈를 얻을 수도 있습니다.You can also get the forward-predicted head pose for this current frame. 원본 포즈와 마찬가지로,이 기능은 커서를 렌더링 하는 데 유용 합니다. 단, 아래에 설명 된 기록 이벤트 api를 사용 하는 경우에는 지정 된 누름 또는 릴리스를 대상으로 하는 것이 가장 정확 합니다.As with the source pose, this is useful for rendering a cursor, although targeting a given press or release will be most accurate if you use the historical event APIs described below.

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

상호 작용 소스 이벤트 처리Handling interaction source events

정확한 기록 포즈 데이터에서 발생 하는 입력 이벤트를 처리 하기 위해 폴링 대신 상호 작용 소스 이벤트를 처리할 수 있습니다.To handle input events as they happen with their accurate historical pose data, you can handle interaction source events instead of polling.

상호 작용 소스 이벤트를 처리 하려면:To handle interaction source events:

  • InteractionManager 입력 이벤트에 등록 합니다.Register for a InteractionManager input event. 관심이 있는 각 상호 작용 이벤트 형식에 대해 구독 해야 합니다.For each type of interaction event that you are interested in, you need to subscribe to it.

    InteractionManager.InteractionSourcePressed += InteractionManager_InteractionSourcePressed;
    
  • 이벤트를 처리 합니다.Handle the event. 상호 작용 이벤트를 구독 한 후에는 해당 하는 경우 콜백을 받게 됩니다.Once you have subscribed to an interaction event, you will get the callback when appropriate. Sourcepressed 예제에서는 소스가 검색 된 후와 릴리스 또는 손실 되기 전에이 상태가 됩니다.In the SourcePressed example, this will be after the source was detected and before it is released or lost.

    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
    }
    

이벤트 처리를 중지 하는 방법How to stop handling an event

이벤트에 더 이상 관심이 없거나 이벤트를 구독 하는 개체를 삭제 하려는 경우에는 이벤트 처리를 중지 해야 합니다.You need to stop handling an event when you're no longer interested in the event or you're destroying the object that has subscribed to the event. 이벤트 처리를 중지 하려면 이벤트의 구독을 취소 합니다.To stop handling the event, you unsubscribe from the event.

InteractionManager.InteractionSourcePressed -= InteractionManager_InteractionSourcePressed;

상호 작용 소스 이벤트 목록List of interaction source events

사용할 수 있는 상호 작용 소스 이벤트는 다음과 같습니다.The available interaction source events are:

  • InteractionSourceDetected (원본이 활성화 됩니다.)InteractionSourceDetected (source becomes active)
  • InteractionSourceLost (비활성 상태가 됨)InteractionSourceLost (becomes inactive)
  • InteractionSourcePressed (누르기, 단추 누르기 또는 "Select" 재생)InteractionSourcePressed (tap, button press, or "Select" uttered)
  • InteractionSourceReleased (탭의 끝, 단추 해제 또는 "Select" 재생 끝)InteractionSourceReleased (end of a tap, button released, or end of "Select" uttered)
  • InteractionSourceUpdated (다른 상태를 이동 하거나 변경 하지 않음)InteractionSourceUpdated (moves or otherwise changes some state)

기록 대상 이벤트는 누름 또는 릴리스와 가장 정확 하 게 일치 합니다.Events for historical targeting poses that most accurately match a press or release

앞에서 설명한 폴링 Api는 앱을 앞으로 예측 하는 포즈를 제공 합니다.The polling APIs described earlier give your app forward-predicted poses. 이러한 예측 된 포즈는 컨트롤러 또는 가상 핸드헬드 개체를 렌더링 하는 데 가장 적합 하지만 다음 두 가지 주요 이유로 이후 포즈는 대상 지정에 적합 하지 않습니다.While those predicted poses are best for rendering the controller or a virtual handheld object, future poses aren't optimal for targeting, for two key reasons:

  • 사용자가 컨트롤러의 단추를 누를 때 시스템에서 누르기를 수신 하기 전에 Bluetooth를 통해 무선 대기 시간이 20 밀리초 정도 소요 될 수 있습니다.When the user presses a button on a controller, there can be about 20 ms of wireless latency over Bluetooth before the system receives the press.
  • 그런 다음 앞으로 예측 하는 포즈를 사용 하는 경우 현재 프레임의 photons 사용자의 눈에 도달 하는 시간을 대상으로 적용 하는 다른 10-20 ms의 전달 예측이 적용 됩니다.Then, if you're using a forward-predicted pose, there would be another 10-20 ms of forward prediction applied to target the time when the current frame's photons will reach the user's eyes.

즉, 폴링을 통해 사용자의 헤드와 손을 모두 사용 하는 경우에는 사용자의 헤드와 30-40를 전달 하는 소스 포즈 또는 헤드가 발생 합니다.This means that polling gives you a source pose or head pose that is 30-40 ms forward from where the user's head and hands actually were back when the press or release happened. HoloLens 손으로 입력 한 경우 무선 전송 지연이 발생 하지 않지만, 누르기를 검색 하는 데 비슷한 처리 지연이 발생 합니다.For HoloLens hand input, while there's no wireless transmission delay, there's a similar processing delay to detect the press.

직접 또는 컨트롤러에 대 한 사용자의 원래 의도에 따라 정확 하 게 대상으로 지정 하려면 해당 InteractionSourcePressed 또는 InteractionSourceReleased 입력 이벤트에서 기록 원본 포즈 또는 head 포즈를 사용 해야 합니다.To accurately target based on the user's original intent for a hand or controller press, you should use the historical source pose or head pose from that InteractionSourcePressed or InteractionSourceReleased input event.

사용자의 헤드 또는 해당 컨트롤러에서 기록 포즈 데이터를 사용 하 여 보도를 대상으로 지정할 수 있습니다.You can target a press or release with historical pose data from the user's head or their controller:

  • 사용자가 gazing 된 항목을 확인 하기 위해 대상 지정 에 사용할 수 있는 제스처 또는 컨트롤러를 누를 때 발생 하는 시점의 헤드입니다.The head pose at the moment in time when a gesture or controller press occurred, which can be used for targeting to determine what the user was gazing at:

    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;
             // ...
         }
    }
    
  • 이동 컨트롤러를 사용 하 여 사용자가 컨트롤러를 가리킨 항목을 확인 하는 데 사용 될 수 있는 시점에 발생 하는 소스입니다.The source pose at the moment in time when a motion controller press occurred, which can be used for targeting to determine what the user was pointing the controller at. 이는 누름이 발생 한 컨트롤러의 상태가 됩니다.This will be the state of the controller that experienced the press. 컨트롤러 자체를 렌더링 하는 경우에는 핸들 포즈 대신 포인터 포즈를 요청 하 여 사용자가 렌더링 된 컨트롤러의 자연 스러운 팁을 고려 하는 대상 광선을 만들 수 있습니다.If you're rendering the controller itself, you can request the pointer pose rather than the grip pose, to shoot the targeting ray from what the user will consider the natural tip of that rendered controller:

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

이벤트 처리기 예Event handlers example

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 v2의 동작 컨트롤러Motion Controllers in MRTK v2

입력 관리자에서 제스처 및 동작 컨트롤러 에 액세스할 수 있습니다.You can access gesture and motion controller from the input Manager.

안내 따르기Follow along with tutorials

보다 자세한 사용자 지정 예제가 포함 된 단계별 자습서는 혼합 현실 아카데미에서 제공 됩니다.Step-by-step tutorials, with more detailed customization examples, are available in the Mixed Reality Academy:

MR 입력 213-동작 컨트롤러MR Input 213 - Motion controller
MR 입력 213-동작 컨트롤러MR Input 213 - Motion controller

다음 개발 검사점Next Development Checkpoint

앞서 소개한 Unity 개발 경험을 팔로 사용할 경우 MRTK 핵심 빌딩 블록을 탐색 하는 것이 좋습니다.If you're following the Unity development journey we've laid out, you're in the midst of exploring the MRTK core building blocks. 여기에서 다음 구성 요소로 진행할 수 있습니다.From here, you can continue to the next building block:

또는 Mixed Reality 플랫폼 기능 및 API로 이동합니다.Or jump to Mixed Reality platform capabilities and APIs:

언제든지 Unity 개발 검사점으로 돌아갈 수 있습니다.You can always go back to the Unity development checkpoints at any time.

참고 항목See also