3D 개체 조작

이 자습서에서는 제스처 및 기본 입력을 사용하여 Unity로 만드는 게임 및 애플리케이션의 사용자 인터페이스를 보강하는 방법을 소개합니다. 손 제스처로 제어되는 3D 커서를 만듭니다. 이 커서를 사용하여 장면에서 개체를 선택하고 3D 공간에서 이동합니다.

이 자습서를 완료하는 데 약 30분이 걸립니다.

최종 결과 다운로드

이 자습서에서 얻은 최종 Unity 프로젝트는 GitHub의 오픈 소스 샘플 리포지토리에서 찾을 수 있습니다. 리포지토리를 복제한 후 다음 단계에 따라 애플리케이션을 실행합니다.

  1. Unity를 시작하고 프로젝트 탭에서 열기를 선택합니다.
  2. 복제된 리포지토리 내에서 Unity\Tutorials\3D 개체 조작 디렉터리로 찾습니다.
  3. 재생 단추(또는 Ctrl+P)를 눌러 장면을 실행합니다.

필수 구성 요소

이 자습서에서는 C# 프로그래밍 언어에 대한 기본적인 친숙함과 Unity 환경에 대한 경험이 있다고 가정합니다. Unity 프로젝트, 장면, 게임 개체 및 스크립트를 만드는 방법을 알고 있다고 가정합니다.

이 자습서를 시작하기 전에 소개 자습서를 완료하는 것이 좋습니다. 여기서 설명하는 Unity용 Project Prague 도구 키트 에 익숙하다고 가정합니다.

1단계 - 장면 준비

  1. 3D 개체 조작 - 장면 준비 자습서에서 얻은 장면으로 이 자습서를 시작합니다. 이 장면에는 마우스로 제어되는 커서가 포함되어 있어 개체를 마우스로 가리키고 "잡아" 공간의 새 위치로 이동할 수 있습니다. 현재 자습서에서는 제스처 및 동작을 위해 마우스를 바꾸고, 손을 사용하여 커서를 제어합니다.

    3D 개체 조작 - 장면 준비 자습서를 완료하거나 다음 지침에 따라 최종 제품을 가져오세요. 3D 개체 조작 - 장면 준비 자습서에서는 Unity용 Project Prague 도구 키트와 관련된 자료를 다루지 않으므로 자유롭게 건너뛸 수 있습니다.

  2. Unity에서 3D 개체 조작 - 장면 준비 자습서에서 만든 최종 프로젝트를 로드합니다. 3D 개체 조작 장면을 재생합니다. 마우스를 사용하여 개체를 잡고 이동할 수 있는지 확인합니다.

    명령 잡기 및 이동

    3단계에서는 손을 사용하여 개체(위 그림의 2번)를 끄는 방법을 알아보고, 4단계에서는 손을 사용하여 개체를 카메라(위 그림의 3번)쪽으로 이동하는 방법을 알아봅니다.

