SB_EventSystem.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using JC.Unity;
  6. /**SmartBow_事件系统 */
  7. public class SB_EventSystem : MonoBehaviour
  8. {
  9. public static SB_EventSystem ins;
  10. MouseTest mouseTest;
  11. void Awake()
  12. {
  13. if (ins) {
  14. Destroy(this.gameObject);
  15. } else {
  16. ins = this;
  17. DontDestroyOnLoad(this.gameObject);
  18. AwakenSimulateMouse();
  19. }
  20. }
  21. void Start() {
  22. mouseTest = new MouseTest(this);
  23. InitListenerForMouseClickHightColor();
  24. }
  25. void Update() {
  26. UpdateMoveSimulateMouse();
  27. mouseTest.Update();
  28. }
  29. [SerializeField] SimulateMouse simulateMouse;
  30. #region 客户要求鼠标点到按钮时,按钮高亮
  31. Graphic lockGraphic = null;
  32. Color pointerClickColor = Color.yellow;
  33. void InitListenerForMouseClickHightColor() {
  34. simulateMouse.OnPointerClick += (Selectable target) => {
  35. if (lockGraphic) return;
  36. Button btn = target.GetComponent<Button>();
  37. if (btn.transition != Selectable.Transition.ColorTint) return;
  38. if (btn.targetGraphic) {
  39. Graphic graphic = btn.targetGraphic;
  40. lockGraphic = graphic;
  41. Color oldColor = graphic.color;
  42. graphic.color = pointerClickColor;
  43. DoTweenUtil.CallDelay(0.3f, () => {
  44. lockGraphic = null;
  45. graphic.color = oldColor;
  46. });
  47. }
  48. };
  49. }
  50. #endregion
  51. #region 鼠标激活/关闭
  52. [System.NonSerialized] public bool simulateMouseIsAwaked;
  53. public void AwakenSimulateMouse() {
  54. simulateMouseIsAwaked = !simulateMouse.gameObject.activeSelf;
  55. simulateMouse.gameObject.SetActive(simulateMouseIsAwaked);
  56. hasAxisQuat = false;
  57. try {
  58. GlobalEventCenter.ins.onSimulateMouseAwakeChanged?.Invoke(simulateMouseIsAwaked);
  59. } catch (System.Exception e) { Debug.LogError(e.Message); }
  60. }
  61. #endregion 鼠标激活/关闭
  62. #region 模拟鼠标移动
  63. Vector3 targetNormalVector;
  64. Quaternion targetAxisQuat;
  65. Quaternion nowAxisQuat;
  66. bool hasAxisQuat;
  67. public void MoveSimulateMouse(Quaternion axisQuat) {
  68. if (clickCooling) { //点击就是射出,射出会产生抖动,防止接收抖动后的数据
  69. hasAxisQuat = false;
  70. return;
  71. }
  72. //格式化
  73. Vector3 normalVector = axisQuat * Vector3.forward; //得出对应的法向量
  74. axisQuat = Quaternion.LookRotation(normalVector); //变回四元组,主要作用是规范,去除z轴影响
  75. if (hasAxisQuat) {
  76. //法向量的z从+到-或从-到+,都会导致y轴转180度,也就是x轴旋转从<90跨越>90时触发的问题,这种情况要避免
  77. if (
  78. normalVector.z <= 0 && targetNormalVector.z >= 0 ||
  79. normalVector.z >= 0 && targetNormalVector.z <= 0
  80. ) {
  81. hasAxisQuat = false; //重置
  82. return;
  83. }
  84. //ok
  85. targetAxisQuat = axisQuat;
  86. targetNormalVector = normalVector;
  87. } else {
  88. nowAxisQuat = targetAxisQuat = axisQuat;
  89. targetNormalVector = normalVector;
  90. hasAxisQuat = true;
  91. }
  92. }
  93. Vector2 deltaVectorForMouse;
  94. void UpdateMoveSimulateMouse() {
  95. if (!simulateMouseIsAwaked) return;
  96. if (hasAxisQuat) {
  97. Vector3 lastAngle = nowAxisQuat.eulerAngles;
  98. nowAxisQuat = Quaternion.Lerp(nowAxisQuat, targetAxisQuat, Time.deltaTime * 8f);
  99. Vector3 curAngle = nowAxisQuat.eulerAngles;
  100. float dx = FormatDeltaAngleY(curAngle.y - lastAngle.y) / 150f * simulateMouse.GetScaleScreenWidth();
  101. float dy = -FormatDeltaAngleX(curAngle.x - lastAngle.x) / 100f * simulateMouse.GetScaleScreenHeight();
  102. deltaVectorForMouse.x = dx;
  103. deltaVectorForMouse.y = dy;
  104. simulateMouse.MoveMousePointer(deltaVectorForMouse);
  105. }
  106. }
  107. float FormatDeltaAngleX(float value)
  108. {
  109. return FormatDeltaAngleY(value);
  110. }
  111. float FormatDeltaAngleY(float value)
  112. {
  113. if (Mathf.Abs(value) > 180) {
  114. if (value < 0) {
  115. return 360f + value;
  116. }
  117. if (value > 0) {
  118. return value - 360f;
  119. }
  120. }
  121. return value;
  122. }
  123. #endregion 模拟鼠标移动
  124. //点击鼠标
  125. bool clickCooling = false; //防止高频连续多次点击
  126. public void ClickMouse() {
  127. if (clickCooling) return;
  128. clickCooling = true;
  129. DoTweenUtil.CallDelay(0.3f, () => {
  130. clickCooling = false;
  131. });
  132. simulateMouse.ClickMousePointer();
  133. }
  134. //鼠标居中
  135. public void MakeMouseToScreenCenter() {
  136. hasAxisQuat = false;
  137. simulateMouse.MakeMouseToScreenCenter();
  138. }
  139. /** 鼠标测试类 */
  140. class MouseTest {
  141. SB_EventSystem es;
  142. float mouseTestSensitivity = 3f;
  143. bool mouseTest = false; //开启测试-开关
  144. public MouseTest(SB_EventSystem es) {
  145. this.es = es;
  146. }
  147. public void Update() {
  148. if (mouseTest) {
  149. if (Input.GetKey(KeyCode.A)) {
  150. es.deltaVectorForMouse.x = -mouseTestSensitivity;
  151. }
  152. else if (Input.GetKey(KeyCode.D)) {
  153. es.deltaVectorForMouse.x = +mouseTestSensitivity;
  154. } else {
  155. es.deltaVectorForMouse.x = 0;
  156. }
  157. if (Input.GetKey(KeyCode.W)) {
  158. es.deltaVectorForMouse.y = +mouseTestSensitivity;
  159. }
  160. else if (Input.GetKey(KeyCode.S)) {
  161. es.deltaVectorForMouse.y = -mouseTestSensitivity;
  162. } else {
  163. es.deltaVectorForMouse.y = 0;
  164. }
  165. es.simulateMouse.MoveMousePointer(es.deltaVectorForMouse);
  166. if (Input.GetKeyDown(KeyCode.E)) {
  167. es.AwakenSimulateMouse();
  168. }
  169. if (Input.GetKeyDown(KeyCode.R)) {
  170. es.simulateMouse.ClickMousePointer();
  171. }
  172. }
  173. }
  174. }
  175. }