using System; using System.Collections; using System.Collections.Generic; using DG.Tweening; using DragonLi.Core; using UnityEngine; using Random = UnityEngine.Random; public enum EggBulletType { EnemyType, PlayerType, } public class EggBullet : MonoBehaviour { public EggBulletType type; public bool isDie; public bool isStop; private Transform _enemyTran; private Transform _playerTran; public enum FlyMode { Straight=1, Bouncing=2, CurvedFromSide=3 } [Header("Common Settings")] public FlyMode flyMode = FlyMode.Straight; public Vector3 target; private float speed = 3f; private float speed2 = 1.5f; private float speed3 = 0.5f; private float arrivalThreshold = 0.1f; // 到达目标的容差 [Header("Bouncing Mode Settings")] private int bounceCount = 2; // 弹跳次数 private float bounceHeight = 1.5f; // 弹跳高度 [Header("Curved Mode Settings")] private float sideOffset = 1; // 起始侧向偏移 private float curveHeight = 0.5f; // 弧线高度 public bool startFromLeft = true; // 从左侧还是右侧 private Vector3 startPos; private Vector3 endPos; private float startTime; private float journeyLength; public void Init() { type = EggBulletType.EnemyType; isDie = false; int id = Random.Range(1, 4); flyMode = (FlyMode)id; _enemyTran = GameManager.Ins.enemy.body; _playerTran = GameLocal.Ins.self.transform; float targetX = Random.Range(-1f,2); Vector3 curTarget=_playerTran.position+new Vector3(targetX,0,0); Launch(curTarget); } public void ChangeType(EggBulletType curType) { type = curType; } private void OnTriggerEnter(Collider other) { if (other.tag == "Skillet"&& type == EggBulletType.EnemyType) { ChangeType(EggBulletType.PlayerType); flyMode=FlyMode.Straight; speed = 6f; Launch(_enemyTran.position); GameManager.Ins.playerRightHand.ShowSkilletEx(); } } public void Hit() { isDie = true; Destroy(gameObject); } // 发射方法 public void Launch( Vector3 targetTransform) { target = targetTransform; startPos = transform.position; _vector3Start = GameManager.Ins.enemy.hand.position; if (flyMode == FlyMode.CurvedFromSide) { // 计算侧向起点 Vector3 dirToTarget = (target - transform.position).normalized; Vector3 sideDir = startFromLeft ? -Vector3.Cross(dirToTarget, Vector3.up) : Vector3.Cross(dirToTarget, Vector3.up); startPos = target + sideDir * sideOffset; transform.position = startPos; } endPos = target; startTime = Time.time; journeyLength = Vector3.Distance(startPos, endPos); } private void Update() { float distToEndPos = Vector3.Distance(transform.position.ReflectVectorXOZ(), endPos.ReflectVectorXOZ()); float disToTarget= Vector3.Distance(transform.position.ReflectVectorXOZ(), target.ReflectVectorXOZ()); if (disToTarget <= arrivalThreshold) { if (type == EggBulletType.PlayerType) { GameManager.Ins.EnemyHit(transform.position); } int index= Random.Range(0, 2); if (type == EggBulletType.EnemyType&&index==0) { GameManager.Ins.PlayerHit(); } Hit(); return; } if (distToEndPos <= arrivalThreshold&& type== EggBulletType.EnemyType) { // 到达目标,停止或销毁 OnArrival(); return; } switch (flyMode) { case FlyMode.Straight: FlyStraight(); break; case FlyMode.Bouncing: FlyBouncing(); break; case FlyMode.CurvedFromSide: FlyCurved(); break; } } void FlyStraight() { float frac = (Time.time - startTime) * speed / journeyLength; transform.position = Vector3.Lerp(startPos, endPos, frac); } void FlyBouncing() { // 总共分成:1 段下落 + bounceCount 段弹跳 int segments = bounceCount + 1; float frac = (Time.time - startTime) * speed2 / journeyLength; frac = Mathf.Clamp01(frac); // 水平线性插值 Vector3 horizontalPos = Vector3.Lerp(startPos, endPos, frac); // 计算当前处于哪个“段”和在该段内的进度 t(0~1) float segmentLength = 1f / segments; int segIndex = Mathf.Min((int)(frac / segmentLength), segments - 1); float t = (frac - segIndex * segmentLength) / segmentLength; float y; if (segIndex == 0) { // 初始下落:用半个余弦曲线 y = startY * cos(t * PI/2) y = startPos.y * Mathf.Cos(t * (Mathf.PI / 2)); } else { // 弹跳段:用正弦波 y = sin(t * PI) * bounceHeight y = Mathf.Sin(t * Mathf.PI) * bounceHeight; } // 最终位置 transform.position = new Vector3(horizontalPos.x, y, horizontalPos.z); } private Vector3 _vector3Start; void FlyCurved() { // 进度 0→1 float frac = (Time.time - startTime) * speed3 / journeyLength; frac = Mathf.Clamp01(frac); // 起点和终点 Vector3 P0 = _vector3Start; Vector3 P2 = endPos; // 计算侧向方向(和水平面法线叉乘) Vector3 dir = (P2 - P0).normalized; Vector3 sideDir = startFromLeft ? -Vector3.Cross(dir, Vector3.up) : Vector3.Cross(dir, Vector3.up); // 控制点:在中点向侧面偏移,并抬高 curveHeight Vector3 mid = Vector3.Lerp(P0, P2, 0.5f); Vector3 P1 = mid + sideDir * sideOffset + Vector3.up * curveHeight; // 二次贝塞尔公式 B(t) = (1−t)²P0 + 2(1−t)tP1 + t²P2 float u = 1 - frac; Vector3 pos = u*u * P0 + 2*u*frac * P1 + frac*frac * P2; transform.position = pos; } // 到达目标的回调,可扩展 protected virtual void OnArrival() { // 例如:爆炸、伤害、销毁等 //Destroy(gameObject); Debug.Log("删除鸡蛋"); if(!isDie) Destroy(gameObject); } }