2단계 - 손 커서

  1. 장면에 GesturesManagerUIManager 프리팹을 추가합니다( MicrosoftGesturesToolkit\Prefabs에서). 이러한 프리팹을 사용하여 제스처 서비스와 통신합니다. 자세한 내용은 소개 자습서의 2단계 를 참조하세요.

  2. 손으로 커서를 제어하려면 먼저 손 골격 정보에 액세스해야 합니다. Gestures Service는 손 골격을 계산하고 프레임 단위로 모든 구독 클라이언트에 통신합니다. 장면 의 GesturesManager 게임 개체는 제스처 서비스의 클라이언트 역할을 합니다. GesturesManagerRegisterToSkeleton()UnregisterFromSkeleton() 메서드를 사용하면 손 골격 스트림을 구독하고 구독을 취소할 수 있습니다.

    커서 게임 개체가 활성화될 때마다 손 골격 정보를 받으려고 합니다. OnEnable() 및 OnDisable() 메서드 대한 다음 구현을 커서 스크립트에 추가하세요.

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

  3. 이제 다른 골격 정보와 함께 제공되는 제스처 서비스에서 도착하는 손바닥 위치를 추출합니다. 손바닥 위치를 사용하여 화면에서 커서 위치를 계산 합니다 .

    손 골격은 다음 왼손 좌표계에서 밀리미터 단위로 제공됩니다.

    손 골격 좌표계여기서는 RealSense™ 카메라를 사용하여 좌표계 축을 보여 줍니다. 동일한 좌표계는 Project Prague에서 지원하는 모든 깊이 카메라에 적용됩니다.

    이상적으로, 우리는 우리의 장면에서 메인 카메라가 당신의 눈의 관점에서 손을보고 싶습니다. 우리가 이것을 달성 할 수 있다면 - 화면에 3D 커서의 프로젝션은 자연스럽게 느껴지는 방식으로 손을 따를 것입니다.

    원하는 큐브 뷰를 근사화하기 위해 아래 계수를 사용하여 3D 커서( 주 카메라의 뷰 공간에서 표현하려는)에 손 골격(깊이 카메라의 뷰 공간에 제공됨)을 매핑합니다. Cursor.cs에 다음 공용 멤버를 추가합니다.

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

    이 매핑은 실제로 밀리미터에서 센티미터로 단위 변환인 10의 배에 의해 스케일 다운을 수행합니다. 커서 위치의 동적 범위가 1-10 Unity 단위의 크기 순으로 장면의 개체 크기에 적합하도록 하려면 이 작업을 수행합니다.

    이 준비를 통해 손바닥 위치의 실제 변환을 커서 위치로 계산할 준비가 되었습니다. 커서 스크립트에 GetPalmCameraPosition() 메서드를 추가 합니다 .

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

    GetPalmCameraPosition()에서 SmoothDefaultSkeleton 속성을 사용합니다. 이 속성은 현재 깊이 카메라에서 볼 수 있는 손 골격의 부드러운 버전을 제공합니다. 스무딩은 마지막 몇 프레임 동안 받은 해골의 평균에 의해 달성된다. 평균에 사용되는 프레임 수를 제어할 수 있습니다. 검사기 창에서 GesturesManager를 검사하고 부드러운 이동 평균 창 크기 필드를 수정합니다.

    골격PalmPosition 속성은 손 중앙의 위치에 해당합니다.

    팜 위치 랜드마크

  4. GetCursorScreenPosition()을 다음 내용으로 바꿉니다.

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

  5. 제스처 서비스가 실행 중인지 확인합니다. 장면을 재생하고 깊이 카메라 앞에 손을 가져옵니다. 손을 이동하여 커서를 제어할 수 있어야 합니다.

3단계 - 제스처를 사용하여 개체 잡기 및 이동

