Files
AliceBall/Assets/_Alice/Scripts/Task/BattleTask/EggBullet.cs
2025-07-25 14:30:55 +08:00

222 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
// 计算当前处于哪个“段”和在该段内的进度 t0~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) = (1t)²P0 + 2(1t)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);
}
}