KeyBoardSelector.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. using UnityEngine.UI;
  6. using System.Linq;
  7. public class KeyBoardSelector : MonoBehaviour
  8. {
  9. Button _lastSelectBtn;
  10. List<Button> _selectables = new();
  11. EventSystem _eventSystem;
  12. PointerEventData _pointerEventData;
  13. public bool doing = false;
  14. private float _lastAutoSetFirstBtnTime;
  15. public static KeyBoardSelector ins;
  16. void Start()
  17. {
  18. ins = this;
  19. _eventSystem = FindObjectOfType<EventSystem>();
  20. _pointerEventData = new PointerEventData(_eventSystem);
  21. gameObject.AddComponent<KeyBoardInterface>();
  22. }
  23. void Update()
  24. {
  25. if (doing)
  26. {
  27. RefreshLastSelectBtn();
  28. if (SB_EventSystem.ins.simulateMouseIsAwaked)
  29. {
  30. if (!IsBtnCanReach(_lastSelectBtn)) Quit();
  31. }
  32. else
  33. {
  34. if (!IsLastBtnValid()) Quit();
  35. }
  36. }
  37. else
  38. {
  39. if (Time.realtimeSinceStartup - _lastAutoSetFirstBtnTime > 0.2)
  40. {
  41. _lastAutoSetFirstBtnTime = Time.realtimeSinceStartup;
  42. RefreshLastSelectBtn();
  43. if (SB_EventSystem.ins.simulateMouseIsAwaked)
  44. {
  45. if (!IsBtnCanReach(_lastSelectBtn)) SetFirstSelectBtn();
  46. }
  47. else
  48. {
  49. if (!IsLastBtnValid()) SetFirstSelectBtn();
  50. }
  51. }
  52. }
  53. }
  54. public void Quit()
  55. {
  56. doing = false;
  57. SB_EventSystem.ins.mouseConfirm.Hide();
  58. }
  59. public void Enter()
  60. {
  61. RefreshLastSelectBtn();
  62. SB_EventSystem.ins.mouseConfirm.OnClikc_Confirm(false);
  63. }
  64. public void HandleInput(int delta)
  65. {
  66. doing = true;
  67. RefreshLastSelectBtn();
  68. UpdateSelectables();
  69. if (IsLastBtnValid())
  70. {
  71. Button nextOne = KeyBoardNavigation.Next(_lastSelectBtn, delta);
  72. if (nextOne == null) return;
  73. _lastSelectBtn = nextOne;
  74. SB_EventSystem.ins.mouseConfirm.SetSelectable(_lastSelectBtn);
  75. }
  76. else
  77. {
  78. if (_selectables.Count > 0)
  79. {
  80. Button nextOne = KeyBoardNavigation.Next(_selectables[0], delta, true);
  81. if (nextOne == null) return;
  82. _lastSelectBtn = nextOne;
  83. SB_EventSystem.ins.mouseConfirm.SetSelectable(_lastSelectBtn);
  84. }
  85. }
  86. }
  87. void SetFirstSelectBtn()
  88. {
  89. doing = true;
  90. RefreshLastSelectBtn();
  91. UpdateSelectables();
  92. if (_selectables.Count > 0)
  93. {
  94. Button nextOne = KeyBoardNavigation.Next(_selectables[0], 1, true);
  95. if (nextOne == null) return;
  96. _lastSelectBtn = nextOne;
  97. SB_EventSystem.ins.mouseConfirm.SetSelectable(_lastSelectBtn);
  98. }
  99. }
  100. void UpdateSelectables()
  101. {
  102. _selectables.Clear();
  103. Button[] buttons = FindObjectsOfType<Button>();
  104. List<RaycastResult> raycastResults = new List<RaycastResult>();
  105. foreach (var btn in buttons)
  106. {
  107. if (!btn.interactable) continue;
  108. _pointerEventData.position = JCUnityLib.RectTransformUtils.GetPositionByPivot(btn.transform as RectTransform, Vector2.one * 0.5f);
  109. _eventSystem.RaycastAll(_pointerEventData, raycastResults);
  110. Selectable selectable;
  111. if (raycastResults.Count > 0 && raycastResults[0].gameObject && (selectable = raycastResults[0].gameObject.GetComponentInParent<Selectable>()) && selectable == btn && KeyBoardNavigation.IsNavigationButton(selectable.GetComponent<Button>()))
  112. {
  113. _selectables.Add(btn);
  114. }
  115. }
  116. }
  117. bool IsLastBtnValid()
  118. {
  119. if (!_lastSelectBtn) return false;
  120. if (!_lastSelectBtn.interactable) return false;
  121. List<RaycastResult> raycastResults = new List<RaycastResult>();
  122. _pointerEventData.position = JCUnityLib.RectTransformUtils.GetPositionByPivot(_lastSelectBtn.transform as RectTransform, Vector2.one * 0.5f);
  123. _eventSystem.RaycastAll(_pointerEventData, raycastResults);
  124. Selectable selectable;
  125. if (raycastResults.Count > 0 && raycastResults[0].gameObject && (selectable = raycastResults[0].gameObject.GetComponentInParent<Selectable>()) && selectable == _lastSelectBtn && KeyBoardNavigation.IsNavigationButton(selectable.GetComponent<Button>()))
  126. {
  127. return true;
  128. }
  129. return false;
  130. }
  131. bool IsBtnCanReach(Button btn)
  132. {
  133. if (!btn || !btn.interactable || !btn.gameObject || !btn.gameObject.activeInHierarchy) return false;
  134. List<RaycastResult> raycastResults = new List<RaycastResult>();
  135. _pointerEventData.position = JCUnityLib.RectTransformUtils.GetPositionByPivot(btn.transform as RectTransform, Vector2.one * 0.5f);
  136. _eventSystem.RaycastAll(_pointerEventData, raycastResults);
  137. if (raycastResults.Count == 0) return false;
  138. RaycastResult rs = raycastResults[0];
  139. if (!rs.gameObject) return false;
  140. Button rayHitBtn = rs.gameObject.GetComponentInParent<Button>();
  141. return btn == rayHitBtn;
  142. }
  143. void RefreshLastSelectBtn()
  144. {
  145. if (SB_EventSystem.ins.mouseConfirm._targetSelectable) _lastSelectBtn = SB_EventSystem.ins.mouseConfirm._targetSelectable.GetComponent<Button>();
  146. else _lastSelectBtn = null;
  147. }
  148. }
  149. //public class KeyBoardSelector : MonoBehaviour
  150. //{
  151. // Button _lastSelectBtn;
  152. // List<Button> _selectables = new();
  153. // EventSystem _eventSystem;
  154. // PointerEventData _pointerEventData;
  155. // public bool doing = false;
  156. // public static KeyBoardSelector ins;
  157. // void Start()
  158. // {
  159. // ins = this;
  160. // _eventSystem = FindObjectOfType<EventSystem>();
  161. // _pointerEventData = new PointerEventData(_eventSystem);
  162. // gameObject.AddComponent<KeyBoardInterface>();
  163. // }
  164. // void Update()
  165. // {
  166. // if (doing)
  167. // {
  168. // RefreshLastSelectBtn();
  169. // if (!IsLastBtnValid()) Quit();
  170. // }
  171. // }
  172. // public void Quit()
  173. // {
  174. // doing = false;
  175. // SB_EventSystem.ins.mouseConfirm.Hide();
  176. // }
  177. // public void Enter()
  178. // {
  179. // RefreshLastSelectBtn();
  180. // SB_EventSystem.ins.mouseConfirm.OnClikc_Confirm(false);
  181. // }
  182. // public void HandleInput(Vector2 pointer)
  183. // {
  184. // doing = true;
  185. // RefreshLastSelectBtn();
  186. // UpdateSelectables();
  187. // if (IsLastBtnValid())
  188. // {
  189. // Vector2 curPos = JCUnityLib.RectTransformUtils.GetPositionByPivot(_lastSelectBtn.transform as RectTransform, Vector2.one * 0.5f);
  190. // var selectableList = _selectables.FindAll(b => b != _lastSelectBtn && Vector2.Angle(pointer, (Vector2)JCUnityLib.RectTransformUtils.GetPositionByPivot(b.transform as RectTransform, Vector2.one * 0.5f) - curPos) <= 45);
  191. // if (selectableList.Count == 0)
  192. // {
  193. // //重新筛选
  194. // _selectables = _selectables.FindAll(b => b != _lastSelectBtn && Vector2.Angle(pointer, (Vector2)JCUnityLib.RectTransformUtils.GetPositionByPivot(b.transform as RectTransform, Vector2.one * 0.5f) - curPos) <= 80);
  195. // _selectables = _selectables.OrderBy(b => Vector2.Angle(pointer, (Vector2)JCUnityLib.RectTransformUtils.GetPositionByPivot(b.transform as RectTransform, Vector2.one * 0.5f) - curPos))
  196. // .ThenBy(b => Vector2.Distance(JCUnityLib.RectTransformUtils.GetPositionByPivot(b.transform as RectTransform, Vector2.one * 0.5f), curPos))
  197. // .ToList();
  198. // }
  199. // else
  200. // {
  201. // _selectables = selectableList.OrderBy(b => Vector2.Distance(JCUnityLib.RectTransformUtils.GetPositionByPivot(b.transform as RectTransform, Vector2.one * 0.5f), curPos)).ToList();
  202. // }
  203. // if (_selectables.Count > 0)
  204. // {
  205. // _lastSelectBtn = _selectables[0];
  206. // SB_EventSystem.ins.mouseConfirm.SetSelectable(_lastSelectBtn);
  207. // }
  208. // }
  209. // else
  210. // {
  211. // if (_selectables.Count > 0)
  212. // {
  213. // Vector2 centerPoint = new Vector2(Screen.width, Screen.height) / 2f;
  214. // _selectables.Sort((a, b) =>
  215. // {
  216. // return Vector2.Distance(a.transform.position, centerPoint) - Vector2.Distance(b.transform.position, centerPoint) < 0 ? -1 : 1;
  217. // });
  218. // _lastSelectBtn = _selectables[0];
  219. // SB_EventSystem.ins.mouseConfirm.SetSelectable(_lastSelectBtn);
  220. // }
  221. // }
  222. // }
  223. // void UpdateSelectables()
  224. // {
  225. // _selectables.Clear();
  226. // Button[] buttons = FindObjectsOfType<Button>();
  227. // List<RaycastResult> raycastResults = new List<RaycastResult>();
  228. // foreach (var btn in buttons)
  229. // {
  230. // if (!btn.interactable) continue;
  231. // _pointerEventData.position = JCUnityLib.RectTransformUtils.GetPositionByPivot(btn.transform as RectTransform, Vector2.one * 0.5f);
  232. // _eventSystem.RaycastAll(_pointerEventData, raycastResults);
  233. // Selectable selectable;
  234. // if (raycastResults.Count > 0 && raycastResults[0].gameObject && (selectable = raycastResults[0].gameObject.GetComponentInParent<Selectable>()) && selectable == btn)
  235. // {
  236. // _selectables.Add(btn);
  237. // }
  238. // }
  239. // }
  240. // bool IsLastBtnValid()
  241. // {
  242. // if (!_lastSelectBtn) return false;
  243. // if (!_lastSelectBtn.interactable) return false;
  244. // List<RaycastResult> raycastResults = new List<RaycastResult>();
  245. // _pointerEventData.position = JCUnityLib.RectTransformUtils.GetPositionByPivot(_lastSelectBtn.transform as RectTransform, Vector2.one * 0.5f);
  246. // _eventSystem.RaycastAll(_pointerEventData, raycastResults);
  247. // Selectable selectable;
  248. // if (raycastResults.Count > 0 && raycastResults[0].gameObject && (selectable = raycastResults[0].gameObject.GetComponentInParent<Selectable>()) && selectable == _lastSelectBtn)
  249. // {
  250. // return true;
  251. // }
  252. // return false;
  253. // }
  254. // void RefreshLastSelectBtn()
  255. // {
  256. // if (SB_EventSystem.ins.mouseConfirm._targetSelectable) _lastSelectBtn = SB_EventSystem.ins.mouseConfirm._targetSelectable.GetComponent<Button>();
  257. // else _lastSelectBtn = null;
  258. // }
  259. //}