feat(gameplay): 实现护盾系统和强化增益选择机制

- 新增护盾功能,包括护盾数值显示和护盾条UI
- 重构盾卫技能,实现坚固壁垒技能效果
- 添加暴击率、吸血率等战斗属性
- 优化增益选择界面,新增传奇品质和刷新机制
- 调整材质纹理和文字着色器效果
- 修复金币显示格式问题
```
This commit is contained in:
huadexuan committed 2026-10-09 18:13:18 +08:00
1 parent 336ec9980d
commit 48395ab414
27 files changed
+10343 -128

No files matched your search

+107 -35
View File
@@ -1,62 +1,134 @@
using System.Collections;
using UnityEngine;
/// <summary>
/// 盾卫技能:坚固壁垒
/// 1级:生成相当于自身 25% 最大生命值的护盾(持续 5 秒),播放 MagicShield 护盾特效
/// 3级:护盾值提升至 35% 最大生命值,护盾期间减伤 +15%
/// </summary>
public class ShieldGuardSkill : UnitSkill
{
[Header("盾牌参数")]
[Min(1f)]
public float shieldDurability = 220f;
[Header("护盾配置")]
[Tooltip("护盾持续时间(秒)")]
public float shieldDuration = 5.0f;
[Min(0.1f)]
public float shieldDuration = 4f;
[Tooltip("护盾特效预制体")]
public GameObject shieldVfxPrefab;
[Range(0f, 1f)]
public float damageReduction = 0.35f;
private GameObject activeVfxInstance;
private Coroutine activeShieldCoroutine;
public Vector3 shieldLocalPosition = new Vector3(0f, 1f, 0.7f);
public Vector3 shieldSize = new Vector3(1.5f, 1.8f, 0.12f);
private ShieldBarrier shield;
public ShieldBarrier ActiveShield => shield;
private void EnsureUnit()
{
if (unit == null)
{
unit = GetComponent<UnitBase>();
}
}
public override void ReleaseSkill()
{
EnsureShield();
shield.Refresh(shieldDurability, shieldDuration, shieldLocalPosition, shieldSize);
EnsureUnit();
if (unit == null) return;
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;
// 1. 添加护盾值
healthBar.AddShield(shieldAmount);
// 2. 播放 MagicShield 护盾特效
PlayShieldVfx();
// 3. 开启超时自动清盾协程
if (activeShieldCoroutine != null)
{
StopCoroutine(activeShieldCoroutine);
}
activeShieldCoroutine = StartCoroutine(ShieldTimeoutRoutine(shieldDuration, shieldAmount));
Debug.Log($"<color=cyan>盾卫释放技能【坚固壁垒】</color> 获得 {shieldAmount:F1} 护盾(比例: {ratio * 100}%,等级: {level})");
}
public override float ModifyIncomingDamage(float damage, GameObject attacker)
{
if (shield == null || !shield.IsActive)
EnsureUnit();
// 3级解锁:护盾激活期间享受额外 15% 减伤
if (unit != null && unit.level >= 3)
{
return damage;
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
if (healthBar != null && healthBar.currentShield > 0f)
{
return damage * (1f - 0.15f);
}
}
if (shield.TryBlock(attacker, damage))
{
return damage * (1f - damageReduction);
}
return damage;
}
private void EnsureShield()
private void PlayShieldVfx()
{
if (shield != null)
if (activeVfxInstance != null)
{
return;
Destroy(activeVfxInstance);
}
GameObject shieldObject = new GameObject("ShieldBarrier");
shieldObject.transform.SetParent(unit.transform, false);
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
BoxCollider boxCollider = shieldObject.AddComponent<BoxCollider>();
boxCollider.isTrigger = true;
boxCollider.size = shieldSize;
if (prefab != null)
{
activeVfxInstance = Instantiate(prefab, unit.transform.position + Vector3.up * 1.0f, Quaternion.identity);
activeVfxInstance.transform.SetParent(unit.transform, true);
}
}
shield = shieldObject.AddComponent<ShieldBarrier>();
shield.Configure(unit, boxCollider);
shieldObject.SetActive(false);
private IEnumerator ShieldTimeoutRoutine(float duration, float amount)
{
float timer = duration;
WorldHealthBar healthBar = unit != null ? unit.GetComponent<WorldHealthBar>() : null;
while (timer > 0f)
{
if (unit == null || healthBar == null || healthBar.IsDead || healthBar.currentShield <= 0f)
{
break;
}
timer -= Time.deltaTime;
yield return null;
}
// 超时或护盾为 0 清理特效与护盾值
if (activeVfxInstance != null)
{
Destroy(activeVfxInstance);
activeVfxInstance = null;
}
if (healthBar != null && healthBar.currentShield > 0f && timer <= 0f)
{
healthBar.RemoveShield(amount);
}
}
private void OnDestroy()
{
if (activeVfxInstance != null)
{
Destroy(activeVfxInstance);
}
}
}