人类士兵技能
This commit is contained in:
1 parent
9572db06ad
commit
f6f6666244
39 files changed
+25070
-60
No files matched your search
@@ -1,47 +1,234 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 人类士兵技能:蓄力重斩体系(1/3/6/10 级完整阶梯)
|
||||
/// 1级【蓄力重斩】:双手持短剑横向重斩,造成 150% 物理伤害(播放 SwordSlashThickWhite 锋利白剑气)
|
||||
/// 3级【破阵蓄力】:重斩基础伤害提升至 190%,暴击率 +20%
|
||||
/// 6级【断岳重击】:重斩附带强力震慑,命中直接使目标【眩晕 1.2 秒】(挂 StunStars 眩晕星星,强力打断蓄力)
|
||||
/// 10级【不屈战魂】:生命值首次跌破 35% 时进入无畏状态(脚底光环 AuraSoftBlue),攻速 +60% 且普攻附带 30% 吸血,持续 6 秒绝地翻盘!
|
||||
/// </summary>
|
||||
public class HumanSoldierSkill : UnitSkill
|
||||
{
|
||||
[Min(0f)]
|
||||
public float bonusAttackMultiplier = 0.5f;
|
||||
[Header("重斩配置")]
|
||||
[Tooltip("重斩攻击范围倍率")]
|
||||
public float slashDistanceBuffer = 0.5f;
|
||||
|
||||
[Header("技能动画")]
|
||||
[Min(0f)]
|
||||
public float skillAnimationDuration = 0f;
|
||||
[Header("10级不屈战魂配置")]
|
||||
[Tooltip("战魂触发血量阈值")]
|
||||
public float undyingHealthThreshold = 0.35f;
|
||||
|
||||
private bool isSkillReady;
|
||||
[Tooltip("战魂持续时间(秒)")]
|
||||
public float undyingDuration = 6.0f;
|
||||
|
||||
[Tooltip("战魂攻速提升倍率")]
|
||||
public float undyingAttackSpeedMultiplier = 1.6f;
|
||||
|
||||
[Tooltip("战魂额外吸血比例")]
|
||||
public float undyingLifestealRatio = 0.30f;
|
||||
|
||||
[Header("特效资源")]
|
||||
public GameObject slashVfxPrefab; // 横向白剑气 (SwordSlashThickWhite)
|
||||
public GameObject undyingAuraPrefab; // 不屈战魂光环 (AuraSoftBlue)
|
||||
|
||||
private bool isSkillPending = false;
|
||||
private bool undyingTriggered = false;
|
||||
private GameObject activeUndyingAuraInstance;
|
||||
private Coroutine activeUndyingCoroutine;
|
||||
|
||||
private void EnsureUnit()
|
||||
{
|
||||
if (unit == null)
|
||||
{
|
||||
unit = GetComponent<UnitBase>();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EnsureUnit();
|
||||
if (unit != null)
|
||||
{
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar != null)
|
||||
{
|
||||
healthBar.OnHealthChanged += CheckUndyingTrigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当能量蓄满时触发:播放人类士兵技能动画(双手横向重斩蓄力)
|
||||
/// </summary>
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
isSkillReady = true;
|
||||
unit.PlaySkillAnimation(OnSkillFinished, skillAnimationDuration);
|
||||
EnsureUnit();
|
||||
if (unit == null) return;
|
||||
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar == null || healthBar.IsDead) return;
|
||||
|
||||
unit.FaceCurrentTarget(0f);
|
||||
isSkillPending = true;
|
||||
|
||||
// 播放人类士兵技能动画,由 OnSkillHit1 帧触发斩击命中
|
||||
unit.PlaySkillAnimation(OnSkillAnimationFinished, 1.5f);
|
||||
Debug.Log($"<color=cyan>人类士兵释放技能【蓄力重斩】</color>,等待 OnSkillHit1 命中帧!");
|
||||
}
|
||||
|
||||
// 添加到技能攻击动画的第一段命中帧。
|
||||
/// <summary>
|
||||
/// 动画命中帧方法:在横向重斩刀刃挥出的瞬间触发 (OnSkillHit1)
|
||||
/// </summary>
|
||||
public void OnSkillHit1()
|
||||
{
|
||||
if (!isSkillReady)
|
||||
if (!isSkillPending) return;
|
||||
isSkillPending = false;
|
||||
|
||||
EnsureUnit();
|
||||
if (unit == null || unit.Target == null) return;
|
||||
|
||||
GameObject opponent = unit.Target;
|
||||
int level = unit.level;
|
||||
|
||||
// 1. 播放横向锐利白剑气特效
|
||||
PlaySlashVfx(opponent);
|
||||
|
||||
// 2. 计算技能伤害 (1级 150%, 3级+ 190%)
|
||||
float baseMultiplier = level >= 3 ? 1.90f : 1.50f;
|
||||
float finalMultiplier = baseMultiplier;
|
||||
|
||||
// 3级解锁:暴击率额外 +20%
|
||||
float originalCritRate = unit.critRate;
|
||||
if (level >= 3)
|
||||
{
|
||||
return;
|
||||
unit.critRate += 0.20f;
|
||||
}
|
||||
|
||||
unit.ApplySkillHit(1f, true);
|
||||
}
|
||||
// 3. 施加技能伤害
|
||||
unit.ApplySkillHit(finalMultiplier, true);
|
||||
|
||||
// 添加到技能攻击动画的第二段命中帧。
|
||||
public void OnSkillHit2()
|
||||
{
|
||||
if (!isSkillReady)
|
||||
// 恢复原有暴击率
|
||||
if (level >= 3)
|
||||
{
|
||||
return;
|
||||
unit.critRate = originalCritRate;
|
||||
}
|
||||
|
||||
unit.ApplySkillHit(bonusAttackMultiplier, false);
|
||||
isSkillReady = false;
|
||||
// 4. 6级解锁【断岳重击】:重斩附带 1.2 秒硬性眩晕打断
|
||||
if (level >= 6)
|
||||
{
|
||||
UnitBase targetUnit = opponent.GetComponentInParent<UnitBase>();
|
||||
if (targetUnit != null && targetUnit.IsAlive)
|
||||
{
|
||||
targetUnit.ApplyStun(1.2f);
|
||||
Debug.Log($"<color=yellow>【断岳重击】命中!</color> 目标 {targetUnit.gameObject.name} 眩晕 1.2 秒!");
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"<color=cyan>【蓄力重斩】命中结算!</color> 伤害倍率: {finalMultiplier * 100:F0}% (等级: {level})");
|
||||
}
|
||||
|
||||
private void OnSkillFinished()
|
||||
/// <summary>
|
||||
/// 监测 10 级大招【不屈战魂】:血量首次跌破 35% 时进入无畏战神状态
|
||||
/// </summary>
|
||||
private void CheckUndyingTrigger(float currentHealth, float maxHealth)
|
||||
{
|
||||
isSkillReady = false;
|
||||
if (undyingTriggered || unit == null || maxHealth <= 0f) return;
|
||||
|
||||
int level = unit.level;
|
||||
if (level < 10) return;
|
||||
|
||||
float ratio = currentHealth / maxHealth;
|
||||
if (ratio <= undyingHealthThreshold && currentHealth > 0f)
|
||||
{
|
||||
undyingTriggered = true;
|
||||
if (activeUndyingCoroutine != null) StopCoroutine(activeUndyingCoroutine);
|
||||
activeUndyingCoroutine = StartCoroutine(UndyingSoulRoutine());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator UndyingSoulRoutine()
|
||||
{
|
||||
Debug.Log($"<color=red>【不屈战魂】爆发!</color> 人类士兵生命告急,开启狂暴反击(攻速+60%,吸血+30%)!");
|
||||
|
||||
// 1. 播放脚底战神光环特效 (AuraSoftBlue)
|
||||
PlayUndyingAuraVfx();
|
||||
|
||||
// 2. 施加攻速与吸血增益
|
||||
float prevLifesteal = unit.lifestealRate;
|
||||
unit.lifestealRate += undyingLifestealRatio;
|
||||
unit.MultiplyAttackSpeed(undyingAttackSpeedMultiplier, 3.5f);
|
||||
|
||||
yield return new WaitForSeconds(undyingDuration);
|
||||
|
||||
// 3. 恢复属性
|
||||
if (unit != null)
|
||||
{
|
||||
unit.lifestealRate = prevLifesteal;
|
||||
unit.MultiplyAttackSpeed(1f / undyingAttackSpeedMultiplier, 3.5f);
|
||||
}
|
||||
|
||||
if (activeUndyingAuraInstance != null)
|
||||
{
|
||||
Destroy(activeUndyingAuraInstance);
|
||||
activeUndyingAuraInstance = null;
|
||||
}
|
||||
|
||||
Debug.Log($"<color=gray>【不屈战魂】持续时间结束。</color>");
|
||||
}
|
||||
|
||||
private void PlaySlashVfx(GameObject opponent)
|
||||
{
|
||||
GameObject prefab = slashVfxPrefab;
|
||||
#if UNITY_EDITOR
|
||||
if (prefab == null)
|
||||
{
|
||||
prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/TJGeneratorLibEffects/Prefabs/Combat/Sword/Slash/SwordSlashThick/SwordSlashThickWhite.prefab");
|
||||
}
|
||||
#endif
|
||||
if (prefab != null && unit != null)
|
||||
{
|
||||
Vector3 spawnPos = unit.transform.position + Vector3.up * 0.9f + unit.transform.forward * 0.8f;
|
||||
// 剑气网格自身在 X 轴有 270° (-90°) 的固有旋转,直接叠 unit.transform.rotation 会导致斜立
|
||||
// 只保留角色在 Y 轴的水平朝向,消除 X/Z 轴倾斜,使其精准平行于地面平挥
|
||||
Quaternion rot = Quaternion.Euler(0f, unit.transform.eulerAngles.y, 0f);
|
||||
var vfx = Instantiate(prefab, spawnPos, rot);
|
||||
vfx.transform.rotation = rot;
|
||||
vfx.transform.localScale = Vector3.one * 1.3f;
|
||||
Destroy(vfx, 1.5f);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayUndyingAuraVfx()
|
||||
{
|
||||
GameObject prefab = undyingAuraPrefab;
|
||||
#if UNITY_EDITOR
|
||||
if (prefab == null)
|
||||
{
|
||||
prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/TJGeneratorLibEffects/Prefabs/Combat/Magic/Aura Soft/AuraSoftBlue.prefab");
|
||||
}
|
||||
#endif
|
||||
if (prefab != null && unit != null)
|
||||
{
|
||||
// AuraSoftBlue 采用 Mesh(Quad) 水平平铺地面,需继承其自身的 -90° (270°) X 轴旋转
|
||||
Quaternion rot = prefab.transform.rotation;
|
||||
activeUndyingAuraInstance = Instantiate(prefab, unit.transform.position + Vector3.up * 0.05f, rot);
|
||||
activeUndyingAuraInstance.transform.rotation = rot;
|
||||
activeUndyingAuraInstance.transform.SetParent(unit.transform, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSkillAnimationFinished()
|
||||
{
|
||||
isSkillPending = false;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (activeUndyingAuraInstance != null) Destroy(activeUndyingAuraInstance);
|
||||
if (unit != null)
|
||||
{
|
||||
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar != null) healthBar.OnHealthChanged -= CheckUndyingTrigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user