Files
daluandou/Assets/Scripts/技能脚本/WerewolfSkill.cs
T
huadexuan 714cb7d825 ```
feat(gameplay): 更新狼人技能机制并优化战斗体验

- 重命名【嗜血狂暴】为【利爪撕裂】,调整技能描述和效果说明
- 新增技能动作加速配置,将2.4秒动画压缩至1.0秒提升出招速度
- 10级【不灭狼王】新增巨狼化体型放大1.25倍效果
- 统一技能伤害模式,移除6级扇形AOE改为纯粹单体撕裂
- 添加狼王爆发红光特效和体型缩放平滑过渡动画
- 荆野猎手攻击时长从0调整为1.2秒以改善战斗节奏
```
2026-10-14 22:42:47 +08:00

429 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 狂暴狼人技能:嗜血狂暴体系(吸血战坦 · 1/3/6/10 级完整阶梯)
/// 1级【利爪撕裂】:原地撕咬重创造成 150% 物理伤害(立即回复该次伤害 50% 的生命);并激活持续 5 秒的【嗜血状态】,普攻吸血 +30% 且攻速 +25%
/// 3级【血脉沸腾】:嗜血状态延长至 6.5 秒;期间普攻吸血提升至 45%,攻速提升至 35%,撕裂伤害提升至 190%!且单体撕裂附带流血撕口!
/// 6级【背水一战】:保持纯粹单体撕裂;处于嗜血状态时触发【背水一战】:自身血量每降低 10%,受击伤害减免 +3%,普攻吸血额外 +5%(血越残越硬越能吸,真正的打不死战坦)!
/// 10级【不灭狼王】:释放技能爆发狼王之怒,体型放大 1.25 倍(巨狼化)、临时提升 35% 最大生命值上限并获得等额生命回复!技能期间只要击杀敌人,立即瞬间回复 20% 最大生命值并刷新嗜血狂暴时间!
/// </summary>
public class WerewolfSkill : UnitSkill
{
[Header("动作加速配置")]
[Tooltip("技能动画目标时长(秒)。原动画长达 2.4s,压缩至 1.0s 实现出招速度翻倍以上")]
public float skillTargetDuration = 1.0f;
[Header("特效资源")]
[Tooltip("重抓抓痕特效 (SwordSlashMiniRed)")]
public GameObject clawSlashVfxPrefab;
[Tooltip("受击鲜血爆裂特效 (BloodExplosion)")]
public GameObject bloodHitVfxPrefab;
[Tooltip("10级狼王爆发红光特效 (EnergyExplosionRed)")]
public GameObject wolfKingRageVfxPrefab;
private bool isSkillPending = false;
private bool isBloodthirstActive = false;
private float bloodthirstTimer = 0f;
private float bloodthirstMaxDuration = 5f;
// 属性加成追踪与还原
private float baseBonusLifesteal = 0f;
private float dynamicLossLifesteal = 0f;
private float dynamicLossDamageReduction = 0f;
private float appliedAttackSpeedMultiplier = 1f;
private float temporaryBonusMaxHealth = 0f;
// 10 级体型放大记录与协程
private Vector3 originalModelScale = Vector3.one;
private bool isScaleBoosted = false;
private Coroutine scaleCoroutine;
private void EnsureUnit()
{
if (unit == null)
{
unit = GetComponent<UnitBase>();
}
}
protected override void Awake()
{
base.Awake();
EnsureUnit();
if (unit != null)
{
originalModelScale = unit.transform.localScale;
}
}
private void Start()
{
EnsureUnit();
WorldHealthBar.OnUnitKilled -= OnGlobalUnitKilled;
WorldHealthBar.OnUnitKilled += OnGlobalUnitKilled;
}
/// <summary>
/// 当能量蓄满时触发:播放大招攻击动画
/// </summary>
public override void ReleaseSkill()
{
EnsureUnit();
if (unit == null) return;
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
if (healthBar == null || healthBar.IsDead) return;
if (unit.Target == null) return;
unit.FaceCurrentTarget(0f);
isSkillPending = true;
// 10级大招:临时提升 35% 最大生命上限并回血 + 体型巨狼化放大 1.25 倍
if (unit.level >= 10)
{
TriggerWolfKingAscension(healthBar);
}
// 技能动作速度翻倍:将 2.4 秒的动画压缩到 1.0 秒播放,撕咬出招迅猛凌厉!
unit.PlaySkillAnimation(OnSkillAnimationFinished, skillTargetDuration);
Debug.Log($"<color=red>【狂暴狼人】释放大招【利爪撕裂】</color>,动作速度加速 1 倍(时长: {skillTargetDuration:F1}s)!");
}
/// <summary>
/// 10 级【不灭狼王】爆发:生命上限提升 35% 并回血,模型体型等比放大 1.25 倍
/// </summary>
private void TriggerWolfKingAscension(WorldHealthBar healthBar)
{
// 每次释放大招,如果尚未获得 35% 加成,则增加 35% 基础生命上限;若已有加成,则直接满额治疗回血!
if (temporaryBonusMaxHealth <= 0f)
{
float bonus = healthBar.maxHealth * 0.35f;
temporaryBonusMaxHealth = bonus;
healthBar.maxHealth += bonus;
healthBar.Heal(bonus);
Debug.Log($"<color=red>【不灭狼王】狼王真身觉醒!</color> 最大生命上限 +{bonus:F0},当前上限变为: {healthBar.maxHealth:F0}!");
}
else
{
// 已在狼王状态下再次开大:直接享受 35% 巨额生命恢复
healthBar.Heal(temporaryBonusMaxHealth);
Debug.Log($"<color=red>【不灭狼王】续战愈合!</color> 回复 +{temporaryBonusMaxHealth:F0} 生命值!");
}
// 播放红光爆裂特效
PlayWolfKingVfx();
// 巨狼化体型放大 1.25 倍平滑过渡
if (scaleCoroutine != null) StopCoroutine(scaleCoroutine);
scaleCoroutine = StartCoroutine(SmoothScaleModel(originalModelScale * 1.25f, 0.25f));
isScaleBoosted = true;
}
/// <summary>
/// 动画帧命中回调(兼容 OnAttackEffect 和 OnSkillHit1)
/// </summary>
public void OnSkillHit1()
{
ExecuteBiteStrike();
}
public void OnAttackEffect()
{
if (isSkillPending)
{
ExecuteBiteStrike();
}
}
/// <summary>
/// 实际结算大招单体撕裂重创伤害与启动嗜血狂暴
/// </summary>
private void ExecuteBiteStrike()
{
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级 150%,3级+ 190% (始终保持纯粹单体撕裂,不分散伤害)
float damageMultiplier = level >= 3 ? 1.90f : 1.50f;
float damage = unit.attackPower * damageMultiplier;
ExecuteSingleBite(damage);
// 激活【嗜血状态】
ActivateBloodthirst(level);
}
private void ExecuteSingleBite(float damage)
{
if (unit.Target == null) return;
GameObject target = unit.Target;
UnitBase targetUnit = target.GetComponentInParent<UnitBase>();
WorldHealthBar targetBar = target.GetComponentInParent<WorldHealthBar>();
PlayClawAndBloodVfx(target.transform.position + Vector3.up * 0.8f);
float dealtDamage = 0f;
if (targetUnit != null)
{
targetUnit.ReceiveDamage(damage, unit.gameObject);
dealtDamage = damage;
}
else if (targetBar != null)
{
targetBar.TakeDamage(damage, unit.gameObject);
dealtDamage = damage;
}
// 立即回复该次伤害 50% 的生命
WorldHealthBar myBar = unit.GetComponent<WorldHealthBar>();
if (myBar != null && dealtDamage > 0f)
{
float healAmount = dealtDamage * 0.5f;
myBar.Heal(healAmount);
Debug.Log($"<color=green>【利爪撕裂】重创!</color> 造成 {dealtDamage:F1} 伤害,吸血回复 +{healAmount:F1} HP!");
}
}
/// <summary>
/// 激活/刷新嗜血状态
/// </summary>
private void ActivateBloodthirst(int level)
{
float duration = level >= 3 ? 6.5f : 5.0f;
float bonusLifesteal = level >= 3 ? 0.45f : 0.30f;
float bonusAttackSpeed = level >= 3 ? 1.35f : 1.25f;
bloodthirstMaxDuration = duration;
bloodthirstTimer = duration;
if (!isBloodthirstActive)
{
isBloodthirstActive = true;
baseBonusLifesteal = bonusLifesteal;
unit.lifestealRate += baseBonusLifesteal;
appliedAttackSpeedMultiplier = bonusAttackSpeed;
unit.MultiplyAttackSpeed(appliedAttackSpeedMultiplier, 3.5f);
}
else
{
// 已在嗜血中时重置持续时间
bloodthirstTimer = duration;
}
Debug.Log($"<color=red>【嗜血状态激活】</color> 持续 {duration:F1} 秒:吸血 +{bonusLifesteal * 100:F0}%,攻速 +{(bonusAttackSpeed - 1f) * 100:F0}%!");
}
private void Update()
{
if (!isBloodthirstActive || unit == null) return;
bloodthirstTimer -= Time.deltaTime;
// 6级【背水一战】:嗜血期间自身血量越残,额外获得越高额的减伤与吸血
if (unit.level >= 6)
{
UpdateDesperationBuff();
}
if (bloodthirstTimer <= 0f)
{
EndBloodthirst();
}
}
/// <summary>
/// 6级【背水一战】:自身血量每降低 10%,减伤 +3%,吸血 +5%
/// </summary>
private void UpdateDesperationBuff()
{
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
if (healthBar == null || healthBar.maxHealth <= 0f) return;
float lostHealthRatio = Mathf.Clamp01(1f - (healthBar.currentHealth / healthBar.maxHealth));
int lostTens = Mathf.FloorToInt(lostHealthRatio * 10f); // 每 10%
float targetReduction = lostTens * 0.03f; // 每 10% 减伤 +3% (最高 27%)
float targetExtraLifesteal = lostTens * 0.05f; // 每 10% 吸血 +5% (最高 45%)
// 差量动态更新,避免死循环累加
float deltaReduction = targetReduction - dynamicLossDamageReduction;
unit.damageReductionRate += deltaReduction;
dynamicLossDamageReduction = targetReduction;
float deltaLifesteal = targetExtraLifesteal - dynamicLossLifesteal;
unit.lifestealRate += deltaLifesteal;
dynamicLossLifesteal = targetExtraLifesteal;
}
private void EndBloodthirst()
{
if (!isBloodthirstActive) return;
isBloodthirstActive = false;
bloodthirstTimer = 0f;
// 还原属性
if (unit != null)
{
unit.lifestealRate = Mathf.Max(0f, unit.lifestealRate - baseBonusLifesteal - dynamicLossLifesteal);
unit.damageReductionRate = Mathf.Max(0f, unit.damageReductionRate - dynamicLossDamageReduction);
if (appliedAttackSpeedMultiplier > 1f)
{
unit.MultiplyAttackSpeed(1f / appliedAttackSpeedMultiplier, 3.5f);
}
// 10级大招临时提升的生命上限还原
if (temporaryBonusMaxHealth > 0f)
{
WorldHealthBar bar = unit.GetComponent<WorldHealthBar>();
if (bar != null)
{
bar.maxHealth = Mathf.Max(1f, bar.maxHealth - temporaryBonusMaxHealth);
bar.currentHealth = Mathf.Min(bar.currentHealth, bar.maxHealth);
}
temporaryBonusMaxHealth = 0f;
}
// 还原体型大小
if (isScaleBoosted)
{
if (scaleCoroutine != null) StopCoroutine(scaleCoroutine);
scaleCoroutine = StartCoroutine(SmoothScaleModel(originalModelScale, 0.3f));
isScaleBoosted = false;
}
}
baseBonusLifesteal = 0f;
dynamicLossLifesteal = 0f;
dynamicLossDamageReduction = 0f;
appliedAttackSpeedMultiplier = 1f;
Debug.Log($"<color=gray>【嗜血状态结束】属性与体型恢复正常。</color>");
}
/// <summary>
/// 10级【不灭狼王】:技能期间击杀敌人,立即回复 20% 最大生命值并刷新嗜血时间!
/// </summary>
private void OnGlobalUnitKilled(GameObject victim, GameObject killer)
{
if (!isBloodthirstActive || unit == null || killer == null) return;
if (unit.level < 10) return;
// 判断击杀者是否是自己
if (killer == unit.gameObject || killer.transform.IsChildOf(unit.transform))
{
WorldHealthBar myBar = unit.GetComponent<WorldHealthBar>();
if (myBar != null && !myBar.IsDead)
{
float heal = myBar.maxHealth * 0.20f;
myBar.Heal(heal);
// 重置/刷新嗜血持续时间
bloodthirstTimer = bloodthirstMaxDuration;
Debug.Log($"<color=red>【不灭狼王·猎杀连环】!</color> 击杀 {victim.name},立即回复 20% 生命 (+{heal:F0}) 并刷新狂暴状态!");
}
}
}
private IEnumerator SmoothScaleModel(Vector3 targetScale, float duration)
{
if (unit == null) yield break;
Vector3 from = unit.transform.localScale;
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / duration);
if (unit != null)
{
unit.transform.localScale = Vector3.Lerp(from, targetScale, Mathf.SmoothStep(0f, 1f, t));
}
yield return null;
}
if (unit != null) unit.transform.localScale = targetScale;
}
private void PlayClawAndBloodVfx(Vector3 position)
{
// 1. 鲜血飞溅
GameObject bloodPrefab = bloodHitVfxPrefab;
#if UNITY_EDITOR
if (bloodPrefab == null)
{
bloodPrefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/TJGeneratorLibEffects/Prefabs/Combat/Blood/Red/BloodExplosion.prefab");
}
#endif
if (bloodPrefab != null)
{
var vfx = Instantiate(bloodPrefab, position, Quaternion.identity);
vfx.transform.localScale = Vector3.one * 1.5f;
Destroy(vfx, 1.5f);
}
// 2. 红色抓痕
GameObject slashPrefab = clawSlashVfxPrefab;
#if UNITY_EDITOR
if (slashPrefab == null)
{
slashPrefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/TJGeneratorLibEffects/Prefabs/Combat/Sword/Slash/SwordSlashMini/SwordSlashMiniRed.prefab");
}
#endif
if (slashPrefab != null && unit != null)
{
Quaternion rot = Quaternion.Euler(-90f, 0f, -unit.transform.eulerAngles.y);
var vfx = Instantiate(slashPrefab, position, rot);
vfx.transform.localScale = Vector3.one * 1.4f;
Destroy(vfx, 1.0f);
}
}
private void PlayWolfKingVfx()
{
GameObject vfxPrefab = wolfKingRageVfxPrefab;
#if UNITY_EDITOR
if (vfxPrefab == null)
{
vfxPrefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/TJGeneratorLibEffects/Prefabs/Combat/Explosions/EnergyExplosion/EnergyExplosionRed.prefab");
}
#endif
if (vfxPrefab != null && unit != null)
{
Vector3 pos = unit.transform.position + Vector3.up * 0.8f;
var vfx = Instantiate(vfxPrefab, pos, Quaternion.identity);
vfx.transform.localScale = Vector3.one * 1.5f;
Destroy(vfx, 2.0f);
}
}
private void OnSkillAnimationFinished()
{
if (isSkillPending)
{
ExecuteBiteStrike(); // 容错兜底:若动画结束仍未收到 Event,强制结算撕咬
}
}
private void OnDestroy()
{
WorldHealthBar.OnUnitKilled -= OnGlobalUnitKilled;
EndBloodthirst();
}
}