QCHT手部跟踪集成
QCHT(Qualcomm Compute Hand Tracking)是Snapdragon Spaces SDK的扩展交互工具包,构建在OpenXR手部跟踪之上,提供高级功能如远距离/近距离交互、控制器切换、物理模拟和手势UI。它简化了手部交互的实现,支持虚拟手覆盖、手指针和抓取。
详细步骤
导入QCHT包:
- 从Snapdragon Spaces Developer Portal下载QCHT Unity Interactions包(.unitypackage或.tgz)。
- 在Unity中:Assets > Import Package > Custom Package,导入QCHT。
- 确保已导入Snapdragon Spaces核心SDK和OpenXR插件。
- Project Settings > XR Plug-in Management > Android > OpenXR:启用Hand Tracking和QCHT Interactions功能组。
场景设置:
- 创建XR Rig:Hierarchy右键 > XR > Room-Scale XR Origin。
- 添加QCHT Hand Tracking Manager:右键Hierarchy > QCHT > Hand Tracking Manager(或脚本添加
QCHT.Interactions.HandTracking.HandTrackingManager)。 - 添加虚拟手:为左右手添加QCHT Hand Mesh(QCHT > Hand Mesh Left/Right),或使用预制体。
- 添加交互:为对象添加QCHT Interactable组件(支持Grab、Poke等)。
- 启用控制器切换:添加QCHT Controller Switch脚本,支持手/控制器无缝切换。
模拟与测试:
- Editor模拟:Project Settings > XR Plug-in Management > Hand Tracking Simulation > 启用Simulation子系统。
- 构建APK,部署到支持设备(如XR2头显)。
- 使用Extended Hand Tracking Sample导入样本场景测试近/远交互。
API使用:
HandTrackingManager:管理双手数据。Hand:访问关节、姿态(e.g.,Hand.GetJoint(JointId.Wrist))。- 事件:
OnHandEnter/Exit用于交互。
完整代码示例:QCHTGrabExample.cs
附加到XR Origin,演示QCHT抓取交互。假设有可抓取Cube(添加QCHT Interactable和Rigidbody)。
usingUnityEngine;usingQCHT.Interactions.Core;// QCHT核心命名空间usingQCHT.Interactions.Hands;// 手部命名空间publicclassQCHTGrabExample:MonoBehaviour{publicGameObjectgrabTarget;// 可抓取对象(Cube)privateHandTrackingManagerhandManager;privateHandleftHand,rightHand;voidStart(){// 获取QCHT ManagerhandManager=FindObjectOfType<HandTrackingManager>();if(handManager==null){GameObjectmanagerObj=newGameObject("QCHTHandTrackingManager");handManager=managerObj.AddComponent<HandTrackingManager>();}// 订阅手部事件handManager.OnHandTrackingStarted+=OnTrackingStarted;handManager.OnHandTrackingStopped+=OnTrackingStopped;}voidOnTrackingStarted(){Debug.Log("QCHT Hand Tracking Started");leftHand=handManager.LeftHand;rightHand=handManager.RightHand;}voidOnTrackingStopped(){Debug.Log("QCHT Hand Tracking Stopped");}voidUpdate(){if(handManager.Status!=XRHandTrackingSubsystem.TrackingStatus.Running)return;// 示例:检测捏合抓取if(leftHand!=null&&leftHand.IsPinching){TryGrab(leftHand);}if(rightHand!=null&&rightHand.IsPinching){TryGrab(rightHand);}}voidTryGrab(Handhand){// 简单射线检测抓取Rayray=newRay(hand.PalmPosition,hand.PalmForward);if(Physics.Raycast(ray,outRaycastHithit,0.5f))// 0.5m范围{if(hit.collider.gameObject==grabTarget){grabTarget.transform.SetParent(hand.transform);// 附着手grabTarget.transform.localPosition=Vector3.zero;Debug.Log("Grabbed with "+(hand.IsLeft?"Left":"Right")+" Hand");}}}voidOnDestroy(){if(handManager!=null){handManager.OnHandTrackingStarted-=OnTrackingStarted;handManager.OnHandTrackingStopped-=OnTrackingStopped;}}