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);
}
}
}