feat(EliteSoldier): 精锐士兵重构为刺客定位技能体系

- 完全重写EliteSoldierSkill.cs,将职业定位从大剑狂战改为刺客
- 实现1级【裂空突袭】:飞天斩击敌方后排,造成200%物理暴击伤害
- 添加3级【弱点锁定】:伤害提升至250%,暴击率+25%,落地移速+35%
- 添加6级【影袭破防】:目标眩晕1.2秒且物理易伤35%
- 添加10级【死斗连环】:击杀后连斩最多3次,无缝腾空攻击下一个后排
- 优化动画系统:飞跃期间关闭root motion和nav mesh agent避免位移冲突
- 更新动画控制器override controller的clip引用
- 在预制体中添加isStunImmune字段用于10级霸体效果
- 更新游戏说明文档中的技能描述和开发日志
```
This commit is contained in:
huadexuan committed 2026-10-12 23:10:06 +08:00
1 parent ec35c6c154
commit a9869b7419
18 files changed
+25041 -51

No files matched your search

+70 -4
View File
@@ -83,16 +83,82 @@ public class CastleMageSkill : UnitSkill
Debug.Log($"<color=orange>【爆裂火球】发射!</color> 伤害倍率: {damageMultiplier * 100:F0}%, 范围: {radius:F1}m (等级: {level})");
}
private IEnumerator LaunchSecondFireballDelayed(GameObject target, float damageMultiplier, float radius, bool createBurnField)
private IEnumerator LaunchSecondFireballDelayed(GameObject primaryTarget, float damageMultiplier, float radius, bool createBurnField)
{
yield return new WaitForSeconds(0.25f);
if (target != null && target.activeInHierarchy && unit != null)
if (unit == null) yield break;
// 优先打目标后方的敌人;如果只有一个怪或没有更后方的人,直接打同一个目标,绝不打空
GameObject secondTarget = FindBacklineTarget(primaryTarget);
if (secondTarget != null && secondTarget.activeInHierarchy)
{
LaunchFireball(target, damageMultiplier, radius, createBurnField);
Debug.Log($"<color=red>【双发爆裂】追加第二发火球!</color> 伤害倍率: {damageMultiplier * 100:F0}%");
LaunchFireball(secondTarget, damageMultiplier, radius, createBurnField);
bool isSameTarget = secondTarget == primaryTarget;
Debug.Log($"<color=red>【双发爆裂】追加第二发火球!</color> 目标: {secondTarget.name} ({(isSameTarget ? "单目标连续轰炸" : "后排敌群轰炸")}),伤害倍率: {damageMultiplier * 100:F0}%");
}
}
/// <summary>
/// 寻找位于当前目标后方的敌人。若无后排敌人,回退返回当前目标。
/// </summary>
private GameObject FindBacklineTarget(GameObject currentTarget)
{
if (unit == null) return currentTarget;
UnitTeam myTeam = unit.GetComponent<UnitTeam>();
if (myTeam == null) return currentTarget;
// 如果原目标已失效/死亡,回退找任意当前有效目标
if (currentTarget == null || !currentTarget.activeInHierarchy)
{
return unit.FindNearestEnemyForSkill();
}
Vector3 magePos = unit.transform.position;
Vector3 targetPos = currentTarget.transform.position;
Vector3 forwardDir = (targetPos - magePos).normalized;
if (forwardDir.sqrMagnitude < 0.001f) forwardDir = unit.transform.forward;
var allTeams = Object.FindObjectsOfType<UnitTeam>();
GameObject bestBacklineTarget = null;
float bestDistance = float.MaxValue;
foreach (var t in allTeams)
{
if (t == null || !t.gameObject.activeInHierarchy) continue;
if (!myTeam.IsEnemy(t.gameObject)) continue;
if (t.gameObject == currentTarget || t.transform.root == currentTarget.transform.root) continue;
// 检查敌方单位是否存活
var targetUnit = t.GetComponentInParent<UnitBase>();
if (targetUnit != null && targetUnit.IsDead) continue;
var bar = t.GetComponentInParent<WorldHealthBar>();
if (bar != null && bar.IsDead) continue;
GameObject enemyGo = targetUnit != null ? targetUnit.gameObject : t.gameObject;
// 计算该敌人相对当前目标的深度 (沿法师射向的距离)
Vector3 offset = enemyGo.transform.position - targetPos;
float depth = Vector3.Dot(offset, forwardDir);
// 只要位于目标后方 (深度 > 0.8米)
if (depth > 0.8f)
{
// 优先选择距离当前目标最近的后排敌人(紧邻的后排敌群),形成层次分明的前后封锁
float dist = offset.magnitude;
if (dist < bestDistance)
{
bestDistance = dist;
bestBacklineTarget = enemyGo;
}
}
}
// 如果找到了后排敌人,打后排敌人;如果场上只有一个怪或无后排敌人,打同一个目标
return bestBacklineTarget != null ? bestBacklineTarget : currentTarget;
}
private void LaunchFireball(GameObject target, float damageMultiplier, float radius, bool createBurnField)
{
GameObject missilePrefab = fireballMissilePrefab;