이제 제스처를 도입하고 이를 사용하여 커서를 트리거하여 "잡기 모드"로 전환하고 그대로 둡니다. 잡기 모드에서 잡은 개체는 커서를 따라(손을 따라) 새 위치로 이동할 수 있습니다.

  1. 프로젝트 창의 MicrosoftGesturesToolkit\Prefabs 아래에서 GestureTrigger 프리팹을 찾습니다. 계층 구조 창으로 끌어서 놓아 장면에 새 GestureTrigger 게임 개체를 만듭니다.

  2. 검사기 창에서 GestureTrigger 게임 개체를 검사하고, XAML 제스처 라디오 단추를 선택하고, 제스처 XAML 섹션을 확장하고, 다음 제스처 정의에 붙여넣습니다.

    <Gesture Name="GrabReleaseGesture"
             xmlns="http://schemas.microsoft.com/gestures/2015/xaml">
        <Gesture.Segments>
            <IdleGestureSegment Name="Idle" />
            <HandPose Name="InitSpreadPose">
                <PalmPose Context="{AnyHand}" Direction="Forward|Down" />
                <FingerPose Context="Index, Middle, Ring, Pinky" Flexion="Open" />
            </HandPose>
            <HandPose Name="GrabPose">
                <PalmPose Context="{AnyHand}" />
                <FingerPose Context="Index, Middle, Ring, Pinky" Flexion="Folded" />
            </HandPose>
            <HandPose Name="FinalSpreadPose">
                <PalmPose Context="{AnyHand}" />
                <FingerPose Context="Index, Middle, Ring, Pinky" Flexion="Open" />
            </HandPose>
        </Gesture.Segments>
        <Gesture.SegmentsConnections>
            <SegmentConnections From="Idle" To="Idle, InitSpreadPose" />
            <SegmentConnections From="InitSpreadPose" To="GrabPose" />
            <SegmentConnections From="GrabPose" To="FinalSpreadPose" />
            <SegmentConnections From="FinalSpreadPose" To="Idle" />
        </Gesture.SegmentsConnections>
    </Gesture>
    

    완료되면 GestureTrigger검사기 보기는 다음과 같이 표시됩니다.

    GrabReleaseGesture 제스처 정의

    제스처의 XAML 표현을 생성하려면 C# 제스처 개체 를 만들고 ToXaml() 메서드를 호출합니다. C#에서 제스처를 만드는 방법을 알아보려면 개요 페이지를 방문하세요.

    GrabReleaseGesture는 아래 상태 컴퓨터에 표시된 것처럼 3개의 포즈로 구성됩니다.

    GrabReleaseGesture

    상태 시스템으로서 제스처의 개념에 대해 자세히 알아보려면 개요 페이지를 방문하세요.

  3. 다음과 같은 방식으로 GrabReleaseGesture 를 사용하려고 합니다.

    • GrabPose 검색으로 인해 커서가 잡기 모드로 전환됩니다. 즉, StartGrab()을 트리거해야 합니다.
    • 유휴 검색을 사용하면 커서가 잡기 모드를 벗어나게 됩니다. 즉, StopGrab()을 트리거해야 합니다.

    참고

    유휴 상태는 모든 제스처의 초기 상태입니다. 사용자가 완료하기 위해 제스처를 수행하거나 실행 중간에 제스처를 포기할 때마다 상태 컴퓨터는 유휴 상태로 돌아갑니다.

    검사기 창에서 GestureTrigger 게임 개체를 검사하고 제스처 세그먼트 추가 이벤트 단추를두 번 누릅니다. 이렇게 하면 세그먼트 #1 및 세그먼트 #2의 두 개의 새 UI(사용자 인터페이스) 섹션이 생성됩니다.

     - In the **Segment #1** drop down list, select the **GrabPose** (1), then click the **+** sign in the **On Trigger ()** pane (2). Drag the **Cursor** object to the **None (Object)** box (3) and select the **Cursor → StartGrab()** method from the **No Function** drop-down list (4):
    
     ![GrabPose gesture trigger](Images/UnityGrabGestureTrigger.png)
    
     - In the **Segment #2** drop down list, select the **Idle** (1), then click the **+** sign in the **On Trigger ()** pane (2). Drag the **Cursor** object to the **None (Object)** box (3) and select the **Cursor → StopGrab()** method from the **No Function** drop-down list (4):
    
     ![Idle gesture trigger](Images/UnityIdleGestureTrigger.png)
    
  4. 장면을 실행합니다. 이 단계에서 추가한 기능을 테스트합니다.

    • 커서가 있는 개체 위로 마우스를 가져다 놓습니다.
    • 주먹으로 손을 클린칭하여 잡아,
    • 개체를 새 위치로 이동
    • 손가락을 떼어 개체를 놓습니다.

4단계 - 개체를 멀리 또는 카메라쪽으로 이동

이 단계에서는 잡은 개체가 방사형 방향으로도 이동할 수 있도록 합니다.

  1. Cursor.cs에 다음 프라이빗 멤버를 추가합니다.

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

    개체를 잡을 때마다 이 멤버를 초기화해야 합니다. 이렇게 하려면 StartGrab() 메서드의 끝에 다음 줄을 추가합니다.

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

  2. Cursor.cs에서 GetCursorDistanceCoefficient() 메서드의 내용을 다음으로 바꿉니다.

    경고

    찾으시는 샘플이 이동된 것으로 보입니다. 현재 이 문제를 해결하기 위해 노력하고 있습니다.

  3. 장면을 실행해 보세요. 개체를 잡고 손을 깊이 카메라쪽으로 또는 멀리 이동합니다. 장면의 개체는 가상 장면에서 각각 이동하여 사용자의 손을 따라야 합니다.

    손을 깊이 카메라에 너무 가까이 두지 마십시오. 카메라에는 검소 한 모양의 시야가 있습니다 - 손을 가까이 가져가면 감지 가능한 영역이 작아져 장면의 개체를 조작할 수 있는 동작 범위가 줄어듭니다.