using System.Collections; using System.Collections.Generic; using UnityEngine; public class ArmBow : MonoBehaviour { [SerializeField] AnimationPlayer AP_arm; [SerializeField] AnimationPlayer AP_bow; [SerializeField] GameObject arrow; [SerializeField] BowCamera bowCamera; public HashSet validTargets = new HashSet(); private bool canShoot = false; private bool pulling = false; private bool readying = false; public static ArmBow ins; public Quaternion[] recordRotations = new Quaternion[100]; public float[] recordRotationVars = new float[99]; public int recordCount = 0; void Start() { ins = this; this.readyShoot(); } void OnDestroy() { ins = null; } void FixedUpdate() { if (this.canShoot) { if (DebugBowPower.ins) DebugBowPower.ins.DoUpdate(); } } void Update() { if (Input.GetKeyDown(KeyCode.Q)) { this.ADS_fire(); } if (this.pulling) { this.bowCamera.updateFollowPullBow(); } else if (!this.canShoot) { this.bowCamera.updateGiveUpPullBow(); } CrossHair.ins.gameObject.SetActive(this.canShoot); } void onComplete(AnimationPlayerCompleteResult res) { if (res.index == 0) { this.readying = true; this.idle(); this.Invoke("idleToADS", 0.1f); } else if (res.index == 2) { this.ADS_idle(); } } void ready() { this.arrow.SetActive(true); AP_arm.play(0, WrapMode.Once); AP_bow.play(0, WrapMode.Once); AP_arm.completeCallback = onComplete; this.pulling = false; this.canShoot = false; } void idle() { AP_arm.play(1, WrapMode.Loop); AP_bow.play(1, WrapMode.Loop); AP_arm.completeCallback = null; this.pulling = false; this.canShoot = false; if (DebugBowPower.ins) DebugBowPower.ins.Init(); } public void idleToADS() { AP_arm.play(2, WrapMode.Once); AP_bow.play(2, WrapMode.Once); AP_arm.completeCallback = onComplete; this.pulling = true; this.canShoot = false; } void ADS_idle() { this.canShoot = true; this.pulling = false; if (DebugBowPower.ins) DebugBowPower.ins.PullFinish(); } public void ADS_fire() { if (!canShoot) return; this.pulling = false; this.canShoot = false; this.readying = false; AP_arm.play(3, WrapMode.Once); AP_bow.play(3, WrapMode.Once); AP_arm.completeCallback = null; this.arrow.SetActive(false); this.Invoke("shoot", 0.1f); } public void readyShoot() { this.bowCamera.setFieldOfView(60, false); this.gameObject.SetActive(true); this.ready(); } public void shoot() { // Vector3 rayHitPoint = CrossHair.ins.getRayHitPoint(); // 筛选出一个稳定的发射角度---start Quaternion best_rotation = this.bowCamera.transform.rotation; if (recordCount >= recordRotations.Length) { int single_check_count = 6; float min_wave = float.MaxValue; for (int i = 0; i < recordRotationVars.Length; i++) { recordRotationVars[i] = Quaternion.Angle(recordRotations[i], recordRotations[i + 1]); if (i >= single_check_count - 1) { float wave = 0; for (int j = i; j > i - single_check_count; j--) { wave += recordRotationVars[j]; } if (wave < min_wave) { min_wave = wave; best_rotation = recordRotations[i - single_check_count + 1]; } } } } // 筛选出一个稳定的发射角度---end GameObject arrowCopy = GameObject.Instantiate(this.arrow, this.bowCamera.transform.position, best_rotation); 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); // arrowCopy.transform.LookAt(rayHitPoint); Arrow arrowComp = arrowCopy.AddComponent(); arrowComp.armBow = this; // Arrow.speed = DebugBowPower.ins.getPowerPercent() * 100f; // Arrow.speed = BaseSpeedSlider.ins.getValue(); // Arrow.speed = Mathf.Pow(ShootCheck.ins.shootSpeed, ShootCheck.ins.shootSpeed < 13 ? 2f: (ShootCheck.ins.shootSpeed < 15 ? 2.5f : 3.0f)); if (ShootCheck.ins) { Arrow.speed = ShootCheck.ins.shootSpeed / 16 * 80; } arrowCopy.SetActive(true); arrow.SetActive(false); AudioMgr.ins.PlayShoot(AudioMgr.GetAudioSource(arrowCopy)); this.gameObject.SetActive(false); } public void OnEnable() { AudioMgr.GetAudioSource(this.gameObject).clip = null; } //debug public void mouseDown() { if (!this.readying) return; if (this.pulling || this.canShoot) return; this.idleToADS(); } public void mouseUp() { if (!this.readying) return; if (this.pulling) { this.idle(); } else if (this.canShoot) { this.ADS_fire(); } } }