using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class AimCrossHair : MonoBehaviour { public Camera mainCamera; [NonSerialized] public bool outboundLeft; [NonSerialized] public bool outboundRight; [NonSerialized] public bool outboundUp; [NonSerialized] public bool outboundDown; public static AimCrossHair Instance; void Start() { Instance = this; int currentShootLevel = UserSettings.ins.shootLevel; shootBackTime = new int[] { 0, 2, 5 }[currentShootLevel]; shootOffsetAngleScale = new float[] { 0, 10f, 10f }[currentShootLevel]; } void OnDestroy() { if (Instance == this) Instance = null; } void Update() { if (GetPlayerIndex() == 0) { UpdatePositionByModuleRotation(mouseTest.Update(0),new Vector4(0,Screen.width*0.5f,Screen.height,0)); if (Input.GetKeyDown(KeyCode.Q)) Shoot(); } else if (GetPlayerIndex() == 1) { UpdatePositionByModuleRotation(mouseTest.Update(1), new Vector4(Screen.width*0.5f, Screen.width, Screen.height, 0)); if (Input.GetKeyDown(KeyCode.E)) Shoot(); } if (GameController.ins.gameStart && !GameController.ins.gameOver) { transform.localScale = Vector3.one; } else transform.localScale = Vector3.zero; } int GetPlayerIndex() { return Array.IndexOf(GameController.ins.aimCrossHairs, this); } MouseTest mouseTest = new MouseTest(); class MouseTest { Quaternion quat = Quaternion.identity; float moveSensitivity = 30; public Quaternion Update(int type) { if (type == 0) { if (Input.GetKey(KeyCode.A)) { quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.up) * quat; } else if (Input.GetKey(KeyCode.D)) { quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.up) * quat; } else if (Input.GetKey(KeyCode.W)) { quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.right) * quat; } else if (Input.GetKey(KeyCode.S)) { quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.right) * quat; } } else if (type == 1) { if (Input.GetKey(KeyCode.LeftArrow)) { quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.up) * quat; } else if (Input.GetKey(KeyCode.RightArrow)) { quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.up) * quat; } else if (Input.GetKey(KeyCode.UpArrow)) { quat = Quaternion.AngleAxis(-moveSensitivity * Time.deltaTime, Vector3.right) * quat; } else if (Input.GetKey(KeyCode.DownArrow)) { quat = Quaternion.AngleAxis(moveSensitivity * Time.deltaTime, Vector3.right) * quat; } } return quat; } } Quaternion currentRotation = Quaternion.identity; public void UpdatePositionByModuleRotation(Quaternion moduleRotation,Vector4 bound) { // 限制模块欧拉角范围 Vector3 moduleAngles = moduleRotation.eulerAngles; moduleAngles.x = Mathf.Clamp(moduleAngles.x > 180 ? moduleAngles.x - 360 : moduleAngles.x, -80, 80); moduleAngles.y = Mathf.Clamp(moduleAngles.y > 180 ? moduleAngles.y - 360 : moduleAngles.y, -80, 80); moduleRotation = Quaternion.Euler(moduleAngles); currentRotation = moduleRotation; // 计算准心的世界旋转 Quaternion rotation = mainCamera.transform.rotation * moduleRotation; // 计算准心的世界方向 Vector3 direction = rotation * Vector3.forward; // 计算准心的世界坐标 Vector3 position = mainCamera.transform.position + direction; // 转为屏幕坐标 Vector3 screenPos = mainCamera.WorldToScreenPoint(position); // 标记是否超出屏幕边界 outboundLeft = screenPos.x < bound.x;//0 outboundRight = screenPos.x > bound.y;//Screen.width outboundUp = screenPos.y > bound.z;//Screen.height outboundDown = screenPos.y < bound.w; //0 // 根据需要的范围进行限制 screenPos.x = Mathf.Clamp(screenPos.x, bound.x, bound.y); //x->y screenPos.y = Mathf.Clamp(screenPos.y, bound.w, bound.z); //w->z // 设置准心的位置 transform.position = screenPos; } //射箭姿态记录索引倒退数,根据射击难度制造误差 [NonSerialized] public int shootBackTime = 0; [NonSerialized] public float shootOffsetAngleScale = 0; //过去几帧的镜头值记录 Quaternion[] cameraRotations = new Quaternion[6]; int cameraRotationHasRecordCount = 0; public void Shoot(float shootSpeedNow = 60f) { if (!GameController.ins.gameStart || GameController.ins.gameOver) return; #region Quaternion absolute_rotation = currentRotation; Quaternion final_rotation = currentRotation; if (cameraRotationHasRecordCount >= cameraRotations.Length) { absolute_rotation = cameraRotations[5]; final_rotation = cameraRotations[5 - this.shootBackTime]; } #endregion Quaternion oldCameraRotation = currentRotation; currentRotation = absolute_rotation; RaycastHit absoluteRay = GetRaycastHit(); currentRotation = oldCameraRotation; Vector3 shootOutPosition = mainCamera.transform.position + currentRotation * Vector3.forward * 1f; Vector3 arrowEuler = absolute_rotation.eulerAngles; arrowEuler.z = 0; //绝对角可能是从原始九轴记录数组里取出来的,它的z可能不是0 //生成两种箭 GameObject perfab = GetPlayerIndex() == 0 ? GameController.ins.arrowPrefab : GameController.ins.arrowSecondPrefab; GameObject arrowCopy = Instantiate(perfab, shootOutPosition, Quaternion.Euler(arrowEuler)); ArrowNew arrowComp = arrowCopy.AddComponent(); arrowComp.playerIndex = GetPlayerIndex(); arrowComp.shootOffsetAngleScale = shootOffsetAngleScale; arrowComp.shootOutPosition = shootOutPosition; arrowComp.absoluteRay = absoluteRay; arrowComp.offsetAngle = GameDebug.ins ? GameDebug.ins.GetOffsetAngle() : Quaternion.Angle(absolute_rotation, final_rotation); arrowComp.finalAngleAfterOffset = final_rotation.eulerAngles; ArrowNew.speed = GameMgr.RealSizeToGameSize(shootSpeedNow); //GameEventCenter.ins.onBowArrowShootOut?.Invoke(this, arrowComp); AudioMgr.ins.PlayShoot(AudioMgr.GetAudioSource(arrowCopy)); //if (AimHandler.ins) AimHandler.ins.Ban9AxisCalculate(true); } public RaycastHit GetRaycastHit() { float maxDistance = 100; int layerMask = 1 << 8; //TargetLayerMask if (GetPlayerIndex() == 0) { layerMask = 1 << 6; } else if (GetPlayerIndex() == 1) { layerMask = 1 << 7; } RaycastHit raycastHit; Ray ray = new Ray(mainCamera.transform.position, currentRotation * Vector3.forward); Physics.Raycast(ray.origin, ray.direction, out raycastHit, maxDistance, layerMask); return raycastHit; } private void ChangeLayer(Transform transform, string layer) { if (transform.childCount > 0)//如果子物体存在 { for (int i = 0; i < transform.childCount; i++)//遍历子物体是否还有子物体 { ChangeLayer(transform.GetChild(i), layer);//这里是只将最后一个无子物体的对象设置层级 } transform.gameObject.layer = LayerMask.NameToLayer(layer);//将存在的子物体遍历结束后需要把当前子物体节点进行层级设置 } else //无子物体 { transform.gameObject.layer = LayerMask.NameToLayer(layer); } if (transform.name == "_hunse_jian") { Debug.Log(transform.gameObject.layer); } } }