AimCrossHair.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System;
  5. public class AimCrossHair : MonoBehaviour
  6. {
  7. public Camera mainCamera;
  8. [NonSerialized] public bool outboundLeft;
  9. [NonSerialized] public bool outboundRight;
  10. [NonSerialized] public bool outboundUp;
  11. [NonSerialized] public bool outboundDown;
  12. public static AimCrossHair Instance;
  13. void Start()
  14. {
  15. Instance = this;
  16. int currentShootLevel = UserSettings.ins.shootLevel;
  17. shootBackTime = new int[] { 0, 2, 5 }[currentShootLevel];
  18. shootOffsetAngleScale = new float[] { 0, 10f, 10f }[currentShootLevel];
  19. }
  20. void OnDestroy()
  21. {
  22. if (Instance == this) Instance = null;
  23. }
  24. void Update()
  25. {
  26. if (GetPlayerIndex() == 0)
  27. {
  28. UpdatePositionByModuleRotation(mouseTest.Update(0),new Vector4(0,Screen.width*0.5f,Screen.height,0));
  29. if (Input.GetKeyDown(KeyCode.Q)) Shoot();
  30. }
  31. else if (GetPlayerIndex() == 1)
  32. {
  33. UpdatePositionByModuleRotation(mouseTest.Update(1), new Vector4(Screen.width*0.5f, Screen.width, Screen.height, 0));
  34. if (Input.GetKeyDown(KeyCode.E)) Shoot();
  35. }
  36. if (GameController.ins.gameStart && !GameController.ins.gameOver)
  37. {
  38. transform.localScale = Vector3.one;
  39. }
  40. else transform.localScale = Vector3.zero;
  41. }
  42. int GetPlayerIndex()
  43. {
  44. return Array.IndexOf(GameController.ins.aimCrossHairs, this);
  45. }
  46. MouseTest mouseTest = new MouseTest();
  47. class MouseTest
  48. {
  49. Quaternion quat = Quaternion.identity;
  50. float moveSensitivity = 30;
  51. public Quaternion Update(int type)
  52. {
  53. if (type == 0)
  54. {
  55. if (Input.GetKey(KeyCode.A))
  56. {
  57. quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.up) * quat;
  58. }
  59. else if (Input.GetKey(KeyCode.D))
  60. {
  61. quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.up) * quat;
  62. }
  63. else if (Input.GetKey(KeyCode.W))
  64. {
  65. quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.right) * quat;
  66. }
  67. else if (Input.GetKey(KeyCode.S))
  68. {
  69. quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.right) * quat;
  70. }
  71. }
  72. else if (type == 1)
  73. {
  74. if (Input.GetKey(KeyCode.LeftArrow))
  75. {
  76. quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.up) * quat;
  77. }
  78. else if (Input.GetKey(KeyCode.RightArrow))
  79. {
  80. quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.up) * quat;
  81. }
  82. else if (Input.GetKey(KeyCode.UpArrow))
  83. {
  84. quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.right) * quat;
  85. }
  86. else if (Input.GetKey(KeyCode.DownArrow))
  87. {
  88. quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.right) * quat;
  89. }
  90. }
  91. return quat;
  92. }
  93. }
  94. Quaternion currentRotation = Quaternion.identity;
  95. public void UpdatePositionByModuleRotation(Quaternion moduleRotation,Vector4 bound)
  96. {
  97. // 限制模块欧拉角范围
  98. Vector3 moduleAngles = moduleRotation.eulerAngles;
  99. moduleAngles.x = Mathf.Clamp(moduleAngles.x > 180 ? moduleAngles.x - 360 : moduleAngles.x, -80, 80);
  100. moduleAngles.y = Mathf.Clamp(moduleAngles.y > 180 ? moduleAngles.y - 360 : moduleAngles.y, -80, 80);
  101. moduleRotation = Quaternion.Euler(moduleAngles);
  102. currentRotation = moduleRotation;
  103. // 计算准心的世界旋转
  104. Quaternion rotation = mainCamera.transform.rotation * moduleRotation;
  105. // 计算准心的世界方向
  106. Vector3 direction = rotation * Vector3.forward;
  107. // 计算准心的世界坐标
  108. Vector3 position = mainCamera.transform.position + direction;
  109. // 转为屏幕坐标
  110. Vector3 screenPos = mainCamera.WorldToScreenPoint(position);
  111. // 标记是否超出屏幕边界
  112. outboundLeft = screenPos.x < bound.x;//0
  113. outboundRight = screenPos.x > bound.y;//Screen.width
  114. outboundUp = screenPos.y > bound.z;//Screen.height
  115. outboundDown = screenPos.y < bound.w; //0
  116. // 根据需要的范围进行限制
  117. screenPos.x = Mathf.Clamp(screenPos.x, bound.x, bound.y); //x->y
  118. screenPos.y = Mathf.Clamp(screenPos.y, bound.w, bound.z); //w->z
  119. // 设置准心的位置
  120. transform.position = screenPos;
  121. }
  122. //射箭姿态记录索引倒退数,根据射击难度制造误差
  123. [NonSerialized] public int shootBackTime = 0;
  124. [NonSerialized] public float shootOffsetAngleScale = 0;
  125. //过去几帧的镜头值记录
  126. Quaternion[] cameraRotations = new Quaternion[6];
  127. int cameraRotationHasRecordCount = 0;
  128. public void Shoot(float shootSpeedNow = 60f)
  129. {
  130. if (!GameController.ins.gameStart || GameController.ins.gameOver) return;
  131. #region
  132. Quaternion absolute_rotation = currentRotation;
  133. Quaternion final_rotation = currentRotation;
  134. if (cameraRotationHasRecordCount >= cameraRotations.Length)
  135. {
  136. absolute_rotation = cameraRotations[5];
  137. final_rotation = cameraRotations[5 - this.shootBackTime];
  138. }
  139. #endregion
  140. Quaternion oldCameraRotation = currentRotation;
  141. currentRotation = absolute_rotation;
  142. RaycastHit absoluteRay = GetRaycastHit();
  143. currentRotation = oldCameraRotation;
  144. Vector3 shootOutPosition = mainCamera.transform.position + currentRotation * Vector3.forward * 1f;
  145. Vector3 arrowEuler = absolute_rotation.eulerAngles;
  146. arrowEuler.z = 0; //绝对角可能是从原始九轴记录数组里取出来的,它的z可能不是0
  147. //生成两种箭
  148. GameObject perfab = GetPlayerIndex() == 0 ? GameController.ins.arrowPrefab : GameController.ins.arrowSecondPrefab;
  149. GameObject arrowCopy = Instantiate(perfab, shootOutPosition, Quaternion.Euler(arrowEuler));
  150. ArrowNew arrowComp = arrowCopy.AddComponent<ArrowNew>();
  151. arrowComp.playerIndex = GetPlayerIndex();
  152. arrowComp.shootOffsetAngleScale = shootOffsetAngleScale;
  153. arrowComp.shootOutPosition = shootOutPosition;
  154. arrowComp.absoluteRay = absoluteRay;
  155. arrowComp.offsetAngle = GameDebug.ins ?
  156. GameDebug.ins.GetOffsetAngle() :
  157. Quaternion.Angle(absolute_rotation, final_rotation);
  158. arrowComp.finalAngleAfterOffset = final_rotation.eulerAngles;
  159. ArrowNew.speed = GameMgr.RealSizeToGameSize(shootSpeedNow);
  160. //GameEventCenter.ins.onBowArrowShootOut?.Invoke(this, arrowComp);
  161. AudioMgr.ins.PlayShoot(AudioMgr.GetAudioSource(arrowCopy));
  162. //if (AimHandler.ins) AimHandler.ins.Ban9AxisCalculate(true);
  163. }
  164. public RaycastHit GetRaycastHit()
  165. {
  166. float maxDistance = 100;
  167. int layerMask = 1 << 8; //TargetLayerMask
  168. if (GetPlayerIndex() == 0)
  169. {
  170. layerMask = 1 << 6;
  171. }
  172. else if (GetPlayerIndex() == 1)
  173. {
  174. layerMask = 1 << 7;
  175. }
  176. RaycastHit raycastHit;
  177. Ray ray = new Ray(mainCamera.transform.position, currentRotation * Vector3.forward);
  178. Physics.Raycast(ray.origin, ray.direction, out raycastHit, maxDistance, layerMask);
  179. return raycastHit;
  180. }
  181. private void ChangeLayer(Transform transform, string layer)
  182. {
  183. if (transform.childCount > 0)//如果子物体存在
  184. {
  185. for (int i = 0; i < transform.childCount; i++)//遍历子物体是否还有子物体
  186. {
  187. ChangeLayer(transform.GetChild(i), layer);//这里是只将最后一个无子物体的对象设置层级
  188. }
  189. transform.gameObject.layer = LayerMask.NameToLayer(layer);//将存在的子物体遍历结束后需要把当前子物体节点进行层级设置
  190. }
  191. else //无子物体
  192. {
  193. transform.gameObject.layer = LayerMask.NameToLayer(layer);
  194. }
  195. if (transform.name == "_hunse_jian") {
  196. Debug.Log(transform.gameObject.layer);
  197. }
  198. }
  199. }