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(); } }