完善盾卫技能
This commit is contained in:
1 parent
195a459c76
commit
9572db06ad
41 files changed
+25241
-351
No files matched your search
@@ -2,21 +2,38 @@ using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 盾卫技能:坚固壁垒
|
||||
/// 1级:生成相当于自身 25% 最大生命值的护盾(持续 5 秒),播放 MagicShield 护盾特效
|
||||
/// 3级:护盾值提升至 35% 最大生命值,护盾期间减伤 +15%
|
||||
/// 盾卫技能:圣盾壁垒体系(1/3/6/10 级完整阶梯)
|
||||
/// 1级【圣盾壁垒】:举盾生成 35% 最大生命值的护盾(持续 5s),挂 MagicShieldBlue 特效
|
||||
/// 3级【坚不可摧】:护盾厚度提升至 50% 最大生命值,持续时间延长至 6s
|
||||
/// 6级【战吼嘲讽】:技能拍地 OnSkillHit1 瞬间爆发 NovaBlue 蓝色声波冲击环,强制周围 4 米所有敌人攻击自己 3s!
|
||||
/// 10级【圣盾清算】:护盾期间霸体免眩晕;当护盾被打破或超时结束时爆发神圣冲击波,将吸收伤害的 50% 转化为真实伤害反弹全场!
|
||||
/// </summary>
|
||||
public class ShieldGuardSkill : UnitSkill
|
||||
{
|
||||
[Header("护盾配置")]
|
||||
[Tooltip("护盾持续时间(秒)")]
|
||||
public float shieldDuration = 5.0f;
|
||||
[Tooltip("基础护盾持续时间(秒)")]
|
||||
public float baseShieldDuration = 5.0f;
|
||||
|
||||
[Tooltip("护盾特效预制体")]
|
||||
public GameObject shieldVfxPrefab;
|
||||
[Tooltip("3级以上护盾持续时间(秒)")]
|
||||
public float upgradedShieldDuration = 6.0f;
|
||||
|
||||
private GameObject activeVfxInstance;
|
||||
[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()
|
||||
{
|
||||
@@ -26,6 +43,9 @@ public class ShieldGuardSkill : UnitSkill
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当能量蓄满时触发:播放盾卫专属技能动画(举盾蓄力后砸地)
|
||||
/// </summary>
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
EnsureUnit();
|
||||
@@ -34,72 +54,109 @@ public class ShieldGuardSkill : UnitSkill
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar == null || healthBar.IsDead) return;
|
||||
|
||||
int level = unit.level; // 从 UnitBase 字段读取 level
|
||||
// 1级:25% maxHealth,3级+:35% maxHealth
|
||||
float ratio = level >= 3 ? 0.35f : 0.25f;
|
||||
float shieldAmount = healthBar.maxHealth * ratio;
|
||||
unit.FaceCurrentTarget(0f);
|
||||
isSkillPending = true;
|
||||
|
||||
// 1. 添加护盾值
|
||||
// 播放盾卫技能动画,并在 1.09s 的 OnSkillHit1 帧触发核心效果
|
||||
unit.PlaySkillAnimation(OnSkillAnimationFinished, 1.87f);
|
||||
Debug.Log($"<color=cyan>盾卫开始吟唱技能【圣盾壁垒】</color>,等待 OnSkillHit1 拍地!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动画事件帧方法:在双手持盾猛烈砸地的瞬间触发 (1.095 秒处)
|
||||
/// </summary>
|
||||
public void OnSkillHit1()
|
||||
{
|
||||
if (!isSkillPending) return;
|
||||
isSkillPending = false;
|
||||
|
||||
EnsureUnit();
|
||||
if (unit == null) return;
|
||||
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
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);
|
||||
|
||||
// 2. 播放 MagicShield 护盾特效
|
||||
// 3. 挂载护盾环绕特效 (MagicShieldBlue)
|
||||
PlayShieldVfx();
|
||||
|
||||
// 3. 开启超时自动清盾协程
|
||||
// 4. 10 级解锁:霸体免疫眩晕
|
||||
StatusEffectController statusCtrl = unit.GetComponent<StatusEffectController>();
|
||||
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(ShieldTimeoutRoutine(shieldDuration, shieldAmount));
|
||||
activeShieldCoroutine = StartCoroutine(ShieldLifecycleRoutine(duration, shieldAmount));
|
||||
|
||||
Debug.Log($"<color=cyan>盾卫释放技能【坚固壁垒】</color> 获得 {shieldAmount:F1} 护盾(比例: {ratio * 100}%,等级: {level})");
|
||||
Debug.Log($"<color=cyan>【盾卫】拍地爆发!</color> 获得护盾 {shieldAmount:F1} (等级: {level})");
|
||||
}
|
||||
|
||||
public override float ModifyIncomingDamage(float damage, GameObject attacker)
|
||||
private void ExecuteTauntAndWave()
|
||||
{
|
||||
EnsureUnit();
|
||||
// 3级解锁:护盾激活期间享受额外 15% 减伤
|
||||
if (unit != null && unit.level >= 3)
|
||||
// 播放声波光环特效 (NovaBlue)
|
||||
PlayTauntWaveVfx();
|
||||
|
||||
// 范围嘲讽所有敌人
|
||||
UnitTeam myTeam = unit.GetComponent<UnitTeam>();
|
||||
UnitBase[] allUnits = FindObjectsOfType<UnitBase>();
|
||||
float radiusSq = tauntRadius * tauntRadius;
|
||||
int tauntedCount = 0;
|
||||
|
||||
foreach (var other in allUnits)
|
||||
{
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar != null && healthBar.currentShield > 0f)
|
||||
if (other == null || other == unit || !other.gameObject.activeInHierarchy || other.IsDead) continue;
|
||||
UnitTeam otherTeam = other.GetComponent<UnitTeam>();
|
||||
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)
|
||||
{
|
||||
return damage * (1f - 0.15f);
|
||||
other.ApplyTaunt(unit.gameObject, tauntDuration);
|
||||
tauntedCount++;
|
||||
}
|
||||
}
|
||||
return damage;
|
||||
|
||||
Debug.Log($"<color=yellow>【盾卫战吼嘲讽】激发!</color> 强制嘲讽周围 {tauntedCount} 个敌人持续 {tauntDuration:F1} 秒!");
|
||||
}
|
||||
|
||||
private void PlayShieldVfx()
|
||||
private void RecordAbsorbedDamage(float absorbed)
|
||||
{
|
||||
if (activeVfxInstance != null)
|
||||
{
|
||||
Destroy(activeVfxInstance);
|
||||
}
|
||||
|
||||
GameObject prefab = shieldVfxPrefab;
|
||||
if (prefab == null)
|
||||
{
|
||||
prefab = Resources.Load<GameObject>("Prefabs/Combat/Magic/Shield/MagicShieldBlue");
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
if (prefab == null)
|
||||
{
|
||||
prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/TJGeneratorLibEffects/Prefabs/Combat/Magic/Shield/MagicShieldBlue.prefab");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (prefab != null)
|
||||
{
|
||||
activeVfxInstance = Instantiate(prefab, unit.transform.position + Vector3.up * 1.0f, Quaternion.identity);
|
||||
activeVfxInstance.transform.SetParent(unit.transform, true);
|
||||
}
|
||||
totalAbsorbedDamage += absorbed;
|
||||
}
|
||||
|
||||
private IEnumerator ShieldTimeoutRoutine(float duration, float amount)
|
||||
private IEnumerator ShieldLifecycleRoutine(float duration, float initialShieldAmount)
|
||||
{
|
||||
float timer = duration;
|
||||
WorldHealthBar healthBar = unit != null ? unit.GetComponent<WorldHealthBar>() : null;
|
||||
StatusEffectController statusCtrl = unit != null ? unit.GetComponent<StatusEffectController>() : null;
|
||||
|
||||
while (timer > 0f)
|
||||
{
|
||||
@@ -111,24 +168,125 @@ public class ShieldGuardSkill : UnitSkill
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// 超时或护盾为 0 清理特效与护盾值
|
||||
if (activeVfxInstance != 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)
|
||||
{
|
||||
Destroy(activeVfxInstance);
|
||||
activeVfxInstance = null;
|
||||
TriggerShieldBurst(totalAbsorbedDamage * 0.50f);
|
||||
}
|
||||
|
||||
if (healthBar != null && healthBar.currentShield > 0f && timer <= 0f)
|
||||
// 清理状态与特效
|
||||
if (statusCtrl != null)
|
||||
{
|
||||
healthBar.RemoveShield(amount);
|
||||
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($"<color=cyan>【盾卫】护盾结算完毕</color> (是否被击破: {isShieldBroken}, 总共吸收伤害: {totalAbsorbedDamage:F1})");
|
||||
}
|
||||
|
||||
private void TriggerShieldBurst(float burstDamage)
|
||||
{
|
||||
Debug.Log($"<color=yellow>【圣盾清算】护盾爆发!</color> 造成 {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<GameObject>("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<GameObject>("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<GameObject>("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 (activeVfxInstance != null)
|
||||
if (activeShieldVfx != null) Destroy(activeShieldVfx);
|
||||
if (unit != null)
|
||||
{
|
||||
Destroy(activeVfxInstance);
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar != null) healthBar.OnShieldAbsorbedDamage -= RecordAbsorbedDamage;
|
||||
StatusEffectController statusCtrl = unit.GetComponent<StatusEffectController>();
|
||||
if (statusCtrl != null) statusCtrl.isStunImmune = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user