SB_EventSystem.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. }
  58. #endregion 鼠标激活/关闭
  59. #region 模拟鼠标移动
  60. Vector3 targetNormalVector;
  61. Quaternion targetAxisQuat;
  62. Quaternion nowAxisQuat;
  63. bool hasAxisQuat;
  64. public void MoveSimulateMouse(Quaternion axisQuat) {
  65. if (clickCooling) { //点击就是射出,射出会产生抖动,防止接收抖动后的数据
  66. hasAxisQuat = false;
  67. return;
  68. }
  69. //格式化
  70. Vector3 normalVector = axisQuat * Vector3.forward; //得出对应的法向量
  71. axisQuat = Quaternion.LookRotation(normalVector); //变回四元组,主要作用是规范,去除z轴影响
  72. if (hasAxisQuat) {
  73. //法向量的z从+到-或从-到+,都会导致y轴转180度,也就是x轴旋转从<90跨越>90时触发的问题,这种情况要避免
  74. if (
  75. normalVector.z <= 0 && targetNormalVector.z >= 0 ||
  76. normalVector.z >= 0 && targetNormalVector.z <= 0
  77. ) {
  78. hasAxisQuat = false; //重置
  79. return;
  80. }
  81. //ok
  82. targetAxisQuat = axisQuat;
  83. targetNormalVector = normalVector;
  84. } else {
  85. nowAxisQuat = targetAxisQuat = axisQuat;
  86. targetNormalVector = normalVector;
  87. hasAxisQuat = true;
  88. }
  89. }
  90. Vector2 deltaVectorForMouse;
  91. void UpdateMoveSimulateMouse() {
  92. if (!simulateMouseIsAwaked) return;
  93. if (hasAxisQuat) {
  94. Vector3 lastAngle = nowAxisQuat.eulerAngles;
  95. nowAxisQuat = Quaternion.Lerp(nowAxisQuat, targetAxisQuat, Time.deltaTime * 15f);
  96. Vector3 curAngle = nowAxisQuat.eulerAngles;
  97. float dx = FormatDeltaAngleY(curAngle.y - lastAngle.y) / 150f * simulateMouse.GetScaleScreenWidth();
  98. float dy = -FormatDeltaAngleX(curAngle.x - lastAngle.x) / 150f * simulateMouse.GetScaleScreenHeight();
  99. deltaVectorForMouse.x = dx;
  100. deltaVectorForMouse.y = dy;
  101. simulateMouse.MoveMousePointer(deltaVectorForMouse);
  102. }
  103. }
  104. float FormatDeltaAngleX(float value)
  105. {
  106. return FormatDeltaAngleY(value);
  107. }
  108. float FormatDeltaAngleY(float value)
  109. {
  110. if (Mathf.Abs(value) > 180) {
  111. if (value < 0) {
  112. return 360f + value;
  113. }
  114. if (value > 0) {
  115. return value - 360f;
  116. }
  117. }
  118. return value;
  119. }
  120. #endregion 模拟鼠标移动
  121. //点击鼠标
  122. bool clickCooling = false; //防止高频连续多次点击
  123. public void ClickMouse() {
  124. if (clickCooling) return;
  125. clickCooling = true;
  126. DoTweenUtil.CallDelay(0.3f, () => {
  127. clickCooling = false;
  128. });
  129. simulateMouse.ClickMousePointer();
  130. }
  131. //鼠标居中
  132. public void MakeMouseToScreenCenter() {
  133. simulateMouse.MakeMouseToScreenCenter();
  134. }
  135. /** 鼠标测试类 */
  136. class MouseTest {
  137. SB_EventSystem es;
  138. float mouseTestSensitivity = 3f;
  139. bool mouseTest = false; //开启测试-开关
  140. public MouseTest(SB_EventSystem es) {
  141. this.es = es;
  142. }
  143. public void Update() {
  144. if (mouseTest) {
  145. if (Input.GetKey(KeyCode.A)) {
  146. es.deltaVectorForMouse.x = -mouseTestSensitivity;
  147. }
  148. else if (Input.GetKey(KeyCode.D)) {
  149. es.deltaVectorForMouse.x = +mouseTestSensitivity;
  150. } else {
  151. es.deltaVectorForMouse.x = 0;
  152. }
  153. if (Input.GetKey(KeyCode.W)) {
  154. es.deltaVectorForMouse.y = +mouseTestSensitivity;
  155. }
  156. else if (Input.GetKey(KeyCode.S)) {
  157. es.deltaVectorForMouse.y = -mouseTestSensitivity;
  158. } else {
  159. es.deltaVectorForMouse.y = 0;
  160. }
  161. es.simulateMouse.MoveMousePointer(es.deltaVectorForMouse);
  162. if (Input.GetKeyDown(KeyCode.E)) {
  163. es.AwakenSimulateMouse();
  164. }
  165. if (Input.GetKeyDown(KeyCode.R)) {
  166. es.simulateMouse.ClickMousePointer();
  167. }
  168. }
  169. }
  170. }
  171. }