using System.Collections.Generic; using UnityEngine; using DG.Tweening; public class Arrow : MonoBehaviour { private Rigidbody newRigidbody; public Vector3 shootOutPosition; public float flyTime = 0; public bool isHit = false; public RaycastHit raycastHit; private float mySpeed = 0; public bool simulatedParabola = false; //模拟抛物线 public ArmBow armBow; public static float speed = GameMgr.RealSizeToGameSize(60); void Awake() { GameMgr.ins.gameMode.PauseTimeCounting(this); } void Start() { newRigidbody = this.gameObject.AddComponent(); mySpeed = speed; if (GameAssistUI.ins) { mySpeed *= (1 + GameAssistUI.ins.shootScaleValue); } //瞄准靶子发射时,自动调整仰角 if (raycastHit.transform && raycastHit.transform.gameObject.name == "TargetBody") { ApplyParabolaAngle(raycastHit.point); float distance = TargetBody.ins.GetDistance(); if (Mathf.RoundToInt(distance) >= 50) { if (Random.value < 0.5) simulatedParabola = true; } } newRigidbody.velocity = this.transform.forward * mySpeed; newRigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; Transform cameraTF = this.transform.Find("Camera"); cameraTF.gameObject.SetActive(true); cameraTF.gameObject.AddComponent().arrow = this; this.activeEffectTrail(true); } void ApplyParabolaAngle(Vector3 destination) { float angleX = 0; float distX = Vector2.Distance( new Vector2(destination.x, destination.z), new Vector2(this.transform.position.x, this.transform.position.z) ); float distY = destination.y - this.transform.position.y; float posBase = (Physics.gravity.y * Mathf.Pow(distX, 2.0f)) / (2.0f * Mathf.Pow(mySpeed, 2.0f)); float posX = distX / posBase; float posY = (Mathf.Pow(posX, 2.0f) / 4.0f) - ((posBase - distY) / posBase); bool paoshe = false; if (posY >= 0.0f) { if (paoshe) angleX = Mathf.Rad2Deg * Mathf.Atan(-posX / 2.0f + Mathf.Pow(posY, 0.5f)); else angleX = Mathf.Rad2Deg * Mathf.Atan(-posX / 2.0f - Mathf.Pow(posY, 0.5f)); } else { return; } Vector3 finalAngle = this.transform.eulerAngles; finalAngle = new Vector3(-angleX, finalAngle.y, finalAngle.z); this.transform.localRotation = Quaternion.Euler(finalAngle); } void OnDestroy() { GameMgr.ins.gameMode.ResumeTimeCounting(this); if (this.newRigidbody) { Destroy(this.newRigidbody); } } Vector3 position; Quaternion rotation; void FixedUpdate() { if (newRigidbody) { transform.forward = newRigidbody.velocity.normalized; } if (!isHit && flyTime >= 0) { flyTime += Time.deltaTime; this.position = this.transform.position; this.rotation = this.transform.rotation; if (flyTime > 14) { Destroy(gameObject); GameMgr.ins.gameMode.HitTarget(0); AudioMgr.ins.PlayCheer(false); nextShoot(); } this.UpdateRotate(); } // this.UpdateShake(); } public void Hit() { gameObject.GetComponent().enabled = false; if (newRigidbody) { newRigidbody.useGravity = false; newRigidbody.velocity = Vector3.zero; Destroy(newRigidbody); newRigidbody = null; } isHit = true; // this.Shake(); this.activeEffectCyclone(false); this.activeEffectBomb(true); this.activeEffectTrail(false); } public Vector3 getHeadPosition() { return this.transform.Find("Head").position; } /**箭矢旋转 */ private Vector3 rotateV3 = new Vector3(0, 0, 1400); private void UpdateRotate() { this.transform.Find("Head").Rotate(rotateV3 * Time.deltaTime, Space.Self); } /**箭矢震动 */ private bool shaking = false; private float shakeTime = 0; private float shakeTimeMax = 0.5f; private float shakeRange = 5; private int shakeDirection = 1; private Vector3 shakeAngles = new Vector3(); private void Shake() { this.shaking = true; this.shakeTime = 0; this.shakeDirection = 1; } private void UpdateShake() { if (!this.shaking) { return; } Transform transform = this.transform.Find("Head").transform; float shakeRangeNow = (1 - this.shakeTime / this.shakeTimeMax) * this.shakeRange; if (shakeRangeNow <= 0) {//震动结束 this.shaking = false; this.shakeAngles.x = 0; } else { this.shakeAngles.x = -this.shakeDirection * shakeRangeNow; this.shakeDirection *= -1; } transform.localEulerAngles = this.shakeAngles; this.shakeTime += Time.deltaTime; } //进入下一轮射击 bool hasDoneNextShoot = false; public void nextShoot() { if (hasDoneNextShoot) return; hasDoneNextShoot = true; GameMgr.ins.gameMode.ResumeTimeCounting(this); if (!GameMgr.ins.gameMode.DoNextShoot()) return; this.armBow.readyShoot(); } void OnCollisionEnter(Collision collision) { if ((1 << collision.gameObject.layer) != LayerMask.GetMask("Target")) { this.Hit(); GameMgr.ins.gameMode.HitTarget(0); AudioMgr.ins.PlayCheer(false); } this.transform.SetParent(collision.transform.parent); } public void activeEffectCyclone(bool value) { this.transform.Find("Head/EF_kuosanquan").gameObject.SetActive(value); if (!value) return; ParticleSystemRenderer ps = this.transform.Find("Head/EF_kuosanquan/kuosan").GetComponent(); ParticleSystemRenderer ps1 = this.transform.Find("Head/EF_kuosanquan/kuosan (1)").GetComponent(); DOTween.To(() => ps.minParticleSize, value => { ps.minParticleSize = value; ps.maxParticleSize = value; }, 0.4f, 0.6f); DOTween.To(() => ps1.minParticleSize, value => { ps1.minParticleSize = value; ps1.maxParticleSize = value; }, 0.8f, 0.6f); } void activeEffectBomb(bool value) { this.transform.Find("Head/EF_baodian").gameObject.SetActive(value); } void activeEffectTrail(bool value) { this.transform.Find("EF_tuowei").gameObject.SetActive(value); this.transform.Find("EF_tuowei/Trail").GetComponent().time = 1.6f / mySpeed; } }