using System; using System.Collections; using System.Collections.Generic; using UnityEngine; /* 弓对象 */ public class ArmBowDoublePlayer : MonoBehaviour { //玩家 [Header("当前脚本属于的玩家是?")] public PlayerType playerType = PlayerType.FirstPlayer; [SerializeField] AnimationPlayer AP_arm; [SerializeField] AnimationPlayer AP_bow; [SerializeField] public GameObject arrow; [SerializeField] GameObject armObj; [SerializeField] GameObject bowObj; [SerializeField] GameObject bullet; BowCameraDoublePlayer _bowCamera; BowCameraDoublePlayer bowCamera { get { if (!_bowCamera) _bowCamera = GetComponentInParent(); return _bowCamera; } } //有效射击目标集合,可以理解为射中集合中的目标才能得分 public HashSet validTargets = new HashSet(); //本地坐标z public const float localPosZ = -0.1f; //射箭姿态记录索引倒退数,根据射击难度制造误差 [NonSerialized] public int shootBackTime = 0; [NonSerialized] public float shootOffsetAngleScale = 0; //禁止准备的外部接口 [NonSerialized] public bool banReady = false; //禁止射击的外部接口 [NonSerialized] public bool banShoot = false; //禁止逻辑,只用于同步状态和渲染,目前用于联机 [NonSerialized] public bool banLogic = false; //过去几帧的镜头值记录 Quaternion[] cameraRotations = new Quaternion[6]; int cameraRotationHasRecordCount = 0; #region logic state [NonSerialized] public int phase = -1; //当前阶段 void UpdatePhase() { if (phase == -1) return; if (phase == 0) { //拉弓前的准备 if (arm_ani_index_cur != 0) { AP_arm.play(arm_ani_index_cur = 0, WrapMode.Once); AP_arm.completeCallback = onComplete; } if (bow_ani_index_cur != 0) { AP_bow.play(bow_ani_index_cur = 0, WrapMode.Once); } } else if (phase == 1) { //拉弓过程 if (arm_ani_index_cur != 2) { AP_arm.play(arm_ani_index_cur = 2, WrapMode.Once); AP_arm.completeCallback = onComplete; } if (bow_ani_index_cur != 2) { AP_bow.play(bow_ani_index_cur = 2, WrapMode.Once); } this.bowCamera.updateFollowPullBow(); } else if (phase == 2) { //拉完完成,等待发射 if (arm_ani_index_cur != 2) { AP_arm.play(arm_ani_index_cur = 2, WrapMode.Once); AP_arm.completeCallback = onComplete; } if (bow_ani_index_cur != 2) { AP_bow.play(bow_ani_index_cur = 2, WrapMode.Once); } } else if (phase == 3) { //射出后 if (arm_ani_index_cur != 3) { AP_arm.play(arm_ani_index_cur = 3, WrapMode.Once); AP_arm.completeCallback = onComplete; } if (bow_ani_index_cur != 3) { AP_bow.play(bow_ani_index_cur = 3, WrapMode.Once); } } if (!IsCanShoot()) { this.bowCamera.updateGiveUpPullBow(); } } void onComplete(AnimationPlayerCompleteResult res) { if (res.index == 0 && !banLogic) { this.phase = 1; } else if (res.index == 2 && !banLogic) { this.phase = 2; // slambb todo // GameMgr.ins.gameMode.ResumeTimeCounting(this); } } public bool IsCanShoot() { return phase == 2 && !bowCamera.GetArrowFollowing(); } #endregion #region display state int arm_ani_index_cur = -1; int bow_ani_index_cur = -1; #endregion void Awake() { this.transform.localPosition = new Vector3(0.0865f, -1.692f, -0.1f); //initdata Vector3 localPos = transform.localPosition; localPos.z = localPosZ; transform.localPosition = localPos; int currentShootLevel = UserSettings.ins.shootLevel; shootBackTime = new int[] { 0, 2, 5 }[currentShootLevel]; shootOffsetAngleScale = new float[] { 0, 10f, 10f }[currentShootLevel]; //根据 hideInfraredBowAndArrow 判断是否显示隐藏 //双人模式下先不处理 armObj.SetActive(UserSettings.ins.openBowAndArrow); bowObj.SetActive(UserSettings.ins.openBowAndArrow); } void Start() { this.readyShoot(); } void OnDestroy() { } void OnEnable() { AudioMgr.GetAudioSource(this.gameObject).clip = null; } void Update() { UpdatePhase(); #if UNITY_EDITOR if (playerType == PlayerType.FirstPlayer) { if (Input.GetKeyDown(KeyCode.Q)) this.ADS_fire(true); } else { if (Input.GetKeyDown(KeyCode.E)) this.ADS_fire(true); } #endif } void FixedUpdate() { // 记录一些旋转角---start if (this.bowCamera) { for (int i = cameraRotations.Length - 1; i > 0; i--) { cameraRotations[i] = cameraRotations[i - 1]; } cameraRotations[0] = this.bowCamera.transform.rotation; cameraRotationHasRecordCount++; } // 记录一些旋转角---end } public void readyShoot() { if (banLogic) return; this.bowCamera.SetCameraFieldOfViewRecord(this.bowCamera.defaultCameraFieldOfView); if (banReady) return; // GameMgr.ins.gameMode.PauseTimeCounting(this); // GameMgr.ins.gameMode.onBowReady(); this.phase = 0; } public void ADS_fire(bool bAddCount = false, float shootSpeedNow = 60f) { Debug.Log("GameController.ins.gameOver:"+GameController.ins.gameOver); if (!IsCanShoot() || banShoot || banLogic || GameController.ins.gameOver) return; //枪模式连接的情况下需要判断子弹 if (Billboard.ins && Billboard.ins.isBulletStatus) { if (playerType == PlayerType.FirstPlayer) { if (Billboard.ins.bulletManager.bulletZero(playerType)) return; //发射消耗子弹 Billboard.ins.bulletManager.FireBullet(); } else { if (Billboard.ins.bulletManagerSecond.bulletZero(playerType)) return; //发射消耗子弹 Billboard.ins.bulletManagerSecond.FireBullet(); } } //记录射箭 this.phase = 3; //这里使用的是AimCrossHair //GameController.ins.aimCrossHairs[playerType == PlayerType.FirstPlayer ? 0 : 1].Shoot(this,shootSpeedNow); shoot(shootSpeedNow); } void shoot(float shootSpeedNow = 60f) { #region Quaternion absolute_rotation = this.bowCamera.transform.rotation; Quaternion final_rotation = this.bowCamera.transform.rotation; if (cameraRotationHasRecordCount >= cameraRotations.Length) { absolute_rotation = cameraRotations[5]; final_rotation = cameraRotations[5 - this.shootBackTime]; } #endregion //BowCameraDoublePlayer bowCamera = GameController.ins.GetBowCameraDoublePlayer(playerType); Quaternion oldCameraRotation = bowCamera.transform.rotation; bowCamera.transform.rotation = absolute_rotation; RaycastHit absoluteRay = GameController.ins.GetAimCrossHair(playerType).GetRaycastHit(); bowCamera.transform.rotation = oldCameraRotation; Vector3 shootOutPosition = bowCamera.transform.position; Vector3 arrowEuler = absolute_rotation.eulerAngles; arrowEuler.z = 0; //绝对角可能是从原始九轴记录数组里取出来的,它的z可能不是0 //GameObject arrowCopy = GameObject.Instantiate(this.arrow, shootOutPosition, Quaternion.Euler(arrowEuler)); GameObject arrowCopy = Instantiate(GlobalData.MyDeviceMode == DeviceMode.Archery ? arrow : bullet, shootOutPosition, Quaternion.Euler(arrowEuler)); arrowCopy.SetActive(true); //子弹层级 if(GlobalData.MyDeviceMode == DeviceMode.Gun) SetLayerRecursively(arrowCopy,playerType == PlayerType.FirstPlayer?20:21); Vector3 s1 = arrowCopy.transform.localScale; Vector3 s2 = bowCamera.transform.localScale; arrowCopy.transform.localScale = new Vector3(s1.x * s2.x, s1.y * s2.y, s1.z * s2.z); ArrowNew2 arrowComp = arrowCopy.AddComponent(); arrowComp.armBow = this; arrowComp.playerIndex = playerType == PlayerType.FirstPlayer ? 0:1; arrowComp.shootOutPosition = shootOutPosition; arrowComp.absoluteRay = absoluteRay; arrowComp.offsetAngle = GameDebug.ins ? GameDebug.ins.GetOffsetAngle() : Quaternion.Angle(absolute_rotation, final_rotation); arrowComp.finalAngleAfterOffset = final_rotation.eulerAngles; if (!GameController.ins.debugInEditor && !GameController.ins.GetBowCameraDoublePlayer(playerType).isTouchMode) { ArrowNew2.speed = GameMgr.RealSizeToGameSize(shootSpeedNow); //if (playerType == PlayerType.FirstPlayer && ShootCheck.ins) { // Arrow.speed = GameMgr.RealSizeToGameSize(ShootCheck.ins.shootSpeed); //} //if (playerType == PlayerType.SecondPlayer) { // Arrow.speed = GameMgr.RealSizeToGameSize(shootSpeedNow); //} } //GameEventCenter.ins.onBowArrowShootOut?.Invoke(this, arrowComp); AudioMgr.ins.PlayShoot(AudioMgr.GetAudioSource(arrowCopy)); // if (AimHandler.ins) AimHandler.ins.Ban9AxisCalculate(true); } void SetLayerRecursively(GameObject obj, int layer) { obj.layer = layer; foreach (Transform child in obj.transform) { SetLayerRecursively(child.gameObject, layer); } } public void Hide() { this.transform.localScale = Vector3.zero; } public void Show() { this.transform.localScale = new Vector3(1, 1, 1); } }