using EZXR.Glass.Core; using EZXR.Glass.Simulator.Hand; using EZXR.Glass.SixDof; using System.Collections; using UnityEngine; namespace EZXR.Glass.Inputs { [ScriptExecutionOrder(-49)] public class ARHandManager : MonoBehaviour { #region singleton private static ARHandManager instance; public static ARHandManager Instance { get { return instance; } } #endregion public enum HandTrackingMode { HighPrecision,//GPU HighEfficiency,//DSP } HandTrackingMode handTrackingMode = HandTrackingMode.HighPrecision; public bool enableHandSimulatorInEditor = true; ///// ///// 是否显示球棍手 ///// //public bool ShowHandJoint = true; /// /// 头部坐标系所在的物体 /// public static Transform head; /// /// 实例化出来作为所有手的根节点 /// GameObject prefab_handRoot; Transform handRoot; /// /// 记录了左手的所有信息,包括当前有没有捏合,有没有握持物体等等 /// public static HandInfo leftHand; /// /// 记录了右手的所有信息,包括当前有没有捏合,有没有握持物体等等 /// public static HandInfo rightHand; /// /// 由外部逻辑控制手的射线的方向 /// /// /// /// public delegate bool Delegate_SetRayDataByExternal(HandInfo handInfo, ref Vector3 value); public static Delegate_SetRayDataByExternal SetRayDirByExternal; public static Delegate_SetRayDataByExternal SetRayStartPointByExternal; private void Awake() { instance = this; gameObject.AddComponent(); if (Application.isEditor) { if (enableHandSimulatorInEditor) { gameObject.AddComponent(); } } StartCoroutine(enableHandDetecting()); //注册回调,以得到HandTrackingData的数据更新 NativeSwapManager.OnHandTrackingDataUpdated += OnHandTrackingDataUpdated; //if (ShowHandJoint) //{ // gameObject.AddComponent(); //} head = HMDPoseTracker.Instance.Head; Transform handRoot_Left = transform.Find("Left"); Transform handRoot_Right = transform.Find("Right"); #region 兼容旧版 if (handRoot_Left == null || handRoot_Right == null) { handRoot = transform.Find("HandRoot"); handRoot_Left = handRoot.Find("HandRoot_Left"); handRoot_Right = handRoot.Find("HandRoot_Right"); } #endregion //初始化HandInfo,以指定HandInfo是左手还是右手 leftHand = handRoot_Left.GetComponent(); leftHand.Init(HandType.Left); rightHand = handRoot_Right.GetComponent(); rightHand.Init(HandType.Right); //拇指和食指之间用来触发近距离捏合的区域 GameObject prefab_TriggerBetweenDaddyAndMommyFinger = ResourcesManager.Load("Triggers/TriggerBetweenDaddyAndMommyFinger"); TriggerForPinch interactWithFingerTip_Left = Instantiate(prefab_TriggerBetweenDaddyAndMommyFinger, leftHand.root).GetComponent(); interactWithFingerTip_Left.SetUp(leftHand.root); TriggerForPinch interactWithFingerTip_Right = Instantiate(prefab_TriggerBetweenDaddyAndMommyFinger, rightHand.root).GetComponent(); interactWithFingerTip_Right.SetUp(rightHand.root); //手部的预触发区,用于切换近距离和远距离交互 GameObject prefab_TriggerForFarNearSwitch = ResourcesManager.Load("Triggers/TriggerForFarNearSwitch"); TriggerForFarNearSwitch triggerForFarNearSwitch_Left = Instantiate(prefab_TriggerForFarNearSwitch, leftHand.root).GetComponent(); triggerForFarNearSwitch_Left.SetUp(leftHand.root); TriggerForFarNearSwitch triggerForFarNearSwitch_Right = Instantiate(prefab_TriggerForFarNearSwitch, rightHand.root).GetComponent(); triggerForFarNearSwitch_Right.SetUp(rightHand.root); } private void OnApplicationPause(bool pause) { if (!pause) { if (!Application.isEditor) { StartCoroutine(enableHandDetecting()); } } } private void OnDestroy() { disableHandDetecting(); } public void changeHandRunMode(HandTrackingMode mode) { handTrackingMode = mode; StartCoroutine(enableHandDetecting()); } // 控制器统一管理时,激活手势功能 public void SetActive(bool value) { //StartCoroutine(enableHandDetecting()); //transform.GetComponent().enabled = true; //for (int i = 0; i < transform.childCount; i++) //{ // transform.GetChild(i).gameObject.SetActive(true); //} gameObject.SetActive(value); } private IEnumerator resetHandRunMode(HandTrackingMode mode) { yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); NativeSwapManager.setHandRunMode((int)handTrackingMode); } private IEnumerator enableHandDetecting() { yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); if (handTrackingMode == HandTrackingMode.HighEfficiency) { SessionManager.Instance.ARInitConfig.HandsFindingMode = HandsFindingMode.Enable_HighEfficiency; } else if (handTrackingMode == HandTrackingMode.HighPrecision) { SessionManager.Instance.ARInitConfig.HandsFindingMode = HandsFindingMode.Enable_HighPrecision; } SessionManager.Instance.ResumeSession(); } private void disableHandDetecting() { SessionManager.Instance.ARInitConfig.HandsFindingMode = HandsFindingMode.Disable; SessionManager.Instance.ResumeSession(); } public void UpdateHandTrackingDataManually(NativeSwapManager.HandTrackingData[] handTrackingData) { OnHandTrackingDataUpdated(handTrackingData); } private void OnHandTrackingDataUpdated(NativeSwapManager.HandTrackingData[] handTrackingData) { NativeSwapManager.HandTrackingData handTrackingData_Left, handTrackingData_Right; handTrackingData_Left = handTrackingData[0]; handTrackingData_Right = handTrackingData[1]; //开启或关闭虚拟手物体(直接关闭手GameObject的原因是当手不存在的时候不应该执行任何逻辑) leftHand.root.gameObject.SetActive(handTrackingData_Left.isTracked); rightHand.root.gameObject.SetActive(handTrackingData_Right.isTracked); //刷新手的数据 leftHand.UpdateHandInfoData(handTrackingData_Left); rightHand.UpdateHandInfoData(handTrackingData_Right); } public HandInfo GetHand(HandType handedness) { if (handedness == HandType.Left) { return leftHand; } else { return rightHand; } } } }