HandleControllerManager.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using EZXR.Glass.Core;
  5. using EZXR.Glass.Inputs;
  6. using UnityEngine;
  7. namespace EZXR.Glass.Inputs
  8. {
  9. public enum HandleKeyEvent
  10. {
  11. Idle, //默认状态
  12. Down, //按下(仅单帧有效)
  13. Up, //弹起(仅单帧有效)
  14. /// <summary>
  15. /// (feat)等同于长按
  16. /// Down之后每帧有效
  17. /// </summary>
  18. PrePressed, //介于按下和长按之间状态
  19. Pressing //长按(每帧有效)
  20. }
  21. [ScriptExecutionOrder(-49)]
  22. public class HandleControllerManager : MonoBehaviour
  23. {
  24. #region singleton
  25. private static HandleControllerManager instance;
  26. public static HandleControllerManager Instance
  27. {
  28. get
  29. {
  30. return instance;
  31. }
  32. }
  33. #endregion
  34. /// <summary>
  35. /// 记录了左手柄的所有信息
  36. /// </summary>
  37. public static ControllerInfo leftHand;
  38. /// <summary>
  39. /// 记录了右手柄的所有信息
  40. /// </summary>
  41. public static ControllerInfo rightHand;
  42. // 手柄模型
  43. public Transform leftController;
  44. public Transform rightController;
  45. private List<Action<HandType, bool>> bindingActions = new List<Action<HandType, bool>>();
  46. private List<Action<HandType, bool>> connectedActions = new List<Action<HandType, bool>>();
  47. private List<Action<HandType, float>> powerChangedActions = new List<Action<HandType, float>>();
  48. private List<Action<HandType, bool>> holdChangedActions = new List<Action<HandType, bool>>();
  49. private List<Action<HandType, bool>> silenceChangedActions = new List<Action<HandType, bool>>();
  50. private List<Action<HandType, bool>> buttonChangedActions = new List<Action<HandType, bool>>();
  51. private List<Action<HandType, int>> trackingChangedActions = new List<Action<HandType, int>>();
  52. /// <summary>
  53. /// 由外部逻辑控制手的射线的方向
  54. /// </summary>
  55. /// <param name="controllerInfo"></param>
  56. /// <param name="rayDir"></param>
  57. /// <returns></returns>
  58. public delegate bool Delegate_SetRayDataByExternal(ControllerInfo controllerInfo, ref Vector3 value);
  59. public static Delegate_SetRayDataByExternal SetRayDirByExternal;
  60. public static Delegate_SetRayDataByExternal SetRayStartPointByExternal;
  61. private void Awake()
  62. {
  63. instance = this;
  64. leftHand = leftController.GetComponent<ControllerInfo>();
  65. rightHand = rightController.GetComponent<ControllerInfo>();
  66. }
  67. private void Start()
  68. {
  69. HandleControllerSession.Instance.InitRegistration(OnBindingEventCallback, OnConnectEventCallback,
  70. OnButtonEventCallback, OnAxis2DEventCallback,
  71. OnHoldEventCallback, OnSilenceEventCallback,
  72. OnTrackingStateChangedCallback);
  73. if (leftHand != null)
  74. {
  75. // 初始化手柄的生命状态
  76. leftHand.Init(HandType.Left);
  77. }
  78. if (rightHand != null)
  79. {
  80. // 初始化手柄的生命状态
  81. rightHand.Init(HandType.Right);
  82. }
  83. StartCoroutine(WaitForTimeout());
  84. }
  85. private void Update()
  86. {
  87. //if (Input.GetKeyDown(KeyCode.Q))
  88. // Debug.Log($"HandleControllerManager, rightHand binding = {rightController != null && rightHand.Exist}, controllerPose: ({HandleControllerSession.controllerPose_right.position.x}, {HandleControllerSession.controllerPose_right.position.y}, {HandleControllerSession.controllerPose_right.position.z})");
  89. if (leftHand.Exist || rightHand.Exist)
  90. HandleControllerSession.Instance.UpdateHandlePose();
  91. if (leftController != null && leftHand.Exist)
  92. leftController.SetLocalPositionAndRotation(HandleControllerSession.controllerPose_left.position, HandleControllerSession.controllerPose_left.rotation);
  93. if (rightController != null && rightHand.Exist)
  94. rightController.SetLocalPositionAndRotation(HandleControllerSession.controllerPose_right.position, HandleControllerSession.controllerPose_right.rotation);
  95. }
  96. /// <summary>
  97. /// 初始化注册,监听手柄生命状态
  98. /// </summary>
  99. /// <param name="bindingEventCallback">绑定状态改变的回调事件</param>
  100. /// <param name="connectedEventCallback">连接状态改变的回调事件</param>
  101. /// <param name="powerChangedCallback">电量改变的回调事件</param>
  102. public void InitRegistration(Action<HandType, bool> bindingEventCallback, Action<HandType, bool> connectedEventCallback, Action<HandType, float> powerChangedCallback)
  103. {
  104. InitRegistration(bindingEventCallback, connectedEventCallback, powerChangedCallback, null, null, null);
  105. }
  106. /// <summary>
  107. /// 初始化注册,监听手柄生命状态
  108. /// </summary>
  109. /// <param name="bindingEventCallback">绑定状态改变的回调事件</param>
  110. /// <param name="connectedEventCallback">连接状态改变的回调事件</param>
  111. /// <param name="powerChangedCallback">电量改变的回调事件</param>
  112. /// <param name="trackingStateChangedCallback">跟踪状态改变的回调事件(3/6dof)</param>
  113. public void InitRegistration(Action<HandType, bool> bindingEventCallback, Action<HandType, bool> connectedEventCallback, Action<HandType, float> powerChangedCallback, Action<HandType, int> trackingStateChangedCallback)
  114. {
  115. InitRegistration(bindingEventCallback, connectedEventCallback, powerChangedCallback, null, null, null);
  116. trackingChangedActions.Add(trackingStateChangedCallback);
  117. }
  118. /// <summary>
  119. /// 初始化注册,监听手柄生命状态
  120. /// </summary>
  121. /// <param name="bindingEventCallback">绑定状态改变的回调事件</param>
  122. /// <param name="connectedEventCallback">连接状态改变的回调事件</param>
  123. /// <param name="powerChangedCallback">电量改变的回调事件</param>
  124. /// <param name="buttonChangedCallback">按键状态改变的回调</param>
  125. /// <param name="holdChangedCallback">握持状态改变的回调</param>
  126. /// <param name="silenceChangedCallback">静置状态改变的回调</param>
  127. public void InitRegistration(Action<HandType, bool> bindingEventCallback,
  128. Action<HandType, bool> connectedEventCallback,
  129. Action<HandType, float> powerChangedCallback,
  130. Action<HandType, bool> buttonChangedCallback,
  131. Action<HandType, bool> holdChangedCallback,
  132. Action<HandType, bool> silenceChangedCallback)
  133. {
  134. bindingActions.Add(bindingEventCallback);
  135. connectedActions.Add(connectedEventCallback);
  136. powerChangedActions.Add(powerChangedCallback);
  137. silenceChangedActions.Add(silenceChangedCallback);
  138. holdChangedActions.Add(holdChangedCallback);
  139. buttonChangedActions.Add(buttonChangedCallback);
  140. }
  141. /// <summary>
  142. /// 进行手柄配对
  143. /// </summary>
  144. public bool BindHandle(HandType handType)
  145. {
  146. return HandleControllerSession.Instance.BindHandle((int)handType);
  147. }
  148. /// <summary>
  149. /// 取消手柄配对
  150. /// </summary>
  151. public bool UnbindHandle(HandType handType)
  152. {
  153. return HandleControllerSession.Instance.UnbindHandle((int)handType);
  154. }
  155. /// <summary>
  156. /// 手柄震动,震动等级 1-8,震动时长 0-65535 ms
  157. /// </summary>
  158. public bool VibrateHandle(HandType handType, int level, int time)
  159. {
  160. return HandleControllerSession.Instance.VibrateHandle((int)handType, level, time);
  161. }
  162. /// <summary>
  163. /// 获取手柄绑定状态
  164. /// </summary>
  165. /// <param name="handType"></param>
  166. /// <returns></returns>
  167. public bool GetBindState(HandType handType)
  168. {
  169. return HandleControllerSession.Instance.GetBindState(handType);
  170. }
  171. /// <summary>
  172. /// 获取手柄连接状态
  173. /// </summary>
  174. public bool GetConnectState(HandType handType)
  175. {
  176. return HandleControllerSession.Instance.GetConnectState((int)handType);
  177. }
  178. /// <summary>
  179. /// 获取手柄电量
  180. /// </summary>
  181. public float GetPowerStats(HandType handType)
  182. {
  183. return HandleControllerSession.Instance.GetPowerStats((int)handType);
  184. }
  185. /// <summary>
  186. /// 手柄按键是否按下
  187. /// </summary>
  188. public bool GetButtonDown(HandType handType, HandleKeyCode keyCode)
  189. {
  190. if (handType == HandType.Left)
  191. return leftHand.GetButtonDown(keyCode);
  192. else
  193. return rightHand.GetButtonDown(keyCode);
  194. }
  195. /// <summary>
  196. /// 手柄按键是否弹起
  197. /// </summary>
  198. public bool GetButtonUp(HandType handType, HandleKeyCode keyCode)
  199. {
  200. if (handType == HandType.Left)
  201. return leftHand.GetButtonUp(keyCode);
  202. else
  203. return rightHand.GetButtonUp(keyCode);
  204. }
  205. /// <summary>
  206. /// 手柄按键是否长按
  207. /// </summary>
  208. public bool GetButton(HandType handType, HandleKeyCode keyCode)
  209. {
  210. if (handType == HandType.Left)
  211. return leftHand.GetButton(keyCode);
  212. else
  213. return rightHand.GetButton(keyCode);
  214. }
  215. /// <summary>
  216. /// 获取手柄摇杆坐标
  217. /// </summary>
  218. /// <param name="handType">左手柄or右手柄</param>
  219. /// <returns>坐标范围[-1,-1]到[1,1],复位为[0,0]</returns>
  220. public Vector2 GetAxis2D(HandType handType)
  221. {
  222. if (handType == HandType.Left)
  223. return leftHand.GetAxis2D();
  224. else
  225. return rightHand.GetAxis2D();
  226. }
  227. // 控制器统一管理时,激活手柄功能
  228. public void SetActive(bool value)
  229. {
  230. //var controller = handType == HandType.Left ? leftController : rightController;
  231. //controller.GetComponent<InputRaycast>().enabled = true;
  232. //for (int i = 0; i < controller.childCount; i++)
  233. //{
  234. // controller.GetChild(i).gameObject.SetActive(true);
  235. //}
  236. gameObject.SetActive(value);
  237. if (value)
  238. {
  239. //(handType == HandType.Left ? leftController : rightController).gameObject.SetActive(false);
  240. //StartCoroutine(SetActive_WaitForSeconds(handType, value));
  241. //var handInfo = handType == HandType.Left ? leftHand : rightHand;
  242. //StartCoroutine(handInfo.CheckStatus());
  243. StartCoroutine(leftHand.CheckStatus());
  244. StartCoroutine(rightHand.CheckStatus());
  245. }
  246. }
  247. private IEnumerator SetActive_WaitForSeconds(HandType handType, bool value)
  248. {
  249. yield return new WaitForSeconds(1);
  250. (handType == HandType.Left ? leftController : rightController).gameObject.SetActive(value);
  251. }
  252. private void OnBindingEventCallback(HandType handType, bool status)
  253. {
  254. if (handType == HandType.Left)
  255. {
  256. leftHand.UpdateBindingState(status, _status =>
  257. {
  258. bindingActions.ForEach(action => { if (action != null) action(HandType.Left, _status); });
  259. });
  260. }
  261. else
  262. {
  263. rightHand.UpdateBindingState(status, _status =>
  264. {
  265. bindingActions.ForEach(action => { if (action != null) action(HandType.Right, _status); });
  266. });
  267. }
  268. }
  269. private void OnConnectEventCallback(HandType handType, bool connected)
  270. {
  271. if (handType == HandType.Left)
  272. {
  273. leftHand.UpdateConnectedState(connected, _connected =>
  274. {
  275. connectedActions.ForEach(action => { if (action != null) action(HandType.Left, _connected); });
  276. });
  277. }
  278. else
  279. {
  280. rightHand.UpdateConnectedState(connected, _connected =>
  281. {
  282. connectedActions.ForEach(action => { if (action != null) action(HandType.Right, _connected); });
  283. });
  284. }
  285. }
  286. private void OnPowerStatsChangedCallback(HandType handType, float power)
  287. {
  288. if (handType == HandType.Left)
  289. {
  290. leftHand.UpdatePowerStats(power, _power =>
  291. {
  292. powerChangedActions.ForEach(action => { if (action != null) action(HandType.Left, _power); });
  293. });
  294. }
  295. else
  296. {
  297. rightHand.UpdatePowerStats(power, _power =>
  298. {
  299. powerChangedActions.ForEach(action => { if (action != null) action(HandType.Right, _power); });
  300. });
  301. }
  302. }
  303. private void OnButtonEventCallback(HandType handType, HandleKeyCode keycode, bool pressed)
  304. {
  305. if (handType == HandType.Left)
  306. {
  307. leftHand.UpdateButtonState(keycode, pressed);
  308. buttonChangedActions.ForEach(action => { if (action != null) action(HandType.Left, pressed); });
  309. }
  310. else
  311. {
  312. rightHand.UpdateButtonState(keycode, pressed);
  313. buttonChangedActions.ForEach(action => { if (action != null) action(HandType.Right, pressed); });
  314. }
  315. }
  316. private void OnAxis2DEventCallback(HandType handType, Vector2 coord)
  317. {
  318. if (handType == HandType.Left)
  319. leftHand.UpdateAxis2D(coord);
  320. else
  321. rightHand.UpdateAxis2D(coord);
  322. }
  323. private void OnHoldEventCallback(HandType handType, HandleKeyCode keycode, bool isHeld)
  324. {
  325. if (handType == HandType.Left)
  326. {
  327. leftHand.UpdateHoldState(isHeld, _isHeld =>
  328. {
  329. holdChangedActions.ForEach(action => { if (action != null) action(HandType.Left, _isHeld); });
  330. });
  331. }
  332. else
  333. {
  334. rightHand.UpdateHoldState(isHeld, _isHeld =>
  335. {
  336. holdChangedActions.ForEach(action => { if (action != null) action(HandType.Right, _isHeld); });
  337. });
  338. }
  339. }
  340. private void OnSilenceEventCallback(HandType handType, bool silent)
  341. {
  342. if (handType == HandType.Left)
  343. {
  344. leftHand.UpdateSilenceState(silent, _silent =>
  345. {
  346. silenceChangedActions.ForEach(action => { if (action != null) action(HandType.Left, _silent); });
  347. });
  348. }
  349. else
  350. {
  351. rightHand.UpdateSilenceState(silent, _silent =>
  352. {
  353. silenceChangedActions.ForEach(action => { if (action != null) action(HandType.Right, _silent); });
  354. });
  355. }
  356. }
  357. private void OnTrackingStateChangedCallback(HandType handType, int state) //state 0: 6dof,1: 3dof
  358. {
  359. if (handType == HandType.Left)
  360. {
  361. trackingChangedActions.ForEach(action => { if (action != null) action(HandType.Left, state); });
  362. }
  363. else
  364. {
  365. trackingChangedActions.ForEach(action => { if (action != null) action(HandType.Right, state); });
  366. }
  367. }
  368. /// <summary>
  369. /// 定时刷新手柄电量
  370. /// </summary>
  371. /// <returns></returns>
  372. private IEnumerator WaitForTimeout()
  373. {
  374. yield return new WaitForSeconds(3);
  375. if (leftHand.Exist) OnPowerStatsChangedCallback(HandType.Left, GetPowerStats(HandType.Left));
  376. if (rightHand.Exist) OnPowerStatsChangedCallback(HandType.Right, GetPowerStats(HandType.Right));
  377. while (true)
  378. {
  379. yield return new WaitForSeconds(300);
  380. if (leftHand.Exist) OnPowerStatsChangedCallback(HandType.Left, GetPowerStats(HandType.Left));
  381. if (rightHand.Exist) OnPowerStatsChangedCallback(HandType.Right, GetPowerStats(HandType.Right));
  382. }
  383. }
  384. }
  385. }