using System; using System.Collections; using EZXR.Glass.Core; using EZXR.Glass.SixDof; using UnityEngine; using UnityEngine.EventSystems; namespace EZXR.Glass.Inputs { [ScriptExecutionOrder(-47)] public class InputSystem : MonoBehaviour { #region singleton private static InputSystem instance; public static InputSystem Instance { get { return instance; } } #endregion [SerializeField] private ControllerType m_ControllerType; [Obsolete("Please use 'CurrentActiveControllerType' instead!")] public ControllerType controllerType { get { return m_ControllerType; } } /// /// 当前激活的控制器类型 /// public static ControllerType CurrentActiveControllerType { get { return Instance.m_ControllerType; } } /// /// 开启动态模式时,支持热切换 /// [SerializeField] private bool dynamicMode = true; /// /// InputSystem当前是否被启用 /// private bool isActive = true; /// /// 记录了左手柄的所有信息 /// public static InputInfoBase leftHand; /// /// 记录了右手柄的所有信息 /// public static InputInfoBase rightHand; /// /// 按键按住或握持住时,手柄保持激活 /// private bool keepHandlesActive = false; private bool isInited = false; private bool isPaused = false; private bool isGlassStandby = false; private bool isHandlesStandby = false; public void SetActive(bool value) { isActive = value; switch (CurrentActiveControllerType) { case ControllerType.HandTracking: ARHandManager.Instance.gameObject.SetActive(value); break; case ControllerType.Controllers: HandleControllerManager.Instance.gameObject.SetActive(value); break; } } private void Awake() { instance = this; //TODO 初始化交互:头控<手势<手柄 if (dynamicMode) m_ControllerType = ControllerType.Helmet; Debug.Log($"ControllerManager, init dynamicMode: {dynamicMode}, controllerType: {CurrentActiveControllerType}"); if (dynamicMode) { m_ControllerType = ControllerType.HandTracking; leftHand = ARHandManager.leftHand; rightHand = ARHandManager.rightHand; } } private IEnumerator Start() { //Debug.Log("InputSystem--> KeyBoard"); //if (KeyBoard.Instance == null) //{ // Instantiate(ResourcesManager.Load("KeyBoard")); //} HandleControllerManager.Instance.InitRegistration(null, OnHandleConnectChanged, null, OnHandleButtonChanged, OnHandleHoldChanged, OnHandleSilenceChanged); HandleControllerSession.Instance.InitServerReconnectRegistration(OnServerReconnected); #if SYSTEMUI SDKEventSystem.OnSystemEnterStandbyMode += OnServerStandby; #else OSEventSystem.OnSystemEnterStandbyMode += OnServerStandby; #endif if (dynamicMode) { //StartCoroutine(ChangeToGestureController()); //StartCoroutine(CheckStatus()); m_ControllerType = ControllerType.HandTracking; leftHand = ARHandManager.leftHand; rightHand = ARHandManager.rightHand; HandleControllerManager.Instance.SetActive(false); ARHandManager.Instance.SetActive(true & isActive); Debug.Log($"ControllerManager, init Change to GestureController ({Time.frameCount})"); Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); } else { if (CurrentActiveControllerType == ControllerType.HandTracking) { leftHand = ARHandManager.leftHand; rightHand = ARHandManager.rightHand; HandleControllerManager.Instance.SetActive(false); if (!isPaused) { Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Hand"); Debug.Log($"ControllerManager, init SendIntent ControllerType HandTracking ({Time.frameCount})"); } } else { leftHand = HandleControllerManager.leftHand; rightHand = HandleControllerManager.rightHand; ARHandManager.Instance.SetActive(false); if (!isPaused) { Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Controllers"); Debug.Log($"ControllerManager, init SendIntent ControllerType Controllers ({Time.frameCount})"); } } } yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); HandleControllerSession.Instance.ChangeControllerType((int)CurrentActiveControllerType); isInited = true; } private void Update() { // 不受HandleControllerSession未激活影响 HandleControllerSession.Instance?.UpdateHandleCallback(); if (isGlassStandby) { isGlassStandby = false; if (dynamicMode || (!dynamicMode && CurrentActiveControllerType == ControllerType.HandTracking)) { StartCoroutine(ChangeToGestureController()); } Debug.Log($"ControllerManager, Awake after standby, isGlassStandby = {isGlassStandby} ({Time.frameCount})"); } if (isHandlesStandby) { isHandlesStandby = false; if (dynamicMode) StartCoroutine(ChangeToGestureController()); Debug.Log($"ControllerManager, Awake after Handles Standby, controllerType: {CurrentActiveControllerType}, dynamicMode: {dynamicMode} ({Time.frameCount})"); } //if (!isPaused && Input.GetKeyDown(KeyCode.I)) // InitDynamicMode(ControllerType.Controllers); //if (!isPaused && Input.GetKeyDown(KeyCode.E)) // EnableDynamicMode(); //if (!isPaused && Input.GetKeyDown(KeyCode.H)) // DisableDynamicMode(ControllerType.HandTracking); //if (!isPaused && Input.GetKeyDown(KeyCode.C)) // DisableDynamicMode(ControllerType.Controllers); } private void OnApplicationPause(bool pause) { if (!pause) { if (isInited) { if (dynamicMode) { Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); //手柄未连接状态下(回调失效),Resume时强制切到手势模式 if (!HandleControllerManager.Instance.GetConnectState(HandType.Left) && !HandleControllerManager.Instance.GetConnectState(HandType.Right)) { isHandlesStandby = true; Debug.Log($"ControllerManager, OnApplicationResume(Handles Standby) ChangeControllerType: {CurrentActiveControllerType}, dynamicMode: {dynamicMode} ({Time.frameCount})"); } } else { switch (m_ControllerType) { case ControllerType.Helmet: Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Head"); break; case ControllerType.HandTracking: Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Hand"); break; case ControllerType.Controllers: Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Controllers"); break; } } HandleControllerSession.Instance.ChangeControllerType((int)CurrentActiveControllerType); Debug.Log($"ControllerManager, OnApplicationResume(Inited) ChangeControllerType: {CurrentActiveControllerType}, dynamicMode: {dynamicMode} ({Time.frameCount})"); } else { //在上一应用时进入了待机模式(手柄算法会重置), //再Resume该应用时应通知Server同步到当前ControllerType StartCoroutine(CheckStatusWhenResume()); } } isPaused = pause; Debug.Log($"ControllerManager, OnApplicationPause isPaused: {isPaused}, dynamicMode: {dynamicMode} ({Time.frameCount})"); } // for fix private IEnumerator CheckStatus() { yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); Debug.Log($"ControllerManager, rightHand check ConnectState: {HandleControllerManager.Instance.GetConnectState(HandType.Right)}"); if (HandleControllerManager.Instance.GetConnectState(HandType.Left) || HandleControllerManager.Instance.GetConnectState(HandType.Right)) { //StartCoroutineChangeToHandleController()); } } private IEnumerator CheckStatusWhenResume() { yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); HandleControllerSession.Instance.ChangeControllerType((int)CurrentActiveControllerType); Debug.Log($"ControllerManager, OnApplicationResume(UnInit) ChangeControllerType: {CurrentActiveControllerType}, dynamicMode: {dynamicMode} ({Time.frameCount})"); } /// /// 动态模式初始化时,指定控制器类型 /// public void InitDynamicMode(ControllerType type) { StartCoroutine(InitDynamicMode_Coroutine(type)); } /// /// 开启动态模式,自动热切换 /// public void EnableDynamicMode() { StartCoroutine(EnableDynamicMode_Coroutine()); } /// /// 禁用动态模式时,指定控制器类型 /// /// public void DisableDynamicMode(ControllerType type) { StartCoroutine(DisableDynamicMode_Coroutine(type)); } private IEnumerator InitDynamicMode_Coroutine(ControllerType type) { yield return new WaitUntil(() => isInited); if (!dynamicMode) yield break; if (type == ControllerType.HandTracking) { if (isPaused) yield break; if (m_ControllerType == ControllerType.HandTracking) yield break; m_ControllerType = ControllerType.HandTracking; leftHand = ARHandManager.leftHand; rightHand = ARHandManager.rightHand; HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); HandleControllerManager.Instance.SetActive(false); ARHandManager.Instance.SetActive(true & isActive); Debug.Log($"ControllerManager, InitDynamicMode Change to GestureController, leftHand = {leftHand.GetType().Name}, rightHand = {rightHand.GetType().Name} ({Time.frameCount})"); } else if (type == ControllerType.Controllers) { //手柄未连接时从纯手柄应用切回launcher,强制置为手势 if (!HandleControllerManager.Instance.GetConnectState(HandType.Left) && !HandleControllerManager.Instance.GetConnectState(HandType.Right)) { if (m_ControllerType == ControllerType.HandTracking) yield break; m_ControllerType = ControllerType.HandTracking; leftHand = ARHandManager.leftHand; rightHand = ARHandManager.rightHand; HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); HandleControllerManager.Instance.SetActive(false); ARHandManager.Instance.SetActive(true & isActive); Debug.Log($"ControllerManager, OnApplicationResume Change to GestureController ({Time.frameCount})"); Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); } else { if (isPaused) yield break; if (m_ControllerType == ControllerType.Controllers) yield break; m_ControllerType = ControllerType.Controllers; leftHand = HandleControllerManager.leftHand; rightHand = HandleControllerManager.rightHand; HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); ARHandManager.Instance.SetActive(false); HandleControllerManager.Instance.SetActive(true & isActive); Debug.Log($"ControllerManager, InitDynamicMode Change to HandleController, leftHand = {leftHand.GetType().Name}, rightHand = {rightHand.GetType().Name} ({Time.frameCount})"); } } } private IEnumerator EnableDynamicMode_Coroutine() { yield return new WaitUntil(() => isInited); dynamicMode = true; Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); } private IEnumerator DisableDynamicMode_Coroutine(ControllerType type) { yield return new WaitUntil(() => isInited); dynamicMode = false; switch (type) { case ControllerType.Helmet: StartCoroutine(ChangeToHelmetController()); break; case ControllerType.HandTracking: StartCoroutine(ChangeToGestureController()); break; case ControllerType.Controllers: StartCoroutine(ChangeToHandleController()); break; } } /// /// 手柄连接状态改变 /// /// /// private void OnHandleConnectChanged(HandType handType, bool connected) { if (!dynamicMode) return; if (isPaused) return; Debug.Log($"ControllerManager, {handType} OnHandleConnectChanged, connected = {connected} ({Time.frameCount})"); if (connected) { StartCoroutine(ChangeToHandleController()); } else { if (!HandleControllerManager.Instance.GetConnectState(HandType.Left) && !HandleControllerManager.Instance.GetConnectState(HandType.Right)) { keepHandlesActive = false; StartCoroutine(ChangeToGestureController()); } } } /// /// 手柄按键状态改变 /// /// /// private void OnHandleButtonChanged(HandType handType, bool pressed) { if (!dynamicMode) return; if (isPaused) return; //Debug.Log($"ControllerManager, {handType} OnHandleButtonChanged, pressed = {pressed} ({Time.frameCount})"); StartCoroutine(ChangeToHandleController()); //按键按住过程中,保持手柄功能激活 keepHandlesActive = pressed; } /// /// 手柄握持状态改变 /// /// /// private void OnHandleHoldChanged(HandType handType, bool isHeld) { if (!dynamicMode) return; if (isPaused) return; //Debug.Log($"ControllerManager, {handType} OnHandleHoldChanged, isHeld = {isHeld} ({Time.frameCount})"); StartCoroutine(ChangeToHandleController()); //手柄握持过程中,保持手柄功能激活 keepHandlesActive = isHeld; } /// /// 手柄静置状态改变 /// /// /// private void OnHandleSilenceChanged(HandType handType, bool silent) { if (!dynamicMode) return; if (isPaused) return; //Debug.Log($"ControllerManager, {handType} OnHandleSilenceChanged, silent = {silent} ({Time.frameCount})"); if (silent && !keepHandlesActive) { StartCoroutine(ChangeToGestureController()); } } /// /// (手柄算法)Server重连 /// /// private void OnServerReconnected(bool connected) { Debug.Log($"ControllerManager, OnServerReconnected, connected = {connected} ({Time.frameCount})"); if (connected && isInited) { //在Server重启后应通知Server同步到当前ControllerType StartCoroutine(CheckStatusWhenResume()); } } /// /// (眼镜系统)进入待机状态 /// private void OnServerStandby() { isGlassStandby = true; Debug.Log($"ControllerManager, OnServerSleep, isGlassStandby = {isGlassStandby} ({Time.frameCount})"); } private IEnumerator ChangeToHelmetController() { if (isPaused) yield break; if (m_ControllerType == ControllerType.Helmet) yield break; //TODO if (dynamicMode) Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); else Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Head"); yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); } private IEnumerator ChangeToGestureController() { if (isPaused) yield break; if (m_ControllerType == ControllerType.HandTracking) yield break; m_ControllerType = ControllerType.HandTracking; leftHand = ARHandManager.leftHand; rightHand = ARHandManager.rightHand; //HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); HandleControllerManager.Instance.SetActive(false); ARHandManager.Instance.SetActive(true & isActive); Debug.Log($"ControllerManager, Change to GestureController, leftHand = {leftHand.GetType().Name}, rightHand = {rightHand.GetType().Name} ({Time.frameCount})"); //Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Hand"); if (dynamicMode) Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); else Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Hand"); yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); } private IEnumerator ChangeToHandleController() { if (isPaused) yield break; if (m_ControllerType == ControllerType.Controllers) yield break; m_ControllerType = ControllerType.Controllers; leftHand = HandleControllerManager.leftHand; rightHand = HandleControllerManager.rightHand; //HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); ARHandManager.Instance.SetActive(false); HandleControllerManager.Instance.SetActive(true & isActive); Debug.Log($"ControllerManager, Change to HandleController, leftHand = {leftHand.GetType().Name}, rightHand = {rightHand.GetType().Name} ({Time.frameCount})"); //Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Controllers"); if (dynamicMode) Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Dynamic"); else Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "ControllerType", Application.identifier + "," + "Controllers"); yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited); HandleControllerSession.Instance.ChangeControllerType((int)m_ControllerType); } } }