일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 연습
- 앱 배포
- 오큘러스
- 포트폴리오
- meta xr
- 드래곤 플라이트 모작
- 길건너 친구들
- CGV
- XR
- VR
- 개발
- Oculus
- 유니티 GUI
- 유니티
- input system
- 드래곤 플라이트
- 멀티플레이
- OVR
- 가상현실
- 팀프로젝트
- HAPTIC
- 모작
- 팀 프로젝트
- 유니티 Json 데이터 연동
- 개발일지
- 유니티 UI
- ChatGPT
- meta
- 오브젝트 풀링
- Photon Fusion
- Today
- Total
EasyCastleUNITY
유니티에서의 Meta Body Tracking 본문
Meta XR SDK의 71버전을 기준으로 작성합니다.
https://developers.meta.com/horizon/documentation/unity/move-body-tracking
위 링크에 내용을 기반으로 작성되었습니다.
통합 Body Tracking
학습 목적
이 페이지의 학습을 완료한 후 개발자는 아래의 사항을 수행할 수 있어야 합니다.
1. Body Tracking을 지원할 수 있는 프로젝트를 구성할 수 있다.
참고 : 이 단계를 따르기 전에 Movement SDK 시작하기 의 필수 구성요소를 확인하세요.
Body Tracking 추가
VR에 맞게 프로젝트를 구성한 후 아래 단계를 따라라.
1. Scene에 OVRCameraRig 프리팹이 있는지 확인하라. 해당 프리팹은 Packages/com.meta.xr.sdk.core/Prefabs/OvrCameraRig.prefab 에 있다.
2. OVRCameraRig 객체에서 OVRManager 컴포넌트로 이동한다.
3. Target Devices를 선택한다.
4. Quest Features > General 로 스크롤 다운한다.
5. 만약 여러분이 Hand Tracking을 원한다면, Hand Tracking Support 를 하기 위해 Controllers and Hands 를 선택
6. General 아래에, Body Tracking Support를 선택하였는지 확인. 이 보기가 보이지 않는다면 General 을 클릭
- IOBT를 사용하려면 Movement Tracking 섹션에서 Body Tracking Fidelity 에 High를 선택한다. IOBT는 API의 요구 사항이 아닌 제안된 충실도 모드이다. 자세한 내용은 Troubleshooting Body Tracking을 참고
- Full Body를 사용하려면 Movement Tracking 섹션에서 Body Tracking Joint Set 을 선택
7. Eye와 Face Tracking을 원한다면 6번과 동일한 설정을 적용한다. OVRManager는 필요한 추적 기술에 대해 선택해야 하는 Permission Request On Startup 이 있다는 점에 유의해야 한다.
8. 프로젝트가 Face, Eye Tracking이나 Hand Tracking 에 의존하는 경우 HMD에서 이러한 기능이 활성화되어 있는지 확인하세요. 이는 일반적으로 장치 설정의 일부이지만 Settings > Movement Tracking 을 클릭하여 설정을 확인하거나 변경할 수 있다.
9. Project Setup Tool에서 진단한 모든 문제를 해결한다. Unity의 메뉴에서 Edit > Project Settings > Meta XR 로 이동하여 Project Setup Tool에 액세스한다.
10. 플랫폼을 선택한다.
11. 문제가 있다면 Fix All 을 선택한다. 자세한 내용은 Use Project Setup Tool 를 참고
Body Tracking을 하기 위한 캐릭터 세팅
학습 목적
이 섹션을 완료한 이후 개발자는 아래의 사항들을 할 줄 알아야 한다.
- Unity의 Mecanim Rig 관계를 이해한다.
- 캐릭터 모델에 Body Tracking을 적용할 수 있다.
- 변형 논리(deformation logic)를 적용하여 캐릭터 Mesh에 맞추어 Bone을 조정하여 움직임이 자연스럽게 보이도록 할 수 있다.
이 섹션에서는 캐릭터 에셋을 가져오는 방법, Unity Mecanim Humanoid로 리깅하는 방법, 그리고 Body Tracking을 활성화하는 방법에 대해 알아본다.
Meta는 84개의 Bone으로 구성된 독자적인 Body Tracking Skeleton을 사용한다. (부록 A 참조) 이 Skeleton은 캐릭터 리그가 아닌 human skeleton에 해당된다. Unity 내에서 Body Tracking API는 Unity GameObject에 연결된 Component들로 실행되는 일련의 스크립트를 통해 액세스한다.
Body Tracking Support가 활성화된 경우, OVRBody 스크립트는 Tracking 공간에서 업데이트된 Body Pose(위치 및 회전) 데이터를 폴링한다. 이 Pose 데이터는 직접 해석하여 사용할 수 있고, figure에 표시된 것처럼 Unity Mecanim Humanoid에 매핑할 수도 있다. Unity가 Skeleton의 각 Bone에 사용하는 명명 규칙은 Meta Body Tracking Skeleton과 동일하지 않으므로 Tracking Skeleton에서 Unity Mecanim Humanoid로 매핑해야 한다.
Mecanim Humanoid를 가지는 rig와 Character 가져오기
캐릭터와 Mecanim Humanoid로서의 리그를 가져오기 위해 아래와 같은 단계를 따라라.
1. Unity Project에 커스텀 캐릭터를 asset의 형태로 가져온다.
2. third-party model asset (target rig)를 클릭한다.
3. Unity Inspector 탭에서 Rig 탭으로 이동한다.
4. Animation Type 옆에 있는 Humanoid 를 클릭한다.
5. Apply 를 클릭한다.
6. 이제 Configure 버튼을 볼 수 있다. 이 버튼을 클릭하여 캐릭터의 시뮬레이션된 Bone 대부분이 Unity의 HumanBodyBones 에 매핑되었는지 확인한다. 턱이나 눈과 같은 특정 Bone들은 다리, 척추, 팔의 Bone에 비해 Body를 애니메이션화 하는데 필요하지 않을 수 있다.
7. (선택사항) Scene에 가져올 때 캐릭터가 너무 작거나 너무 크게 보이면 Asset의 Model 탭에서 Scale Factor를 다른 값으로 수정한 다음 Apply를 클릭한다. Body Tracking이 Joints Transform을 수정할 때 Scene에서 캐릭터의 배율을 변경하면 만족스럽지 못한 결과가 발생한 가능성이 있다.
자세한 내용은 Unity 설명서를 참조. 아래의 사진은 일반적인 Humanoid이다.
8. Muscles & Settings 로 가서 마지막까지 스크롤하여 Translation DoF 가 활성화되어 있는지 확인하자. 활성화되어 있지 않으면 활성하한 다음 그 아래에 있는 Apply 버튼을 클릭하세요.
커스텀 타겟 캐릭터는 Humanoid로 가져왔고, 각각의 Bone은 HumanBodyBone 스크립트의 enum 값과 연결되어 있다.
캐릭터에 대한 Tracking 활성화
다음 단계는 Service에서 Body Tracking Pose를 읽고 캐릭터에 적용하는 스크립트인 컴포넌트를 캐릭터에 추가하는 것이다.
1. 캐릭터의 모델이나 프리팹을 Scene으로 드래그한다. 모델에는 아바타가 할당된 애니메이터 Component가 있어야한다. 그렇지 않은 경우, 이전 섹션의 단계를 따르고 애니메이션 유형을 Humanoid로 변경한다.
2. 모델을 마우스 우클릭한 다음 Movement Samples > Body Tracking > Animation Rigging Retargeting(upper body)(constraints)를 선택한다. Full Body 캐릭터의 경우, Movement Samples > Body Tracking > Animation Rigging Retargeting(full body)(contraints)를 사용한다. 제약조건이 있는 옵션은 다음을 추가하여 캐릭터의 모양을 개선한다.
- Rig 아래에 있는 FullBodyDeformationConstraint (Animation Rigging)을 사용하여 캐릭터 비율을 유지한다.
3. 이전 단계에서 추가한 컴포넌트에서 다음 옵션을 확인한다.
- Generative Legs의 경우, 캐릭터의 Provided Skeleton Type이 OVRBody에서 Full Body 로 설정되어 있는지 확인해야 한다. 또한 OVRManager의 Body Tracking Joint Set 은 모든 캐릭터에서 전체 신체 관절을 표현하기 위해 Movement Tracking 섹션에서 Full Body 로 설정되어 있어야 한다. IOBT의 경우, OVRManager의 Movement Tracking 섹션에서 Body Tracking Fidelity 가 High로 설정되어 있는지 확인해아 한다. IOBT는 API의 요구사항이 아닌 권장 충실도 모드입니다. 자세한 내용은 Troubleshooting Body Tracking에서 확인
- 이전 단계에서 추가한 Retargeting Layer에 다음 사항이 있는지 확인한다.
- Skeleton Type이 Full Body로 설정
- Tracking By Proxy가 체크되어 있다.
- Blend Left Hand, Blend Right Hand, Correct Bones, Correct Left Hand, Correct Right Hand 리타겟팅 프로세서는 Retargeting Processors array에 위치하고 할당된다. 이것들은 Packages/com.meta.movement/Shared/RetargetingProcessors 에서 찾을 수 있다.
- Blend Hand Processor들은 추적된 위치로 편향하여 손이 몸 앞에 있을 때 정확한 위치를 유지하려고 노력한다. 그러나 손이 머리 위나 몸의 옆이나 뒤로 움직일 때 프로세서는 캐릭터 Humanoid Constraints를 유지하는 쪽으로 편향된다.
캐릭터 외관 개선
Unity Mecanim Humanoid는 Bone에서 Bone으로 움직임을 전송할 수 있는 명명 규칙을 제공하지만 캐릭터가 여러 가지 이유로 움직이려고 할 때 문제가 발생할 수 있다.
- 실제 Rig는 Mesh의 앞이나 뒤쪽에 위치할 수 있다.
- Rig의 비율이 일반적인 인간의 비율과 일치하지 않을 수 있다.
- 추적되는 사람은 등장인물과 비율이 상당히 다를 수 있다. (ex: 어깨가 넓은 경우)
따라서 움직임이 자연스럽게 보이도록 캐릭터를 조정해야 하는 경우가 많다. Meta는 캐릭터가 움직이는 동안 더 자연스럽게 보이도록 하는 변형 제약 조건(deformation constraints)을 제공했다. 아래의 gif는 파란색 로봇 예제를 자연스럽게 보이도록 하기 위해 따른 순서를 보여준다. 따라야 할 정확한 단계는 창작 의도에 따라 달라진다. 예를 들어, 캐릭터가 굽은 자세로 걷게 하거나 좋은 자세를 취하게 하기를 원할 수 있다. gif는 원래 비율을 유지하면서 파란색 로봇으로 리타겟팅 하는 방법을 나타내고 있다.
1. Base Retargeting (기본 리타겟팅) : 이 단계에서는 캐릭터와 Body Tracking에서 수신한 데이터 간의 비율 차이를 고려하지 않고 리타게팅된 캐릭터에 Body Tracking 정보를 적용한다. 여기에서는 캐릭터의 Mesh에 Skinning된 Mecanim Humanoid의 Bone 변형을 수정하여 회전과 위치에 영향을 미치는 작업이 포함된다.
2. Adjust(조정) : 캐릭터는 캐릭터가 조작된 방식에 따라 Tracking 결과에 적용되는 추가 회전 조정이 필요할 수 있다. 조정을 수정하려면 "Adjust" 배열을 수정해야 한다. "Adjust" 배열은 캐릭터에 대한 Tracking 활성화 섹션의 2단계에서 설명한 원클릭으로 캐릭터에 추가된 Retargeting Layer 스크립트의 일부이다. 기본적으로 원클릭 설정은 자동으로 계산되는 척추와 어깨에 대한 조정을 추가한다. 이러한 회전의 축이나 값으로 인해 적용 시 모델이 이상하다면 조정을 수정하거나 제거해야 한다.
3. Base Deformation (기본 변형) : 이 단계에서는 많은 Skeleton에 공통적인 몇 가지 기본 제약을 추가한다. 변형 제약 스크립트는 원클릭 설정이 적용된 캐릭터의 Rig 구조에 추가되었다. 원클릭을 적용한 캐릭터의 Rig GameObject 아래에 있는 프로젝트 탐색기에서 이를 볼 수 있어야 한다. 아래의 이미지에서 FullBodyDeformationConstraint 는 원클릭으로 추가되었다.
Deformation Settings(변형 설정)
변형 설정을 사용하려면 Body Tracking으로 구동되는 캐릭터의 Skeleton과 앞서 설명한 Body Tracking Skeleton 사이에서 균형을 맞추어야 한다. 여기에는 창작 의도에 대한 이해가 필요하다. 예를 들어, 캘기터는 구부정하게 서 있는 사람을 Tracking하는 Tracking Skeleton과 함께 구부정하게 서 있는 늙은 마법사를 나타낼 수 있다. 이 상황에서는 추적된 사람에서 멀어지고( away from the tracked person ) 캐릭터 Skeleton 쪽으로 기울어지게 하여 세번째 사람이 자세가 좋은 사람이 걷는 것이 아닌 구부정한 마법사가 걷는 모습을 볼 수 있도록 해야 한다.
1. Spine Translation Correction Type(척추 변환 수정 유형) : 이 설정은 엉덩이와 머리 위치의 관계가 추적된 인간 위치와 매우 다를 수 있기 때문에 필요하다. 다리에 비해 몸통이 큰 캐릭터를 생각해 보자. 머리 위치가 정확하기를 원하고 머리 위치에 따라 캐릭터의 비율을 조정해야 할까? 이렇게 하면 "Accurate Head" 를 선택하면 머리 위치에 따라 캐릭터의 크기가 조정되어 엉덩이가 올바른 위치에 있지 않을 수 있다. 반면에 캐릭터의 엉덩이 위치가 더 중요하면 "Accurate Hips" 를 선택하면 머리 위치가 실제 머리보다 높아질 수 있다. 둘 다 원하는 경우 추적된 위치와 일치하도록 몸통 비율 중 일부가 손상된다. 이 설명에 대한 한 가지 주의 사항은 전신(Full Body)을 사용할 때 항상 올바른 발 위치를 사용한 다음 머리/엉덩이 위치에 따라 조정해야 한다는 것이다.
2. Spine Alignment (척추 정렬): 이 설정을 사용하면 척추의 실제 추적 위치와 척추를 엉덩이 위에 수직으로 정렬하는 것 사이의 균형을 맞출 수 있다. 많은 캐릭터는 엉덩이 위에 완벽하게 곧은 척추가 정렬되어 있다고 가정하도록 제작되었다. 가중치 1은 SpineLower/SpineUpper/Chest Bone을 엉덩이에 정렬하고 ,가중치 0은 SpineLower/SpineUpper/Chest Bone을 추적된 척추 위치에 정렬한다. 이것은 Rest Pose의 시작 위치에 적용된다. 모든 값이 1로 설정되어 있어도 캐릭터는 여전히 구부릴 수 있지만 캐릭터의 Rest Pose(직선일 가능성 있음)와 유사한 척추로 구부릴 수 있음을 의미한다. Unity Mecanim Humanoid는 매핑되지 않은 Bone(Unity Skeleton에 Bone이 많은 경우) 을 자동으로 보간하고 Bone이 적은 경우 정확하지 않을 수 있지만 최소한 아래쪽 척추가 매핑되어 있으면 작동해야 한다. Bone이 적은 경우, 이건 동작해야 한다. 추적 품질은 낮추는 대신 원래 Spine Bone 로컬 위치를 적용하려면 "Original Spine Positions Weight" 의 가중치를 늘려야 된다.
3. Shoulder Interpolation(어깨 보간) : 추적하는 사람의 어깨 너비가 캐릭터와 크게 다를 경우, 정확한 어깨 위치를 유지하는 것과 캐릭터의 모양과 보여지는 모양새 사이에서 균형을 맞추어야 한다. 예를 들어, 추적하는 사람의 어깨가 넓고 스타일 적으로 우앙한 발레리나를 표현하려는 경우, 어깨의 정확한 위치 지정보다 캐릭터를 유지하는 쪽으로 오차를 두는 것이 좋습니다.
가중치 1은 추적된 어깨 위치를 무시하고 어깨를 원래 가슴에 대한 로컬 위치에 배치한다. 가중치 0은 어깨를 추적된 위치에 배치한다.
Retargeting Layer에서 ArmatureCorlectBones의 리타겟팅 프로세서에는 제한된 근육 공간 회전이 잘못된 경우 업데이트할 수 있는 Shoulder Correction Weight Late Update가 있습니다. 가중치 1은 근육 공간에 의해 제한 되지 않고 리타게팅된 어깨 회전을 사용하는 반면, 가중치 0은 근육 공간에 의 제한된 어깨 회전을 사용한다.
1. 팔과 손 보간 : 팔을 배치하는 데도 비슷한 트레이드 오프가 있다. 가중치 1은 캐릭터의 비율을 사용하여 팔(위팔과 아래팔 Bone)을 배치한다. 가중치 0은 팔을 추적된 위치에 배치한다. 손 가중치도 같다. 예를 들오, 추적된 사람에 비해 캐릭터의 팔이 정말 짧은 경우 다음 가중치를 사용하여 조정할 수 있다.
2. 다리 정렬 : 다리 가중치를 사용하여 추적된 위치(가중치 0)과 비율이 적용되고 정렬된 후의 위치(가중치 1)사이에 다리를 정렬한다.
3. 발 정렬 : Tracking Skeleton은 발 아치가 약간 있다. 이로 인해 캐릭터의 발가락이 위로 들어올려질 수 있다. 발 정렬 가중치에 대한 가중치 1은 추적된 수직회전을 무시하고 발을 발가락 쪽으로 회전한다. 가중치 0은 추적된 발 회전을 변경하지 않는다. 비율을 적용할 때 발가락 위치가 잘못되어 보이면 발가락 가중치를 조정할 수 있다. 발가락 가중치에 대한 가중치 1은 발가락을 발에 대한 로컬 위치에 배치한다. 발가락 가중치에 대한 가중치 0은 발가락을 추적된 위치에 배치한다.
Retargeting Processor(리타겟팅 프로세서)
리타겟팅 프로세서는 LateUpdate 단계에서 데이터를 저장하고 명령을 실행하여 Unity의 Humanoid 근육 공간의 제약을 넘어서는 최종 리타게팅 출력을 조정하는 Scriptable Object이다. 여기에는 손가락의 위치 및 회전 수정과 잠재적으로 캐릭터의 다른 Bone이 포함된다. 이러한 프로세서는 기본 RetargetingProcessor.cs 스크립트를 상속한다.
- Blend Hands Processor : 이 프로세서는 추적된 손 데이터를 기반으로 머리 시야 내에 들어올 때 손의 최적 배치를 결정한다. 보이는 손에 대해 IK 타겟을 정확하게 설정하고 가려진 손에 대해 팔 회전을 유지함으로써 이 접근 방식은 리타겟팅된 바디 추적을 통해 현실적인 손 위치와 보존된 팔 움직임을 모두 보장한다. 가중치 1은 이 프로세서가 IK프로세서 가중치를 적극적으로 수정하고, 가중치 0은 IK 프로세서 가중치를 수정하지 않음을 의미한다.
- Correct Bones Processor : 이 프로세서는 애니메이션 리깅 스택에 있는 Pose Capture constraints 의 정보를 사용하여 근육 공간에 의해 제한되지 않도록 Humanoid의 모든 Bone의 위치와 회전을 업데이트한다. 가중치 1은 근육 공간에 의해 제한되지 않는 애니메이션 리깅의 위치 및 회전 오프셋을 적용하고, 가중치 0은 업데이트를 적용하지 않는다.
- Correct Hands Processor : 이 프로세서는 IK 알고리즘을 사용하여 팔의 회전을 조작하여 손이 지정된 IK 대상의 위치에 도달하도록 업데이트한다. 가중치 1은 선택한 IK 알고리즘을 완전히 실행하고, 가중치 0은 팔과 손의 위치에 수정 사항이 적용되지 않습니다.
- Remaining Touch-ups : 모델이 여전히 제대로 보이지 않으면 부록 C - 고급 Body Contrasints에 설명된 고급 조정을 시도할 수 있다. 캐릭터가 캐릭터를 좌석에 고정하고 VR 환경이 평평하지 않은 경우 (ex: 계단) 추적을 무시하려는 경우에도 유용할 수 있다.
사용자와 일치하도록 캐릭터 키 조정
이 섹션에서 선택한 옵션에 따라 캐릭터가 사용자의 키에 따라 변형될 수 있다. 따라서 관절 주변 영역이 Mesh에 충분히 영향을 미쳐 키가 다른 사용자를 허용하도록 하여 캐릭터가 다양한 키에 적응할 수 있도록 해야 한다. 부록 C의 캐릭터 키 구성을 참조하자.
캐릭터에 애니메이션 추가하기
이 섹션을 완료한 후 개발자는 다음 사항들을 알아야 한다.
- Body Tracking이 키 프레임 애니메이션과 호환된다는 것을 이해한다.
- 이러한 지식을 적용하여 키 프레임 애니메이션을 가져오고 애니메이션을 전체 리그 또는 리그의 일부 (ex: 다리) 에만 적용할 수 있다.
이 섹션에서는 Body Tracking을 사용하여 키 프레임 애니메이션을 가져와 전체 리그나 리그의 일부 (ex: 다리) 에만 적용하는 방법을 자세히 설명한다.
캐릭터에 키 프레임 애니메이션을 추가하고 싶은 다양한 시나리오가 있다. 예를 들어, 애니메이션은 컨트롤러를 사용하여 캐릭터를 구동할 때 Body Tracking 상태에서 "애니메이션 실행" 상태로 변경하는 데 사용할 수 있다. (Body Tracking과 함께 Locomotion 컨트롤러를 사용하는 방법에 대한 자세한 내용은 다음 섹션을 참조)
MovementRetargeting.unity Scene에는 파도 애니메이션을 사용하여 신체 일부를 움직이는 예가 나와 있다.
캐릭터에 애니메이션을 추가하려면:
1. 추가하고 싶은 애니메이션을 다운로드하거나 직접 만든다.
2. 캐릭터에 아바타가 할당된 Animator 컴포넌트가 있는지 확인한다.
3. 애니메이션을 재생할 시기를 제어하고 Animator의 Controller 필드에 할당할 Animator Controller를 추가한다. 메타가 제공한 예제 씬의 WaveAnimController에서 이것에 대한 예시가 있다.
4. 애니메이션이 작동하는 데 사용할 세 개의 마스크를 정의한다.
- Animation Mask : 이것은 애니메이션이 적용되는 마스크이다. Meta의 예시에서 JustRightArm이 이것이다. 이 마스크는 애니메이션 컨트롤러의 WaveAnimation 레이어의 속성으로 구성된다.
- Retargeting Mask : 리타겟팅일 적용되는 마스크이다. Meta의 예시에서 ExcludeRightArm이며, RetargetingConstraint의 AvatarMaskComp 필드에 적용된다.
- Full Body Mask : 애니메이션이 꺼지면 이 마스크는 리타겟팅이 캐릭터의 몸 전체에 다시 영향을 미칠 수 있음을 나타낸다. 이건 캐릭터의 Rig에 있는 RetargetingConstraint의 AvatarMaskComp에 적용되어야 한다.
바디 트래킹은 설정하는 원클릭 스크립트에는 Animator 구성 요소가 필요하며 Humanoid 애니메이션과 함께 사용할 수 있다. 기존 프로젝트로 가져오는 경우 캐릭터에 이미 애니메이션과 애니메이션 컨트롤러가 있을 수 있다. 아래는 리타겟팅과 통합되는 방법에 대한 참고 사항이다.
- Animation Masks : 애니메이션이 같은 관절에서 재생되는 동안 리타겟팅이 영향을 미치지 않아야 하는 신체부위에 대한 애니메이션 마스크를 정의한다. 애니메이션이 재생을 멈추면 다른 마스크를 사용하여 리타겟팅이 모든 관절에 영향을 미칠 수 있도록 한다. 우리는 리타겟팅 샘플에서 웨이브 애니메이션을 구현하고 재생 중인 애니메이션에 해당하는 마스크를 사용한다. 캐릭터에 애니메이션 추가를 참조하세요.
- Animator states : 애니메이션 컨트롤러에서 애니메이션으로의 전환을 허용하는 상태를 정의할 수 있다. 예를 들어, 컨트롤러가 캐릭터에서 애니메이션을 재생하지 않고 대신 Body Tracking 이 캐릭터에 영향을 미치는 Idle 상태에서 결정할 수 있다. 그런 다음 애니메이션 상태 (ex: 걷기, 달리기) 로 전환할 때 애니메이션을 재생하도록 허용하고 마스킹을 사용하여 애니메이션과 관련된 관절에서 리타겟팅을 방지한다.
참고 : 런타임에 캐릭터에 리타겟팅을 추가할 수 있는 AddComponetsRuntime.cs 스크립트가 있다. 해당 스크립트의 메서드 SetUpCharacterForRetargeting 및 SetUpCharacterForAnimationRiggingRetargeting 을 참조
Locomotion 컨트롤러 추가
이 섹션을 완료한 후 개발자는 다음을 수행할 수 있어야 한다.
- 컨트롤러 기반 애니메이션과 Body Tracking의 필요성을 이해한다.
- Body Tracking과 함께 컨트롤러 기반 애니메이션을 허용하는 이동 컨트롤러를 구현할 수 있다.
이 섹션에서는 Body Tracking과 함께 컨트롤러 기반 애니메이션을 허용하는 이동 컨트롤러를 구현하는 방법에 대해 알아본다.
Body Tracking을 통한 이동에 유용한 디자인 패턴은 가상 세계에서 컨트롤러 기반 입력을 사용하여 탐색한 다음 특정 컨텍스트나 위치 내에서 Body Tracking을 사용하는 것이다. 컨트롤러 기반 탐색 중에 캐릭터는 일반적으로 가상 세계에서 캐릭터의 속도(ex: 걷기, 조깅, 달리기)에 따라 애니메이션화 된다. 플레이어 컨트롤러를 구현하는 데는 다양한 옵션이 있으며 온라인에서 튜토리얼을 쉽게 이용할 수 있습니다. 그러나 컨트롤러 기반 애니메이션과 Body Tracking을 혼합하기 위해서는 솔루션이 다음과 같은 문제를 해결해야 한다.
- 지면과 물체의 상호작용이 원활히 작동하도록 충돌체를 배치한다.
- PlayerController를 가상 세계에서 올바르게 이동하고 카메라를 1P 시점에 맞춰 유지한다.
- 컨트롤러 구동 애니메이션을 재정의하여 Body Tracking을 허용하는 시기를 결정한다.
자세한 내용을 살펴보기 전이 몇 가지 핵심 개념을 이해하는 것이 중요하다.
- World / Absolute space vs Local / Tracking space : 사용자가 절대 공간에서 점프하거나 움직일 때 (메타가 제공한 샘플에서는 왼쪽 조이스틱 사용) PlayerController의 움직임. 이 움직임은 게임 세계를 통해 local body-tracked tarcked space (OvrCameraRig) 의 위치를 이동한다. 사용자가 현실 세계에서 움직일 때 XR 하드웨어는 그 움직임을 감지하고 사용자의 Body는 추적 공간 내에서 움직인다. 추적 공간을 회전할 수 있으며 (메타가 제공한 샘플에서는 오른쪽 컨트롤러 조이스틱에서 좌우로), 추적 공간의 원점을 중심으로 하는 것이 아니라 추적 공간에서 플레이어의 위치를 중심으로 회전한다.
- PlayerController - 사용자가 캐릭터를 움직이기 위해 제어하는 GameObject이다. PlayerController는 UserInput 벡터가 조작될 때 애니메이션 캐릭터를 이동(또는 순간이동) 한다. Motion은 Rigidbody 컴포넌트의 속도와 함께 Unity의 물리 시스템에 의해 관리된다. 이동 중 지면과의 충돌도 충돌체를 사용하여 구현된 Unity의 물리 시스템을 사용한다. Sphere Collider는 사용자의 실제 지상 위치 추정에 따라 움직인다.
- Unity 입력에는 입력을 수신하기 위한 Legacy Input API가 있다. (ex: Input.GetAxis..) 이는 MovementLocomotion 샘플의 UnityInputBinding 컴포넌트 (PlayerController 객체 > Controls 개체) 에서 수평 및 수직 입력을 수신하는 데 활용되지만 다른 형태의 입력도 쉽게 사용할 수 있다.
- Meta Quest Controller의 입력은 Meta의 OVRInput API에서 읽을 수 있다.
메타는 원리를 설명하기 위해 기본 XR 운동 컨트롤러를 구현하는 샘플을 제공했다. 운동 컨트롤러를 설정하는 기본 단계는 다음과 같다.
1. 컨트롤러의 변환 (위치 및 회전) 역할을 할 게임 오브젝트를 만든다. 캐릭터를 움직이기 위해 입력과 물리를 처리하는 스크립트가 있어야한다. Meta에서 제공하는 스크립트는 MovementSDKLocomotion이라고 하며 물리를 위한 Rigidbody가 필요하다.
2. 컨트롤러를 따라야 하는 캐릭터의 스킨 메쉬(사용자에게 보이는 몸체)를 추가합니다. 메시 본체를 컨트롤러에 연결하는 가장 간단한 방법은 메시 개체를 컨트롤러(1단계에서 만든 개체)의 하위 개체로 설정하는 것입니다. 이전 섹션에서는 신체 추적을 사용하여 메시의 애니메이터를 조작하는 방법을 설명했습니다. 우리의 예에서는 캐릭터 메시가 컨트롤러의 계층 구조에 없더라도 컨트롤러로 이동하는 TransformsFollowMe라는 스크립트를 사용합니다.
3. 캐릭터 컨트롤러가 움직일 때 움직임 애니메이션을 트리거하는 기능을 추가합니다. 샘플에서는 예상되는 이동 및 점프 애니메이션과 함께 작동하도록 설계된 AnimationHooks 스크립트를 사용하여 애니메이션을 트리거합니다. 참고: 예제 스크립트는 Auto Assign From Children이 true로 설정된 경우 AnimationHooks 구성 요소가 있는 객체의 하위인 메시 애니메이터에 애니메이션 트리거를 전달합니다. 이동 애니메이션 적용의 일부로 RetargetingAnimationConstraint 구성 요소(신체 추적 포즈를 캐릭터 애니메이터에 적용)는 애니메이션 중에 적어도 부분적으로 덮어써야 합니다. 그렇지 않으면 신체 추적이 의도한 이동 애니메이션을 재정의합니다. 이를 올바르게 수행하려면 RetargetingLayer의 Rig 하위 개체에 특수 리그 제약 조건 개체를 추가해야 합니다 :
- Rig의 첫 번째 요소로 CaptureAnimationConstraint를 추가합니다. 이를 수행하려면 프리팹의 포장을 풀어야 할 수도 있습니다. 이 RigConstraint는 RetargetingConstraint에 의해 신체 추적이 적용되기 전에 애니메이션 신체 포즈(AnimationHooks에 의해 트리거됨)를 기억합니다.
- Rig 객체의 새로운 마지막 하위 객체에 PlaybackAnimationConstraint를 추가합니다. 이 스크립트는 RigConstraint 스택 앞의 CaptureAnimationConstraint에 의해 저장된 신체 포즈를 부분적으로 다시 적용합니다. 이러한 애니메이션을 다리에 적용하려면 하체를 표시하는 AvatarMask를 제공합니다(Meta Movement 패키지의 "LowerBodyMask" 참조). 이 신체 포즈 애플리케이션의 강도는 PlaybackAnimationConstraint의 Weight 속성에 의해 제어됩니다. 가중치를 0으로 설정하면 이동 애니메이션이 완전히 숨겨지고 신체 추적이 애니메이터에 적용된 채로 유지됩니다. 가중치를 1로 설정하면 마스크된 영역에 이동 애니메이션이 적용됩니다.
- PlaybackAnimationConstraint의 가중치 속성에 대한 변경 사항을 자동으로 트리거하는 작업은 진행률 값을 가중치 속성에 제공하는 StateTransition 구성 요소를 사용하여 스크립트에서 수행됩니다.
이 전환은 PlayerController 개체에 있는 MovementSDKLocomotion의 OnStartMove 및 OnStopMove 콜백에 의해 스크립트에서 트리거됩니다.
... 그리고 PlayerController의 Jump 객체에서 JumpingRigidbody의 OnJump 및 OnJumpFinished 콜백을 통해:
"Locomotion" 및 "Jump" 애니메이션은 별도로 또는 함께 발생할 수 있고 둘 중 하나가 다른 애니메이션에 의해 취소되지 않고 애니메이션 마스크를 유지할 수 있어야 하기 때문에 이러한 콜백은 문자열로 애니메이션 이벤트의 소스를 식별합니다.
운동을 제한하고 물리 객체와 충돌하려면 Collider(또는 여러 Collider)를 추가하세요. 우리의 솔루션은 :
- 신체의 대부분을 포함하는 상체 Collider,
- 발을 지면 위에 유지하고 캐릭터와 지면의 충돌을 컨트롤러에 알리는 Collider
- 실제 모션을 등록하고 이에 따라 플레이어 컨트롤러의 충돌체를 이동하는 스크립트를 추가합니다. 사용자는 XR 장치를 착용하면 움직일 수 있으며, 이를 통해 앱에서 캐릭터가 움직여야 합니다. 우리의 예에는 실제 동작과 일치하도록 충돌체 위치를 업데이트하는 스크립트인 SphereColliderStaysBelowHips가 있습니다. 참고: 예제 스크립트는 FixUpdate 대신 업데이트에서 충돌체 위치를 업데이트합니다. 이는 사용자가 움직임을 거의 즉각적으로 알아차리지만(메스꺼움 방지에 더 좋음) 이러한 변경 사항이 물리 시스템과 동기화되지 않아 특수한 경우에 충돌 문제가 발생할 수 있음을 의미합니다.
- 특정 입력을 PlayerController 스크립트로 라우팅하는 스크립트를 추가합니다. 우리의 예에는 각각 OVRInput 및 UnityInput에서 입력을 읽는 OVRInputBinding 및 UnityInputBinding이라는 스크립트가 있습니다. 이러한 스크립트에는 MovementSDKLocomotion의 메서드 및 속성에 입력을 전달하는 UnityEvent 콜백이 있습니다.
- OVRCameraRig가 움직일 때 캐릭터 컨트롤러의 위치를 따르는지 확인하세요. OVRCameraRig는 사용자의 실제 '구체화'이며, 어디를 가든지 사용자가 자신이 있는 것처럼 느낄 수 있습니다. 우리의 예제에는 OVRCameraRig가 컨트롤러의 계층 구조에 없더라도 컨트롤러를 따르도록 이동하는 TransformsFollowMe 스크립트가 있습니다. 이론적으로는 간단히 OVRCameraRig를 컨트롤러 계층에 배치하는 것이 가능해야 합니다(1단계의 컨트롤러 개체의 하위 항목). 그러나 OVRCameraRig가 루트 개체가 될 것으로 예상하는 다양한 도구 및 알고리즘에서는 해당 동작이 항상 허용되는 것은 아닙니다. 또한 OVRCameraRig를 컨트롤러와 분리하면 컨트롤러가 사용자 없이도 '몸에서 분리된' 방식으로 더 쉽게 움직일 수 있어 이동이나 튜토리얼에 도움이 될 수 있습니다.
Fitness를 위한 Body Tracking 사용
Movement SDK에는 BodyPoseAlignmentDetection이라는 컴포넌트를 사용하여 신체 자세를 기록하고 비교하는 방법을 보여주는 MovementBodyTrackingForFitness라는 샘플이 있습니다.
이 섹션을 마치면 개발자는 아래의 사항들을 할 줄 알아야 합니다 :
- 사용자가 원하는 운동(예: 스쿼트)에 필요한 자세와 일치하는지 여부를 사용자가 판단할 수 있는 감지기(detector)를 구현할 수 있습니다.
여러분의 Scene에서의 body poses 비교
이 섹션에서는 다음을 수행하는 방법을 보여줍니다 :
- Unity 에디터에서 Body Poses 시각화
- 런타임 시 Body Poses 보기
- Unity Preview 중 Body Poses 내보내기
- Body Poses 가져오기
- 두 Body Poses가 얼마나 밀접하게 정렬되어 있는지 확인하세요.
- 비교를 기반으로 호출할 사용자 정의 작업 설정
- 에디터를 사용하여 Body Poses 조정
Unity 에디터에서 Body Poses 시각화
1. 에디터에서 새로운 GameObject를 만들고 이름을 "BodyPose" 로 지정한 다음, BodyPoseController 컴포넌트를 추가한다.
2. BodyPose GameObject에 BodyPoseBoneTransforms 라는 컴포넌트를 추가한다. 그 후 "Refresh Transform" 버튼을 누른다.
런타임 시 Body Poses 보기
BodyPoseController의 BodyPose는 런타임에 표시되지 않는 Bones Pose 배열로 구성된다. BodyPoseBoneTransforms에 의해 생성된 변환도 추가 작업 없이는 표시되지 않는다 :
- BodyPose 오브젝트에 BodyPoseBoneVisuals라는 컴포넌트를 추가한다.
- "Refresh Bone Visuals" 버튼을 누르면 런타임 시 지속되는 각 Bone에 대한 Bone 시각 객체가 자동으로 생성된다. 그러면 기본 Bone Visual Prefab도 생성된다. 이제 런타임에도 볼 수 있다.
- 기본 Bone Visual Prefab을 다른 것으로 변경하고 Skeleton을 새로 고칠 수 있습니다. 예를 들어, Bone Visual Prefab의 참조를 /Packages/Meta\ Movement/Samples/Prefabs/BodyTrackingForFitness/에 있는 프리팹으로 변경한 다음 "Clear Bone Visuals" 버튼과 "Refresh Bone Visual" 버튼을 차례로 눌러 Skeleton을 새로 고칩니다.
- Unity Editor를 사용하여 Skeleton Pose를 편집할 때 Bone을 표시하기 위해 생성된 Bone Visual Prefab의 복제본이 아니라 Bone 변환의 변환을 변경하고 있는지 확인하세요!
Unity Preview 중 Body Poses 내보내기
1. "BodyPose" 오브젝트에 OVRBodyPose 컴포넌트를 추가합니다. 이 컴포넌트는 헤드셋에서 Body Tracking Data를 읽고 이를 BodyPoseController로 변환합니다. OVRBodyPose는 기본적으로 전신으로 설정되어 있지만 상체만 (다리 없음) 으로 설정할 수도 있습니다.
- Quest 장치마다 신체 추적 데이터를 다르게 읽을 수 있습니다. 예를 들어, Quest3에서는 Quest2에서는 사용할 수 없는 기능인 IOBT(Inside Out Body Tracking)를 통해 전신 추적 데이터를 자동으로 강화할 수 있습니다.
2. BodyPoseController 컴포넌트의 Source Data Object 필드에 OVRBodyPose를 드래그하여 넣으세요.
이를 통해 런타임 시 또는 Link를 사용하여 Unity Preview를 하는 중에 Bone Pose를 구동하는 Body Tracking이 가능합니다. BodyPoseController 컴포넌트의 "Export Asset" 버튼은 Unity의 Preview mode 중에 동작이 가능합니다. 이는 OVRBodyPose에서 읽은 실제 신체 추적 데이터에서 Body Pose를 내보낼 수 있음을 의미합니다.
- "BodyPose" 오브젝트를 선택한 다음 헤드셋이 연결되고 Link에 연결된 상태에서 재생 버튼을 눌러 Unity Preview를 시작합니다. BodyPoseController의 "Export Asset" 버튼을 사용하여 현재 Bone Pose를 내보낸다. 내보낸 데이터는 /Assets/BodyPoses/ 폴더의 타임스탬프와 같이 asset 파일의 형태로 저장된다.
- 참고 : "Export Asset" 은 런타임시 APK에서 액세스할 수 없는 Unity Editor 기능입니다. APK 런타임이 아닌 Unity Preview 중에 BodyPose를 내보낼 수 있습니다.
- Body Pose 에셋의 기본 타임스탬프 이름을 포즈를 설명하는 이름으로 변경하는 것이 좋습니다.
- Link를 통해 Body Tracking이 작동하려면 Meta Quest Link 앱에서 개발자 런타임 기능을 활성화 해야 합니다. 이는 설정 -> 베타 -> 개발자 런타임 기능을 통해 확인할 수 있습니다. Link를 통해 다른 Quest 기능이 제대로 작동하려면 해당 사용자 인터페이스의 추가 토글이 필요할 수 있습니다.
Body Poses 가져오기
- Unity Editor에서(preview 중이 아닌 동안), 생성된 Body Pose 에셋 파일을 BodyPoseController의 Source Data Object 필드로 드래그 합니다. "Refresh T- Pose" 를 클릭한 다음 "Refresh Source Data" 를 클릭하여 두 포즈 간의 Skeleton Swap을 확인하세요
- Source Data Object 필드는 IBodyPose 오브젝트로 채워질 수 있습니다. 즉, BodyPoseController는 다른 BodyPoseController(포즈 복제), BoduPoseBoneTransforms(권장되지 않음), 또는 OVRBodyPose의 데이터를 참조할 수 있습니다.
두 Body Poses가 얼마나 밀접하게 정렬되어 있는지 확인하세요.
- "BodyPose"에 BodyPoseAlignmentDetector 컴포넌트를 추가하세요,
- Pose A 필드의 경우, 생성된 Body Pose 파일을 /Assets/BodyPoses/ 폴더에서 끌어서 넣습니다. Pose B 필드의 경우 이 오브젝트 자체를 끌어다 놓고 명확서 팝업에서 BodyPoseController 컴포넌트를 선택합니다.
- "Bone Visuals To Color" 안에 BodyPose 오브젝트를 드래그 앤 드롭합니다. 그러면 Bone Pose가 얼마나 일치하는지에 따라 Skeleton Visuals가 다시 칠해지게 됩니다.
- BodyTrackingForFitness 씬은 BodyPoseAlignment Detector를 사용하여 운동 자세를 계산하는 앱 컨셉입니다. 예를 들어 이 앱을 사용하여 사용자가 스쿼트 자세를 취하고 있는지 여부를 감지할 수 있습니다.
비교를 기반으로 호출할 사용자 정의 작업 설정
1. BodyPose Alignment Detector 는 다양한 목적으로 확장할 수 있는 유연한 인터페이스를 제공합니다. Pose Events 콜백에는 "Pose A" 가 "Pose B" 와 얼마나 잘 정렬되는지에 따라 사용자 정의 작업을 자동으로 트리거 할 수 있습니다. 이러한 액션은 Unity Event와 같은 로직이나 효과를 트리거 할 수 있습니다.
- OnComliance 는 모든 뼈대 포즈가 comply 될 때마다 한 번씩 트리거 됩니다.
- OnDeficiency 는 하나 이상의 Bone이 더 이상 comply 되지 않을 때마다 한 번씩 트리거 됩니다.
- OnCompliantBoneCount 는 complying 하는 Bone의 수가 변경될 때마다 트리거 됩니다.
- alignment(정렬) 또는 compliance(준수)는 Alignment Wiggle Room configuration entries 에 의해 정의됩니다.
- Maximum Angle Delta 필드는 두 뼈가 호환되는 것으로 간주 되기 위해 얼마나 밀접하게 정렬되어야 하는지를 결정합니다.
- Width 필드는 compliant(준수)와 deficient(결함) 사이의 여백을 결정합니다. 예를 들어 Left Arm Upper가 30도, Width 4도 정렬되어 있어야 하는 경우, Left Upper Arm이 28도 이내로 정렬되면 Complince가 트리거 되고 32도를 초과하면 Compliance에서 벗어납니다. 이러한 중첩은 flickering Compliance를 방지합니다.
- Compliance 각도들은 다음 두 가지 방법 중 하나로 측정할 수 있습니다.
- Joint Rotation : 뼈의 roll을 포함한 로컬 회전을 비교합니다. 이 정렬 감지는 수학적으로 매우 간단하지만 뼈가 완벽하게 각도를 이루는 것 외에도 완벽하게 굴려야 한다는 단점이 있습니다.
- Bone Direction : 특정 뼈의 관점에서 뼈의 방향을 비교합니다. 이 방법은 뼈대 롤을 무시하므로 방향 결정자(arbiter)로 특정 뼈대를 선택해야 합니다. 각도를 비교하는 이 방법은 특정 피트니스 애플리케이션 사용 사례를 테스트하는 동안 더 나은 느낌을 주었지만 테스트하려면 약간 더 많은 처리가 필요합니다.
에디터를 사용하여 Body Poses 조정
- BodyPoseController의 Bone Poses Array에서 위치/회전을 변경하면 Skeleton이 변경됩니다. 이 리스트의 개별 값을 수정하는 것은 가능하지만 Body Pose를 만드는 데 권장되는 방법은 아닙니다! BodyPoseBoneTransforms로 생성된 변환을 수정하거나 Preview 모드에서 Quest의 신체 추적 데이터를 읽은 다음 "Export Asset" 을 눌러 새로운 포즈를 만듭니다.
- 몸체 추적 Bone 위치와 방향 (및 길이)은 런타임에 결정됩니다. 하지만 T-Pose 데이터의 static 복사본은 FullBodySkeletonTPose.cs에 저장되고 Editor의 BodyPoseController에 적용됩니다.
- Editor를 사용하여 특정 Bone Pose를 변경하는 권장 방법은 BodyPoseBoneTransforms -> BoneTransforms로 이동하여 리스트를 확장하고 원하는 Bone을 클릭하는 것입니다. 오브젝트를 클릭하면 해당 오브젝트가 Hierachy에 표시됩니다. Hierachy에서 Transform을 클릭하여 선택한 다음 Transform의 Rotation을 변경합니다. BodyPoseController -> Bone Pose에서 Bone Pose Data를 변경하므로 Bone의 파란색 선이 변경됩니다.
- Bone Visuals To Color가 올바르게 설정된 경우 BodyPoseAlignmentDetector는 Editor 시간 동안 BodyPose를 변경하는 동안 Bone 색상을 조정해야 합니다.
Calibration API (보정 API)
학습 목적
이 섹션을 완료한 이후 개발자는 아래의 사항들을 할 줄 알아야 한다. :
- calibration API가 언제 유용한 지 이해한다.
- 명시적인 높이로 자동 감지된 높이를 재정의 하는 calibration(보정) API를 적용할 수 있다.
이 섹션에서는 보정 API를 사용할 수 있는 시기와 이를 사용하여 앱별 보정에서 자동 감지된 높이를 재정의하는 방법을 자세히 설명합니다.
자동 보정은 시스템이 헤드셋을 착용한 사람의 키를 결정하려고 시도하는 프로세스입니다. 높이는 사용자가 서 있는지, 쪼그리고 앉아 있는지, 앉아 있는지 감지할 수 있도록 하는 데 필요합니다. 자동 보정 루틴은 서비스가 생성된 후 처음 10초 이내에 실행되므로 서비스를 요청할 때 초기 상태가 중요합니다. 이상적으로 애플리케이션은 서비스가 시작될 때 사용자가 서 있는지 확인해야 합니다. 환자가 앉은 자세라면 팔을 쭉 뻗고 팔을 완전히 뻗은 상태에서 직경 약 0.3m(1피트)의 원을 그릴 수도 있습니다. 이 경우 날개폭으로 높이를 추정할 수 있습니다.
그러나 자동 보정이 충분히 작동하지 않는 경우도 있습니다(예: 사람이 계속 앉아 있고 팔을 뻗지 않는 경우). 앱이 사람의 키를 결정하기 위해 이미 초기화 프로세스를 거쳤고 이를 사용하려는 다른 상황도 있습니다. 이 두 사용 사례 모두에 대해 자동 보정을 재정의하는 데 사용할 수 있는 SuggestBodyTrackingCalibrationOverride() 및 ResetBodyTrackingCalibration 함수를 제공합니다.
OVRBody.cs를 사용하면 높이가 미터 단위로 지정되는 SuggestBodyTrackingCalibrationOverride(float height)를 통해 사용자 높이를 재정의할 수 있습니다.
Troubleshooting Body Tracking (Body Tracking 문제 해결)
이 섹션에서는 신체 추적과 관련된 일반적인 문제를 해결하는 방법을 자세히 설명합니다.
이 섹션을 완료한 후에는 다음 사항을 이해해야 합니다:
- 일반적인 프로젝트 관련 오류를 확인하는 방법
- Tracking 서비스가 실행 중인지 확인하는 방법
- 가장 흔한 증상과 원인
문제해결을 시작하기 위해 Edit > Project Settings > Meta XR 아래의 경고를 살펴보고 거기에서 발견된 문제를 해결하세요. 더 많은 정보를 확인하려면 Troubleshooting Movement SDK를 확인하세요.
참고 : 링크를 설정하려면 링크를 참조하세요.
adb logcat -s Unity 명령어를 사용하여 많은 문제를 디버깅할 수 있습니다. 그렇지 않은 경우 아래 강조된 해결 방법을 사용하세요.
See which Body Tracking services are active (어떤 신체 추적 서비스가 활성화되어 있는지 확인하세요)
개발 중에 신체 추적이 작동하지 않는 것처럼 보이는 문제가 발생할 수 있습니다. 이는 신체 추적에 대한 권한이 활성화되지 않은 것을 포함하여 여러 가지 문제로 인해 발생할 수 있습니다. 그러나 모든 권한이 설정되었다고 생각하고 서비스를 시작하려고 시도했지만 여전히 작동하지 않는 경우 ADB를 사용하여 다음 명령을 사용하여 어떤 서비스가 활성화되어 있는지 확인할 수 있습니다 :
adb shell dumpsys activity service com.oculus.bodyapiservice.BodyAPIService
신체 추적이 전혀 활성화되지 않은 경우 이 명령은 다음을 반환합니다 :
“No services match: com.oculus.bodyapiservice.BodyAPIService”
신체 추적 서비스가 활성화된 경우 다음과 같은 출력이 표시됩니다 :
SERVICE com.oculus.bodyapiservice/.BodyApiService 98564e0 pid=17192 user=0
Client:
Begin_BodyApiService
{
"fbs" : true,
"iobt" : false,
"num_updates_counter" : 26693,
"usingEngineV1" : false
}
End_BodyApiService
- fbs 줄은 Generative Legs가 활성화되었는지 여부를 나타냅니다.
- IOBT 줄은 IOBT가 활성 상태인지 여부를 표시합니다.
활성 상태란 현재 최소 한 명의 캐릭터가 서비스를 이용하고 있다는 의미입니다. 현재 적절한 신체 추적 서비스를 사용하여 실행 중인 캐릭터가 없으면 boolean은 false를 나타냅니다.
IOBT는 제안된 충실도 모드이며 API의 요구 사항은 아닙니다. 이 시스템은 전체 시스템의 성능을 관리하기 위해 구현됩니다. 따라서 개발자는 IOBT가 요청된 다른 서비스와 함께 지원되는지 확인하기 위해 IOBT가 다른 기능과 함께 실행되는 모드를 테스트하는 것이 좋습니다. 특히 시스템 활용도가 높은 후에(예: 패스스루 및 FMM(Fast Motion Mode) 또는 컨트롤러가 활성화되거나 시스템이 일반적으로 높은 CPU 부하를 받는 경우) 신체 추적을 위해 IOBT를 활성화하라는 호출이 이루어진 경우 신체 추적이 활성화됩니다. 낮은 충실도 모드(IOBT 없음). 사용자는 동일한 골격 출력을 볼 수 있지만 IOBT에서 제공하는 특정 추적 기능(예: 팔꿈치 추적, 기울어진 자세에서 올바른 척추 위치)을 사용할 수 없습니다.
Body Tracking works with controllers, but not with hands when running on the Quest device (not PC)
Body Tracking이 컨트롤러와 함께 작동하지만 Quest 장치 (PC 아님)에서 실행할 때 손으로는 작동하지 않는다.
- Settings > Movement Tracking > Hand Tracking 에서 장치에 손 추적 권한이 활성화되어 있는지 확인
- 프로젝트 구성에서 핸드 트래킹 및 컨트롤러가 활성화 되어 있는지 확인
- 앱이 시작 시 손 추적을 요청하는지 확인하세요.
Body Tracking works when running directly on the HMD, but fails to run over Link
신체 추적이 HMD에서 직접 실행할 때 작동하지만 링크를 통해 실행되지 않습니다.
- 데이터를 지원하는 USB 케이블로 연결되어 있는지 확인하세요. 이는 PC의 Oculus 앱의 Device Settings : Link Cable > Connect Your Headset > Continue 에서 테스트 할 수 있습니다.
- Settings > Beta > Developer Runtime Features 으로 이동하여 PC의 Oculus 앱에서 개발자 런타임 기능(Developer Runtime features) 이 활성화되어 있는지 확인하세요.
좀 더 많은 정보를 확인하려면 Troubleshooting Movement SDK를 확인하세요.
Body looks collapsed on the floor (몸이 바닥에 쓰러진 모습으로 보인다)
신체 추적이 작동하지 않습니다. 컨트롤러를 사용하는 경우 컨트롤러(또는 손 추적을 사용하는 경우 손)가 추적되고 있는지 확인합니다. 게임 컨텍스트 외부에서 이 작업을 수행할 수 있습니다.
또한 디버그 명령인
adb shell dumpsys activity service com.oculus.bodyapiservice.BodyAPIService
를 사용하여 Body Tracking이 실행 중인지 확인합니다.
헤드셋을 제거하고 나중에 착용할 때 신체 추적 오류가 발생하는 경우, HMDRemountRestartTracking을 사용하여 헤드셋을 착용한 후 신체 추적을 다시 시작할 수 있습니다. 이 스크립트는 프로젝트의 OVRRuntimeSettings Joint Set와 fidelity setting을 제거하고 착용한 후 다시 활성화 합니다.
Body is in a motorcycle pose with the upper body correct, but knees bent
몸은 오토바이 자세를 취하며 상체는 올바르지만 무릎은 구부립니다.
다리가 있는 캐릭터에 IOBT를 사용하는 경우 두 뼈 IK를 사용하여 다리를 쭉 뻗을 수 있습니다. Movement 패키지의 Samples/Prefabs/Retargeting/ArmatureSkinningUpdateGreen에서 이에 대한 예를 볼 수 있습니다.
부록 A : Open XR changes (변경점)
개발자는 뼈대 이름이나 블렌드 셰이프 및 대상 변경된 캐릭터 간의 불일치와 같은 문제를 디버깅하는 데 도움이 될 만큼 명명 규칙 및 Open XR 호출을 이해해야 합니다.
이 섹션의 정보는 독자에게 컨텍스트를 제공하기 위한 OpenXR 인터페이스의 변경 사항을 반영합니다. 하지만 Unity에서 이를 사용하는 경우에는 이러한 API를 직접 다루지 않으며 다음 섹션으로 건너뛸 수 있습니다. API 관련 내용은 Movement SDK OpenXR 설명서를 참조하세요. 높은 수준에서 기존 OpenXR 신체 추적 확장은 다음 네 가지 기능을 노출합니다 :
- xrCreateBodyTrackerFB - 바디 트래커를 생성한다.
- xrGetBodySkeletonFB - 참조 T자형 포즈의 관절 세트를 가져옵니다.
- xrLocateBodyJointsFB - 관절의 현재 위치를 가져옵니다.
- xrDestroyBodyTrackerFB - 트래커를 없앤다.
Generative Legs
새로운 신체 추적 전신 확장은 이러한 기능을 재사용하지만 새로운 관절 세트로 추적기를 생성하기 위한 지원을 추가합니다. 특히 XrBodyJointSetFB enum은 새로운 값 XR_BODY_JOINT_SET_FULL_BODY_META로 확장되어 사용자가 전체 하체에 대한 조인트(관절)(즉, 현재 상체와 새 하체 조인트)를 원하는 대로 지정할 수 있습니다.
하체 추적 기능이 있는 추적기를 만들려면 추적기를 만들 때 새 관절 세트를 지정하세요:
XrBodyTrackerCreateInfoFB
createInfo{XR_TYPE_BODY_TRACKER_CREATE_INFO_FB};
createInfo.bodyJointSet = XR_BODY_JOINT_SET_FULL_BODY_META;
XrBodyTrackerFB bodyTracker;
xrCreateBodyTrackerFB(session, &createInfo, &bodyTracker));
관절 위치 찾기(또는 관절의 기본 위치 찾기)는 기존의 Body Tracking Extension과 동일합니다. 관절 세트는 동일한 70개의 상체 관절과 추가 14개의 하체 관절을 포함하는 enum XrFullBodyJointMETA에 해당합니다. FullBodyJoint enum은 다음과 같습니다.
typedef enum XrFullBodyJointMETA{
XR_FULL_BODY_JOINT_ROOT_META = 0,
XR_FULL_BODY_JOINT_HIPS_META = 1,
XR_FULL_BODY_JOINT_SPINE_LOWER_META = 2,
XR_FULL_BODY_JOINT_SPINE_MIDDLE_META = 3,
XR_FULL_BODY_JOINT_SPINE_UPPER_META = 4,
XR_FULL_BODY_JOINT_CHEST_META = 5,
XR_FULL_BODY_JOINT_NECK_META = 6,
XR_FULL_BODY_JOINT_HEAD_META = 7,
XR_FULL_BODY_JOINT_LEFT_SHOULDER_META = 8,
XR_FULL_BODY_JOINT_LEFT_SCAPULA_META = 9,
XR_FULL_BODY_JOINT_LEFT_ARM_UPPER_META = 10,
XR_FULL_BODY_JOINT_LEFT_ARM_LOWER_META = 11,
XR_FULL_BODY_JOINT_LEFT_HAND_WRIST_TWIST_META = 12,
XR_FULL_BODY_JOINT_RIGHT_SHOULDER_META = 13,
XR_FULL_BODY_JOINT_RIGHT_SCAPULA_META = 14,
XR_FULL_BODY_JOINT_RIGHT_ARM_UPPER_META = 15,
XR_FULL_BODY_JOINT_RIGHT_ARM_LOWER_META = 16,
XR_FULL_BODY_JOINT_RIGHT_HAND_WRIST_TWIST_META = 17,
XR_FULL_BODY_JOINT_LEFT_HAND_PALM_META = 18,
XR_FULL_BODY_JOINT_LEFT_HAND_WRIST_META = 19,
XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_METACARPAL_META = 20,
XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_PROXIMAL_META = 21,
XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_DISTAL_META = 22,
XR_FULL_BODY_JOINT_LEFT_HAND_THUMB_TIP_META = 23,
XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_METACARPAL_META = 24,
XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_PROXIMAL_META = 25,
XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_INTERMEDIATE_META = 26,
XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_DISTAL_META = 27,
XR_FULL_BODY_JOINT_LEFT_HAND_INDEX_TIP_META = 28,
XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_METACARPAL_META = 29,
XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_PROXIMAL_META = 30,
XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_INTERMEDIATE_META = 31,
XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_DISTAL_META = 32,
XR_FULL_BODY_JOINT_LEFT_HAND_MIDDLE_TIP_META = 33,
XR_FULL_BODY_JOINT_LEFT_HAND_RING_METACARPAL_META = 34,
XR_FULL_BODY_JOINT_LEFT_HAND_RING_PROXIMAL_META = 35,
XR_FULL_BODY_JOINT_LEFT_HAND_RING_INTERMEDIATE_META = 36,
XR_FULL_BODY_JOINT_LEFT_HAND_RING_DISTAL_META = 37,
XR_FULL_BODY_JOINT_LEFT_HAND_RING_TIP_META = 38,
XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_METACARPAL_META = 39,
XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_PROXIMAL_META = 40,
XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_INTERMEDIATE_META = 41,
XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_DISTAL_META = 42,
XR_FULL_BODY_JOINT_LEFT_HAND_LITTLE_TIP_META = 43,
XR_FULL_BODY_JOINT_RIGHT_HAND_PALM_META = 44,
XR_FULL_BODY_JOINT_RIGHT_HAND_WRIST_META = 45,
XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_METACARPAL_META = 46,
XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_PROXIMAL_META = 47,
XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_DISTAL_META = 48,
XR_FULL_BODY_JOINT_RIGHT_HAND_THUMB_TIP_META = 49,
XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_METACARPAL_META = 50,
XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_PROXIMAL_META = 51,
XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_INTERMEDIATE_META = 52,
XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_DISTAL_META = 53,
XR_FULL_BODY_JOINT_RIGHT_HAND_INDEX_TIP_META = 54,
XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_METACARPAL_META = 55,
XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_PROXIMAL_META = 56,
XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_INTERMEDIATE_META = 57,
XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_DISTAL_META = 58,
XR_FULL_BODY_JOINT_RIGHT_HAND_MIDDLE_TIP_META = 59,
XR_FULL_BODY_JOINT_RIGHT_HAND_RING_METACARPAL_META = 60,
XR_FULL_BODY_JOINT_RIGHT_HAND_RING_PROXIMAL_META = 61,
XR_FULL_BODY_JOINT_RIGHT_HAND_RING_INTERMEDIATE_META = 62,
XR_FULL_BODY_JOINT_RIGHT_HAND_RING_DISTAL_META = 63,
XR_FULL_BODY_JOINT_RIGHT_HAND_RING_TIP_META = 64,
XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_METACARPAL_META = 65,
XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_PROXIMAL_META = 66,
XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_INTERMEDIATE_META = 67,
XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_DISTAL_META = 68,
XR_FULL_BODY_JOINT_RIGHT_HAND_LITTLE_TIP_META = 69,
// Lower body joints:
XR_FULL_BODY_JOINT_LEFT_UPPER_LEG_META = 70,
XR_FULL_BODY_JOINT_LEFT_LOWER_LEG_META = 71,
XR_FULL_BODY_JOINT_LEFT_FOOT_ANKLE_TWIST_META = 72,
XR_FULL_BODY_JOINT_LEFT_FOOT_ANKLE_META = 73,
XR_FULL_BODY_JOINT_LEFT_FOOT_SUBTALAR_META = 74,
XR_FULL_BODY_JOINT_LEFT_FOOT_TRANSVERSE_META = 75,
XR_FULL_BODY_JOINT_LEFT_FOOT_BALL_META = 76,
XR_FULL_BODY_JOINT_RIGHT_UPPER_LEG_META = 77,
XR_FULL_BODY_JOINT_RIGHT_LOWER_LEG_META = 78,
XR_FULL_BODY_JOINT_RIGHT_FOOT_ANKLE_TWIST_META = 79,
XR_FULL_BODY_JOINT_RIGHT_FOOT_ANKLE_META = 80,
XR_FULL_BODY_JOINT_RIGHT_FOOT_SUBTALAR_META = 81,
XR_FULL_BODY_JOINT_RIGHT_FOOT_TRANSVERSE_META = 82,
XR_FULL_BODY_JOINT_RIGHT_FOOT_BALL_META = 83,
XR_FULL_BODY_JOINT_COUNT_META = 84,
XR_FULL_BODY_JOINT_NONE_META = 85,
XR_FULL_BODY_JOINT_MAX_ENUM_META = 0x7FFFFFFF
} XrFullBodyJointFB;
이 코드가 실행되고 locations.isActivate가 true라고 가정하면, jointLocations[XR_FULL_BODY_JOINT_RIGHT_UPPER_LEG_META] 는 위쪽 다리 관절의 포즈를 나타냅니다.
Body tracking calibration (신체 추적 교정)
새로운 신체 추적 보정 확장을 사용하면 애플리케이션이 사용자 키에 대해 재정의된 값을 제공하여 시스템에서 수행되는 자동 보정을 재정의할 수 있습니다.
XrBodyTrackerCreateInfoFB
createInfo{XR_TYPE_BODY_TRACKER_CREATE_INFO_FB};
createInfo.bodyJointSet = XR_BODY_JOINT_SET_FULL_BODY_META;
XrBodyTrackerFB bodyTracker;
xrCreateBodyTrackerFB(session, &createInfo, &bodyTracker));
XrBodyTrackingCalibrationInfoMETA calibrationInfo = {XR_TYPE_BODY_TRACKING_CALIBRATION_INFO_META};
calibrationInfo.bodyHeight = 2.5;
xrSuggestBodyTrackingCalibrationMETA(bodyTracker, &calibrationInfo);
교정 재정의 높이는 미터 단위로 지정됩니다.
또한 애플리케이션은 현재 교정 상태를 쿼리하고 신체가 현재 올바르게 교정되었는지 여부에 따라 신체 추적 결과를 사용할지 여부를 결정할 수 있습니다. 반환된 뼈대를 보정하는 동안 배율이 변경될 수 있습니다.
현재 교정 상태를 확인하기 위해 응용 프로그램은 xrLocateBodyJointsFB를 통해 신체 포즈를 쿼리할 때 XrBodyJointLocationsFB 구조체의 다음 포인터를 통해 XrBodyTrackingCalibrationStatusMETA를 전달할 수 있습니다.
XrBodyJointLocationFB
jointLocations[XR_FULL_BODY_JOINT_COUNT_META];
XrBodyJointLocationsFB
locations{XR_TYPE_BODY_JOINT_LOCATIONS_FB};
locations.jointCount = XR_FULL_BODY_JOINT_COUNT_META;
locations.jointLocations = locations;
XrBodyTrackingCalibrationStatusMETA calibrationStatus = {XR_TYPE_BODY_TRACKING_CALIBRATION_STATUS_META};
Locations.next = &calibrationStatus;
XrBodyJointsLocateInfoFB
locateInfo{XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB};
locateInfo.baseSpace = GetStageSpace();
locateInfo.time = ToXrTime(in.PredictedDisplayTime);
xrLocateBodyJointsFB(bodyTracker, &locateInfo, &locations));
if (calibrationStatus.status != XR_BODY_TRACKING_CALIBRATION_STATE_VALID_META) {
// Don’t use the body tracking result
}
typedef enum XrBodyTrackingCalibrationStateMETA {
XR_BODY_TRACKING_CALIBRATION_STATE_VALID_META = 0;
XR_BODY_TRACKING_CALIBRATION_STATE_CALIBRATING_META = 1;
XR_BODY_TRACKING_CALIBRATION_STATE_INVALID_META = 2;
} XrBodyTrackingCalibrationStateMETA;
유효한 보정 결과는 해당 포즈를 사용해도 안전하다는 것을 의미합니다. 신체 자세를 교정한다는 것은 교정이 아직 실행 중이고 자세가 올바르지 않을 수 있음을 의미합니다. 잘못된 보정 결과는 해당 포즈가 사용하기에 안전하지 않음을 의미합니다.
부록 B : ISDK integration
개발자는 아래 사항들을 할 수 있어야 합니다.
- ISDK( Interaction SDK) 와 MSDK(Movement SDK)가 호환되도록 설정하는 방법을 이해합니다.
- Interaction SDK를 사용하여 샘플 가상 객체를 조작할 수 있도록 Movement SDK를 사용하여 신체 추적으로 장면을 조작할 수 있습니다.
유니티 Movement package에서 여러분은 MovementISDKIntegration Scene을 Unity-Movement > Samples~ > AdvancedSamples > Scenes. 에서 찾을 수 있습니다.
이 샘플은 Interaction SDK(ISDK) 손 움직임을 리타겟팅된 Movement SDK(MSDK) 본문에 적용하는 방법을 보여줍니다.
이 장면은 MSDK를 사용하여 신체 움직임의 대상을 캐릭터로 변경하고 ISDK에서 제공하는 상호 작용을 사용하여 캐릭터가 가상 개체와 상호 작용하도록 하려는 개발자에게 흥미로울 것입니다. 특히 잡기나 터치 제한을 사용할 때 ISDK는 가상 물체(예: 컵)를 잡거나 가상 화면을 누를 때 시각적으로 정확하도록 추적된 위치에서 손가락 위치를 재배치합니다. 이는 손가락의 실제 위치와 다르기 때문에 대상 변경된 캐릭터의 손가락이나 팔꿈치 위치를 새로운 가상 위치에 맞게 조정해야 합니다. 이 샘플은 이를 수행하는 방법을 보여줍니다.
Interaction SDK에 대한 설명서와 빠른 시작 가이드는 여기에서 찾을 수 있습니다. ISDK와 함께 Capsense를 사용해야 하며 아래 설명된 대로 OVRHands 프리팹을 통합해야 합니다.
- ISDK로 Capsense를 활성화하려면 Controller Driven Hand Poses (OVRManager에 있음)를 Natural로 설정하세요.
- 또한 OVRCameraRig 계층 구조에 있는 OVRHandPrefab 오브젝트를 찾고 Show State 옵션을 Always으로 설정합니다. 이렇게 하면 컨트롤러가 손으로 작업할 수 있습니다.
Key Scirpts
다음 스크립트는 기본 기능을 구현하며 프로젝트에 이식할 수 있습니다:
- SkeletonHandAdjustment는 ISDK 손의 포즈를 대상 변경된 몸체에 적용할 수 있는 스크립트입니다. OVRInteraction 구성 요소의 하위 항목에 여러 인스턴스가 포함되어 있습니다. OVRInteraction은 사용자가 가상 개체를 조작할 수 있도록 손 상호 작용을 제공하는 데 사용됩니다. 이러한 손 상호 작용은 장면 계층 구조에서 왼쪽 및 오른쪽 손, 즉 LeftHandSynthetic 및 RightHandSynthetic으로 표시됩니다. Capsense를 활성화하면 이러한 핸드 메시는 컨트롤러를 사용하든 핸드 트래킹을 사용하든 상관없이 작동합니다.
각 합성 손에는 MovementISDKIntegration 샘플에 표시된 대로 SkeletonHandAdjustment 컴포넌트도 있어야 합니다. 이는 아래 설명된 SkeletonProcessAggregator 스크립트의 데이터 소스 역할을 합니다.
- SkeletonProcessAggregator는 SkeletonHandAdjustment와 같은 여러 IOVRSkeletonProcessor 스크립트를 참조하고 대상 변경이 발생하기 전에 정의된 순서로 입력 뼈대에 적용하는 스크립트입니다. 애니메이션하려는 RetargetingLayer 캐릭터에 구성 요소로 추가됩니다. 예제에서는 ArmatureSkinningUpdateRetargetSkeletonProcessor 아래에 있습니다.
Interaction SDK and Movement SDK Component Integration
Interaction SDK 와 Movement SDK 컴포넌트 조합
잘라내기 및 붙여넣기 작업을 사용하거나 프리팹을 만들어 MovementISDKIntegration 샘플 장면에 사용된 정확한 OVRInteraction 개체를 직접 복사하는 것이 좋습니다. 직접 복사하지 않고 프로젝트에서 이러한 스크립트를 수동으로 설정하려면 다음을 수행하세요:
- ISDK 시작하기 튜토리얼이나 유사한 ISDK 소개를 읽어보세요. 위 이미지에 표시된 것처럼 OVRCameraRig 개체와 OVRInteraction 개체가 있어야 합니다. 단, OVRHands 및 Synthetic 손이 누락됩니다. OVRHands(손 포즈의 소스 역할을 할 수 있는 손 개체가 있음)를 검색하여 OVRInteraction에 추가합니다.
- OVRLeftHandSynthetic 및 OVRRightHandSynthetic 프리팹을 검색하고 해당 항목이 아직 존재하지 않는 경우 OVRHands에 추가합니다. 이러한 스크립트는 명확성을 위해 MovementISDKIntegration 장면에서 이름이 변경되었습니다. 합성 손별로 설정 프로세스를 계속합니다.
- 합성 손(Synthetic Hand)이 자체적으로 설정되지 않으면 해당 데이터 소스를 소스 모노에서 데이터 소스 수정 필드로 끌어서 놓습니다. 예를 들어, 이미지에 표시된 대로 LeftHand를 LeftHandSynthetic으로 드래그해야 합니다.
- 왼쪽 및 오른쪽 합성 손에 SkeletonHandAdjustment를 추가합니다.
- 여기에 설명된 대로 OVRHands에 잡기 인터랙터를 추가합니다. 예를 들어 왼손의 경우 HandGrabInteractor를 OVRHands > LeftHand > HandInteractorsLeft에 추가합니다.
ISDK 핸드 인터랙터가 설정되면 RetargetingLayer의 GameObject에 연결되어야 하는 SkeletonProcessAggregator에서 SkeletonHandAdjustment 구성 요소를 참조해야 합니다. SkeletonProcessAggregator는 RetargetingLayer에서 예상하는 RigConstraint 구성 요소에서 사용되기 전에 입력 뼈대에 특수 처리를 적용합니다.
- RetargetingLayer가 포함된 GameObject에 SkeletonProcessAggregator 컴포넌트가 있는지 확인하세요.
- SkeletonProcessAggregator 컴포넌트를 추가하면 Auto Add To 필드가 자동으로 채워집니다.
- SkeletonProcessAggregator의 Skeleton Processors 목록에 각 합성 손 개체를 추가하고 Enabled가 선택되어 있는지 확인하세요.
- SkeletonProcessAggregator의 스켈레톤 프로세서 리스트에서 null 값을 제거합니다.
이 시점에서 ISDK 상호 작용에 필요한 기본 컴포넌트를 추가했으며 핸드 그랩 상호 작용을 설명하는 튜토리얼 중 하나로 이동하거나 우리가 제공한 샘플을 계속 활용할 수 있습니다.
각 HandGrabInteractor에 대해 HandGrabVisual을 활성화해야 조정된 손의 위치를 가져와 일부 오브젝트를 감싸는 것처럼 보이도록 해야 합니다.
- 인터랙터 오브젝트 계층 아래의 Visuals->HandGrabVisual로 이동합니다.
- HandGrabVisual을 활성화합니다.
- 할당되지 않은 경우 적절한 Synthetic Hand를 Synthetic Hand 필드에 할당합니다. 이는 손을 기반으로 한 손과 관련된 합성 손 개체에 해당합니다.
Visuals
ISDK에는 디버깅에 유용한 몇 가지 시각적 요소가 있지만 캐릭터의 손과 겹쳐서 주의가 산만해 보일 수 있습니다. ISDK의 손 영상을 모두 제거하려는 경우 비활성화할 개체는 다음과 같습니다 :
- 각 synthetic hand object에 대해 그 아래에 있는 OVRLeftHandVisual 또는 OVRRightHandVisual을 비활성화합니다.
- OVRHands > LeftHand 아래에서 HandVisualsLeft를 비활성화합니다.
- OVRHands > RightHand 아래에서 HandVisualsRight를 비활성화합니다.
ISDK Hierarchy
MovementSDKIntegration에는 데모 목적으로만 이해해야 하며 프로젝트에서 교체되거나 제거될 수 있는 계층 구조 개체가 있습니다:
- UI → Skeleton Rendering Menu: 이 메뉴는 런타임 시각화를 활성화/비활성화합니다.
- Input skeleton visualization: Input Body Tracking Skeleton을 렌더링합니다.
- Animator skeleton visualization : 대상이 변경된 애니메이터의 뼈대를 그립니다.
- Skeleton Visuals: 여기에는 메뉴 버튼으로 수정된 BoneVisualizer 개체가 있습니다.
- Environment: 장면의 바닥과 조명을 포함하는 객체입니다.
- MirroredObjects: 여기에는 미러링된 아바타와 관련 조명이 포함됩니다.
- InteractableObjects: 여기에는 Interaction SDK를 시연하는 데 사용되는 잡을 수 있는 개체가 포함되어 있습니다.
부록 C - Advanced Body Deformation(고급 신체 변형)
제약 조건을 조정한 후에도 캐릭터에 시각적 문제가 있는 경우 다른 애니메이션 리깅 제약 조건이나 대상 변경 프로세서를 적용하여 나머지 문제를 해결해야 합니다.
개발자는 필요에 따라 변형 논리를 미세 조정하기 위해 수정할 수 있는 주요 구성 요소를 이해해야 합니다.
- Animation Rigging Constraints: 애니메이션 리깅 제약 조건에 대한 자세한 내용은 여기에 있는 Unity 문서를 참조하세요.
- Retargeting Processors: 대상 변경 프로세서는 원본 추적 데이터와 대상 변경 데이터를 사용하여 뼈대 변환을 업데이트하면서 근육 공간의 제약을 받지 않도록 설계된 스크립트 가능한 개체입니다. ArmatureCordirectLeftHand 리타겟팅 프로세서는 CCD IK를 사용하는 경우 각 리타겟팅된 뼈대를 어깨에서 손 방향으로 회전시켜 원래 추적된 손 위치에 도달하려고 하는 작업의 예입니다. 자신만의 리타겟팅 프로세서를 추가하려는 경우 여기에 있는 템플릿 ScriptableObject가 제공됩니다.
- Retargeted Bone Targets: 추적 출력(예: SpineLower 위치 및 회전)이 필요한 경우 RetargetingLayer에 있는 외부BoneTargets을 통해 노출할 수 있으며, 이는 추적된 변환 데이터(위치 및 회전)로 지정된 대상 변환을 업데이트합니다.
Modifying Character Height to Match Varying User Heights
다양한 사용자 높이에 맞게 문자 높이 수정
캐릭터의 정점은 일반적으로 캐릭터 애니메이션을 사용할 때 메시의 제한된 부분에 영향을 미칩니다. 그러나 신체 추적은 다양한 사용자 높이를 수용하기 위해 메시의 크기를 조정할 수 있으며 이로 인해 여러 가지 시각적 아티팩트가 발생할 수 있습니다. 여기에는 팔뚝 메시에서 연결이 끊어진 손 메시(늘리기) 또는 무릎으로 압축되는 아래쪽 다리 메시(압축)가 포함됩니다.
아래 그림에서 캐릭터의 피부 영향은 현재 일부 관절 변환을 허용하기 위해 팔다리 관절을 따라 공유되지 않습니다. 왼쪽 그림은 발목 관절에서 메쉬 가중치가 없는 원래 캐릭터를 보여주고, 오른쪽 버전은 페인팅된 발목에서 정강이까지 가중치 영향을 보여줍니다.
조정된 가중치 영향을 통해 이제 고정된 발목이 아래쪽 정강이에 영향을 미치는 변형으로 변환될 수 있습니다.
아래의 또 다른 예는 체중의 영향이 허벅지에서 무릎 관절까지의 영역에 어떻게 영향을 미칠 수 있는지 보여줍니다. 왼쪽 그림은 해당 영역에 무게가 없음을 보여 주는 반면, 오른쪽 그림은 페인팅된 무릎에서 허벅지까지 약간의 무게 영향을 보여줍니다.
이제 고정된 무릎을 허벅지와 무릎의 변형 결과로 변환할 수 있습니다.
다음 gif는 모션 결과를 보여줍니다. 왼쪽에는 수정되지 않은 가중치가 표시되고 오른쪽에는 조정된 가중치가 표시됩니다.
일반적으로 뼈대의 충격 영역을 문제의 관절 위 최소 6인치까지 확장하여 스트레칭이나 스퀴싱 중에 더 많은 메시 정점이 영향을 받도록 하는 것이 좋습니다.
'MetaXR_SDK 탐구' 카테고리의 다른 글
Movement SDK for Unity - 시작하기 (1) | 2024.11.26 |
---|---|
상호작용 추가 (0) | 2024.11.20 |
유니티 기본 세팅 (0) | 2024.11.20 |