using System.Collections; using UnityEngine; /// /// 盾卫技能:圣盾壁垒体系(1/3/6/10 级完整阶梯) /// 1级【圣盾壁垒】:举盾生成 35% 最大生命值的护盾(持续 5s),挂 MagicShieldBlue 特效 /// 3级【坚不可摧】:护盾厚度提升至 50% 最大生命值,持续时间延长至 6s /// 6级【战吼嘲讽】:技能拍地 OnSkillHit1 瞬间爆发 NovaBlue 蓝色声波冲击环,强制周围 4 米所有敌人攻击自己 3s! /// 10级【圣盾清算】:护盾期间霸体免眩晕;当护盾被打破或超时结束时爆发神圣冲击波,将吸收伤害的 50% 转化为真实伤害反弹全场! /// public class ShieldGuardSkill : UnitSkill { [Header("护盾配置")] [Tooltip("基础护盾持续时间(秒)")] public float baseShieldDuration = 5.0f; [Tooltip("3级以上护盾持续时间(秒)")] public float upgradedShieldDuration = 6.0f; [Header("6级战吼嘲讽配置")] [Tooltip("嘲讽半径(米)")] public float tauntRadius = 4.0f; [Tooltip("嘲讽持续时间(秒)")] public float tauntDuration = 3.0f; [Header("特效资源")] public GameObject shieldVfxPrefab; // 护盾特效 (MagicShieldBlue) public GameObject tauntWaveVfxPrefab; // 拍地嘲讽声波环特效 (NovaBlue) public GameObject shieldBurstVfxPrefab; // 破盾清算冲击波特效 (NovaLightningBlue 或 TargetHitExplosion) private GameObject activeShieldVfx; private Coroutine activeShieldCoroutine; private float totalAbsorbedDamage = 0f; private bool isSkillPending = false; private float currentMaxShield = 0f; 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; unit.FaceCurrentTarget(0f); isSkillPending = true; // 播放盾卫技能动画,并在 1.09s 的 OnSkillHit1 帧触发核心效果 unit.PlaySkillAnimation(OnSkillAnimationFinished, 1.87f); Debug.Log($"盾卫开始吟唱技能【圣盾壁垒】,等待 OnSkillHit1 拍地!"); } /// /// 动画事件帧方法:在双手持盾猛烈砸地的瞬间触发 (1.095 秒处) /// public void OnSkillHit1() { if (!isSkillPending) return; isSkillPending = false; EnsureUnit(); if (unit == null) return; WorldHealthBar healthBar = unit.GetComponent(); if (healthBar == null || healthBar.IsDead) return; int level = unit.level; // 1. 计算护盾数值 (1级 35%, 3级+ 50%) float ratio = level >= 3 ? 0.50f : 0.35f; float shieldAmount = healthBar.maxHealth * ratio; currentMaxShield = shieldAmount; totalAbsorbedDamage = 0f; // 2. 赋予自身护盾 healthBar.AddShield(shieldAmount); // 3. 挂载护盾环绕特效 (MagicShieldBlue) PlayShieldVfx(); // 4. 10 级解锁:霸体免疫眩晕 StatusEffectController statusCtrl = unit.GetComponent(); if (level >= 10 && statusCtrl != null) { statusCtrl.isStunImmune = true; } // 5. 6 级解锁:拍地激发声波光环 + 强力嘲讽周围 4 米所有敌人 if (level >= 6) { ExecuteTauntAndWave(); } // 6. 监听护盾伤害吸收 (用于 10 级破盾清算) healthBar.OnShieldAbsorbedDamage -= RecordAbsorbedDamage; healthBar.OnShieldAbsorbedDamage += RecordAbsorbedDamage; // 7. 启动护盾生命周期协程 (监测破盾与超时结算) float duration = level >= 3 ? upgradedShieldDuration : baseShieldDuration; if (activeShieldCoroutine != null) { StopCoroutine(activeShieldCoroutine); } activeShieldCoroutine = StartCoroutine(ShieldLifecycleRoutine(duration, shieldAmount)); Debug.Log($"【盾卫】拍地爆发! 获得护盾 {shieldAmount:F1} (等级: {level})"); } private void ExecuteTauntAndWave() { // 播放声波光环特效 (NovaBlue) PlayTauntWaveVfx(); // 范围嘲讽所有敌人 UnitTeam myTeam = unit.GetComponent(); UnitBase[] allUnits = FindObjectsOfType(); float radiusSq = tauntRadius * tauntRadius; int tauntedCount = 0; foreach (var other in allUnits) { if (other == null || other == unit || !other.gameObject.activeInHierarchy || other.IsDead) continue; UnitTeam otherTeam = other.GetComponent(); if (myTeam != null && otherTeam != null && !myTeam.IsEnemy(otherTeam.gameObject)) continue; // 只嘲讽敌方 Vector3 diff = other.transform.position - unit.transform.position; diff.y = 0f; if (diff.sqrMagnitude <= radiusSq) { other.ApplyTaunt(unit.gameObject, tauntDuration); tauntedCount++; } } Debug.Log($"【盾卫战吼嘲讽】激发! 强制嘲讽周围 {tauntedCount} 个敌人持续 {tauntDuration:F1} 秒!"); } private void RecordAbsorbedDamage(float absorbed) { totalAbsorbedDamage += absorbed; } private IEnumerator ShieldLifecycleRoutine(float duration, float initialShieldAmount) { float timer = duration; WorldHealthBar healthBar = unit != null ? unit.GetComponent() : null; StatusEffectController statusCtrl = unit != null ? unit.GetComponent() : null; while (timer > 0f) { if (unit == null || healthBar == null || healthBar.IsDead || healthBar.currentShield <= 0f) { break; } timer -= Time.deltaTime; yield return null; } // 护盾解除/破盾清算 bool isShieldBroken = healthBar != null && healthBar.currentShield <= 0f && timer > 0f; int level = unit != null ? unit.level : 1; // 10 级解锁【圣盾清算】:将吸收的伤害按 50% 转化为真实伤害反弹全场周围 if (level >= 10 && totalAbsorbedDamage > 0f && unit != null) { TriggerShieldBurst(totalAbsorbedDamage * 0.50f); } // 清理状态与特效 if (statusCtrl != null) { statusCtrl.isStunImmune = false; } if (healthBar != null) { healthBar.OnShieldAbsorbedDamage -= RecordAbsorbedDamage; if (timer <= 0f && healthBar.currentShield > 0f) { healthBar.RemoveShield(initialShieldAmount); } } if (activeShieldVfx != null) { Destroy(activeShieldVfx); activeShieldVfx = null; } Debug.Log($"【盾卫】护盾结算完毕 (是否被击破: {isShieldBroken}, 总共吸收伤害: {totalAbsorbedDamage:F1})"); } private void TriggerShieldBurst(float burstDamage) { Debug.Log($"【圣盾清算】护盾爆发! 造成 {burstDamage:F1} 范围反击真实伤害!"); // 播放破盾爆发特效 PlayShieldBurstVfx(); // 对周围 4 米造成反弹伤害 if (unit != null) { unit.ApplyAreaSkillDamage(tauntRadius, burstDamage, false); } } private void PlayShieldVfx() { if (activeShieldVfx != null) Destroy(activeShieldVfx); GameObject prefab = shieldVfxPrefab; #if UNITY_EDITOR if (prefab == null) { prefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/TJGeneratorLibEffects/Prefabs/Combat/Magic/Shield/MagicShieldBlue.prefab"); } #endif if (prefab != null && unit != null) { activeShieldVfx = Instantiate(prefab, unit.transform.position + Vector3.up * 1.0f, Quaternion.identity); activeShieldVfx.transform.SetParent(unit.transform, true); } } private void PlayTauntWaveVfx() { GameObject prefab = tauntWaveVfxPrefab; #if UNITY_EDITOR if (prefab == null) { prefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/TJGeneratorLibEffects/Prefabs/Combat/Nova/Standard/NovaBlue.prefab"); } #endif if (prefab != null && unit != null) { Vector3 spawnPos = unit.transform.position; spawnPos.y = 0.05f; // 贴地 var vfx = Instantiate(prefab, spawnPos, prefab.transform.rotation); // 调整 scale 以匹配 4 米嘲讽范围 vfx.transform.localScale = new Vector3(1.6f, 1.6f, 1.6f); Destroy(vfx, 2.5f); } } private void PlayShieldBurstVfx() { GameObject prefab = shieldBurstVfxPrefab; #if UNITY_EDITOR if (prefab == null) { prefab = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/TJGeneratorLibEffects/Prefabs/Combat/Nova/Lightning/NovaLightningBlue.prefab"); } #endif if (prefab != null && unit != null) { Vector3 spawnPos = unit.transform.position; spawnPos.y = 0.05f; var vfx = Instantiate(prefab, spawnPos, prefab.transform.rotation); vfx.transform.localScale = new Vector3(1.5f, 1.5f, 1.5f); Destroy(vfx, 2.5f); } } private void OnSkillAnimationFinished() { isSkillPending = false; } private void OnDestroy() { if (activeShieldVfx != null) Destroy(activeShieldVfx); if (unit != null) { WorldHealthBar healthBar = unit.GetComponent(); if (healthBar != null) healthBar.OnShieldAbsorbedDamage -= RecordAbsorbedDamage; StatusEffectController statusCtrl = unit.GetComponent(); if (statusCtrl != null) statusCtrl.isStunImmune = false; } } }