using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
///
/// 精锐士兵技能:裂空突袭(刺客定位 · 1/3/6/10 级完整阶梯)
/// 1级【裂空突袭】:核心招牌直接解锁!第一帧立刻起跳,空中划出高抛物线,30帧(约0.95s)落地砸击敌方后排,造成 200% 暴击物理伤害(播放 SwordWaveWhite)
/// 3级【弱点锁定】:突袭伤害提升至 250%,暴击率额外 +25%,落地后 3 秒内自身移速 +35% 紧逼残血
/// 6级【影袭破防】:突袭下砸震碎防御,目标陷入【1.2 秒硬眩晕】(挂 StunStars)且受到物理伤害增加 35%(持续 4s)
/// 10级【死斗连环】:飞天斩若击杀目标,立即从当前落地点再次腾空飞斩下一个后排目标!最多连斩 3 次!
///
public class EliteSoldierSkill : UnitSkill
{
[Header("刺客飞跃参数")]
[Tooltip("飞跃最高拱起高度")]
public float leapPeakHeight = 3.5f;
[Tooltip("落地吸附距离")]
public float landOffsetDistance = 0.8f;
[Tooltip("空中飞跃时长 (第1帧起跳到第30帧落地,精确为 0.95 秒)")]
public float leapDuration = 0.95f;
[Header("特效资源")]
public GameObject swordWavePrefab; // 落地白剑浪特效 (SwordWaveWhite)
public GameObject groundImpactPrefab; // 落地冲击特效 (ShockwaveRing 或 TargetHitExplosion)
private bool isSkillPending = false;
private GameObject leapTarget;
private Coroutine leapCoroutine;
private Coroutine consecutiveCoroutine;
private int consecutiveKillCount = 0; // 10 级连斩计数 (最多 3 次)
private bool prevRootMotionState = true;
private void EnsureUnit()
{
if (unit == null)
{
unit = GetComponent();
}
}
///
/// 当能量蓄满时触发:锁定敌方后排,启动飞天刺杀!
///
public override void ReleaseSkill()
{
EnsureUnit();
if (unit == null) return;
WorldHealthBar healthBar = unit.GetComponent();
if (healthBar == null || healthBar.IsDead) return;
consecutiveKillCount = 0;
ExecuteLeapAttack();
}
///
/// 执行一次飞天斩(第1帧起跳到第30帧落地)
///
private void ExecuteLeapAttack()
{
EnsureUnit();
if (unit == null) return;
// 刺客核心:优先锁定敌方后排最深处的活体敌人
leapTarget = FindBacklineTarget(unit.Target);
if (leapTarget == null)
{
RestoreAgentAndState();
return;
}
Vector3 toTarget = leapTarget.transform.position - unit.transform.position;
toTarget.y = 0f;
if (toTarget.sqrMagnitude > 0.01f)
{
unit.transform.rotation = Quaternion.LookRotation(toTarget.normalized, Vector3.up);
}
isSkillPending = true;
// 1. 关闭 NavMeshAgent 与 Root Motion,位移完全由抛物线代码接管,杜绝任何位移打架漂移
NavMeshAgent agent = unit.GetComponent();
if (agent != null && agent.enabled)
{
agent.enabled = false;
}
Animator anim = GetComponent();
if (anim != null)
{
prevRootMotionState = anim.applyRootMotion;
anim.applyRootMotion = false; // 飞天位移期间禁用根运动,防止动画位移叠加漂移
anim.Play("skill", 0, 0f); // 强制从第 0 帧(第一帧立刻起跳)播放
}
unit.PlaySkillAnimation(OnSkillAnimationFinished, 2.067f);
if (leapCoroutine != null) StopCoroutine(leapCoroutine);
leapCoroutine = StartCoroutine(LeapTrajectoryRoutine(leapTarget));
Debug.Log($"【刺客·精锐士兵】第 {consecutiveKillCount + 1} 斩发动! 第一帧腾空起跳,直扑后排: {leapTarget.name}");
}
///
/// 飞天抛物线协程:第 0 秒立刻起跳,0.95 秒(第30帧)精准落地
///
private IEnumerator LeapTrajectoryRoutine(GameObject target)
{
Vector3 startPos = unit.transform.position;
startPos.y = 0.16f; // 保证起跳起点严格贴地
float elapsed = 0f;
while (elapsed < leapDuration)
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / leapDuration);
// 获取后排目标当前坐标(支持目标位移时动态吸附)
Vector3 targetPos = (target != null && target.activeInHierarchy)
? target.transform.position
: startPos + unit.transform.forward * 4f;
Vector3 toTargetVec = targetPos - startPos;
Vector3 landTargetPos;
// 保持在目标身前适量距离落位,避免模型穿插
if (toTargetVec.sqrMagnitude > landOffsetDistance * landOffsetDistance)
{
landTargetPos = targetPos - toTargetVec.normalized * landOffsetDistance;
}
else
{
landTargetPos = targetPos;
}
landTargetPos.y = 0.16f;
// 水平位置插值:使用匀速/平滑过渡
Vector3 curPos = Vector3.Lerp(startPos, landTargetPos, t);
// 垂直抛物线:4 * H * t * (1 - t),在 t=0.5 (约第15帧/0.48s) 达到最高点 3.5 米
curPos.y += 4f * leapPeakHeight * t * (1f - t);
unit.transform.position = curPos;
// 飞行中面朝目标
Vector3 lookDir = landTargetPos - curPos;
lookDir.y = 0f;
if (lookDir.sqrMagnitude > 0.01f)
{
unit.transform.rotation = Quaternion.LookRotation(lookDir.normalized, Vector3.up);
}
yield return null;
}
// 第 0.95 秒(第30帧)精准落地
Vector3 finalLandPos = unit.transform.position;
finalLandPos.y = 0.16f;
if (NavMesh.SamplePosition(finalLandPos, out NavMeshHit hit, 2.0f, NavMesh.AllAreas))
{
unit.transform.position = hit.position;
}
else
{
unit.transform.position = finalLandPos;
}
}
///
/// 动画命中帧方法:大剑落地砸击目标头顶 (约第 28~30 帧 / 0.904s 处)
///
public void OnSkillHit1()
{
if (!isSkillPending) return;
isSkillPending = false;
EnsureUnit();
if (unit == null) return;
GameObject opponent = (leapTarget != null && leapTarget.activeInHierarchy) ? leapTarget : unit.Target;
if (opponent == null) return;
int level = unit.level;
// 1. 播放破空剑浪与地面冲击特效
PlayImpactVfx(opponent.transform.position);
// 2. 计算刺客伤害 (1级 200%, 3级+ 250%)
float damageMultiplier = level >= 3 ? 2.50f : 2.00f;
// 3级解锁:暴击率额外 +25%
float originalCrit = unit.critRate;
if (level >= 3)
{
unit.critRate += 0.25f;
}
UnitBase targetUnit = opponent.GetComponentInParent();
WorldHealthBar targetBar = opponent.GetComponentInParent();
if (targetBar == null && targetUnit != null)
{
targetBar = targetUnit.GetComponent();
}
// 施加技能重劈伤害
float damage = unit.attackPower * damageMultiplier;
if (targetUnit != null)
{
targetUnit.ReceiveDamage(damage, unit.gameObject);
}
else if (targetBar != null)
{
targetBar.TakeDamage(damage, unit.gameObject);
}
// 恢复暴击率
if (level >= 3)
{
unit.critRate = originalCrit;
// 3级解锁:落地后 3 秒移速 +35%
StartCoroutine(TemporarySpeedBoostRoutine(3.0f, 1.35f));
}
// 3. 6级解锁【影袭破防】:目标陷入 1.2 秒硬眩晕
if (level >= 6 && targetUnit != null && targetUnit.IsAlive)
{
targetUnit.ApplyStun(1.2f);
Debug.Log($"【影袭破防】命中! 目标 {targetUnit.gameObject.name} 被震晕 1.2 秒!");
}
Debug.Log($"【裂空突袭】大剑劈中后排! 造成伤害倍率: {damageMultiplier * 100:F0}% (等级: {level})");
// 4. 10级解锁【死斗连环】:若斩杀目标,短暂停顿 0.25 秒后立即无缝起跳下一个后排!
bool isTargetKilled = (targetBar != null && targetBar.IsDead) || (targetUnit != null && targetUnit.IsDead) || (targetBar != null && targetBar.currentHealth <= 0f);
if (level >= 10 && isTargetKilled)
{
consecutiveKillCount++;
if (consecutiveKillCount < 3)
{
Debug.Log($"【死斗连环】斩杀触发! 精锐士兵斩杀后排目标,准备连斩下一个后排!(连击: {consecutiveKillCount})");
if (consecutiveCoroutine != null) StopCoroutine(consecutiveCoroutine);
consecutiveCoroutine = StartCoroutine(TriggerNextConsecutiveLeapDelayed(0.25f));
}
else
{
consecutiveKillCount = 0;
}
}
else
{
consecutiveKillCount = 0;
}
}
///
/// 连斩平滑衔接:后摇停顿 0.25 秒(让玩家看清落地砍杀),随后直接从当前落地位置再次腾空!
///
private IEnumerator TriggerNextConsecutiveLeapDelayed(float delay)
{
yield return new WaitForSeconds(delay);
if (unit != null && unit.IsAlive)
{
ExecuteLeapAttack();
}
}
private IEnumerator TemporarySpeedBoostRoutine(float duration, float mult)
{
if (unit == null) yield break;
float originalSpeed = unit.speed;
unit.speed = originalSpeed * mult;
yield return new WaitForSeconds(duration);
if (unit != null)
{
unit.speed = originalSpeed;
}
}
private void PlayImpactVfx(Vector3 landPos)
{
// 1. 播放 SwordWaveWhite 白剑浪 (贴地平铺)
GameObject wavePrefab = swordWavePrefab;
#if UNITY_EDITOR
if (wavePrefab == null)
{
wavePrefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/TJGeneratorLibEffects/Prefabs/Combat/Sword/Wave/SwordWaveWhite.prefab");
}
#endif
if (wavePrefab != null && unit != null)
{
Vector3 vfxPos = landPos + Vector3.up * 0.2f;
Quaternion rot = Quaternion.Euler(0f, unit.transform.eulerAngles.y, 0f);
var vfx = Instantiate(wavePrefab, vfxPos, rot);
vfx.transform.rotation = rot;
vfx.transform.localScale = Vector3.one * 1.5f;
Destroy(vfx, 1.5f);
}
// 2. 播放地面震波光圈
GameObject impactPrefab = groundImpactPrefab;
#if UNITY_EDITOR
if (impactPrefab == null)
{
impactPrefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Prefabs/特效/扩散光圈/ShockwaveRing.prefab");
}
#endif
if (impactPrefab != null)
{
var ring = Instantiate(impactPrefab, new Vector3(landPos.x, 0.05f, landPos.z), impactPrefab.transform.rotation);
Destroy(ring, 1.5f);
}
}
///
/// 寻找敌方阵型最远端/最深处的后排存活敌人
///
private GameObject FindBacklineTarget(GameObject currentTarget)
{
if (unit == null) return currentTarget;
UnitTeam myTeam = unit.GetComponent();
var allTeams = Object.FindObjectsOfType();
GameObject furthestBacklineEnemy = null;
float maxDepth = -999f;
foreach (var t in allTeams)
{
if (t == null || !t.gameObject.activeInHierarchy) continue;
// 双重防呆判断:支持 UnitTeam 阵营比对与 Unity Tag 敌我比对
bool isEnemy = (myTeam != null && myTeam.IsEnemy(t.gameObject))
|| (unit.CompareTag("Friend") && (t.CompareTag("Enemy") || t.gameObject.name.Contains("小怪") || t.gameObject.name.Contains("敌方")));
if (!isEnemy) continue;
var targetUnit = t.GetComponentInParent();
if (targetUnit != null && targetUnit.IsDead) continue;
var bar = t.GetComponentInParent();
if (bar != null && bar.IsDead) continue;
GameObject enemyGo = targetUnit != null ? targetUnit.gameObject : t.gameObject;
// 依据战场纵深 (Z 坐标越大即越靠后排敌方阵地)
float depth = enemyGo.transform.position.z;
if (depth > maxDepth)
{
maxDepth = depth;
furthestBacklineEnemy = enemyGo;
}
}
return furthestBacklineEnemy != null ? furthestBacklineEnemy : currentTarget;
}
private void RestoreAgentAndState()
{
isSkillPending = false;
NavMeshAgent agent = unit != null ? unit.GetComponent() : null;
if (agent != null && !agent.enabled)
{
agent.enabled = true;
}
Animator anim = GetComponent();
if (anim != null)
{
anim.applyRootMotion = prevRootMotionState;
}
}
private void OnSkillAnimationFinished()
{
RestoreAgentAndState();
}
private void OnDestroy()
{
if (leapCoroutine != null) StopCoroutine(leapCoroutine);
if (consecutiveCoroutine != null) StopCoroutine(consecutiveCoroutine);
RestoreAgentAndState();
}
}