26 KiB
54 · 霸体系统(Poise / Superarmor System)
命名空间
BaseGames.Combat
所属文档集 ← 返回索引 · 总览
依赖BaseGames.Combat(DamageInfo / HitBox / HurtBox)·BaseGames.Skills(FormSkillSO)·BaseGames.Enemies.Boss.Skills(BossSkillSO)
目录
- 系统总览
- 核心枚举定义
- 霸体窗口配置(PoiseWindowConfig)
- IPoiseSource — 霸体来源接口
- HurtBox 打断判定流水线
- DamageInfo / DamageSourceSO 扩展
- 玩家霸体配置
- 敌人 / Boss 霸体配置(BossSkillSO)
- 显式打断关系表(PoiseOverrideTableSO)
- 全动作霸体参考表
- 平衡设计准则
- 编辑器友好设计
1. 系统总览
霸体(Poise) 是动作游戏中"受击时不被打断"的能力。本系统将霸体和打断能力拆解为两个对立等级,并通过 SO 数据驱动实现对所有技能、攻击、能力的精细配置。
核心概念
| 概念 | 说明 |
|---|---|
| 霸体等级(PoiseLevel) | 当前动作抵抗被打断的强度。等级越高,越难被打断。 |
| 打断等级(BreakLevel) | 攻击/技能的打断能力。等级越高,能打断越强的霸体。 |
| 霸体窗口(Poise Window) | 某个动作在哪段时间内拥有霸体(可以是整个状态,也可以是特定动画帧区间)。 |
| 霸体 vs 无敌帧(IFrame) | 无敌帧 = 不受任何伤害;霸体 = 受伤但不被打断,两者独立,可同时生效。 |
打断判定规则
受击时:
1. 检查无敌帧(IFrame) → 若活跃,直接跳过所有伤害处理
2. 检查打断逻辑:
a. 查询 PoiseOverrideTable 是否有该攻击 vs 该状态的显式规则
→ 若有 AlwaysInterrupt: 强制打断(Unbreakable 除外)
→ 若有 NeverInterrupt: 绝不打断(保留伤害)
b. 默认规则:(int)incomingBreakLevel >= (int)currentPoiseLevel → 打断
3. 若打断:进入 HurtState / 施加击退 / 技能 / 动作被取消
若不打断:仅扣血 + 播放受击闪烁,不进入 HurtState
装备系统
职责图:
├─ PoiseLevel / BreakLevel → 两个对立枚举(等级比较核心)
├─ PoiseWindowConfig → 结构体(哪段时间有霸体,霸体等级)
├─ IPoiseSource → 接口(状态/技能/动作暴露当前霸体等级)
├─ DamageSourceSO → 增加 breakLevel 字段
├─ DamageInfo → 增加 BreakLevel 字段
├─ HurtBox → 打断判定逻辑
├─ FormSkillSO → 技能施放期间的霸体窗口
├─ BossSkillSO → Boss 技能执行期间的霸体配置
├─ PlayerStateBase → 玩家状态暴露 CurrentPoise
└─ PoiseOverrideTableSO → 显式打断关系配置(可选精细控制)
2. 核心枚举定义
namespace BaseGames.Combat
{
/// <summary>
/// 霸体等级:当前动作抵抗被打断的强度。
/// Unbreakable = 100,任何 BreakLevel 均无法打断(BOSS 阶段转换技、玩家特定能力专用)。
/// </summary>
public enum PoiseLevel
{
None = 0, // 无霸体:任何攻击均可打断(普通状态、普通敌人站立)
Light = 1, // 轻霸体:可被中级以上攻击打断(普通攻击第3段可打断)
Medium = 2, // 中霸体:只有重型攻击或技能可打断(精英怪冲刺、玩家技能施放)
Heavy = 3, // 重霸体:只有破甲攻击可打断(Boss 核心攻击前摇)
Unbreakable = 100, // 霸体:完全不可打断(Boss 阶段过渡、剧情硬直)
}
/// <summary>
/// 打断等级:攻击/技能打断对手霸体的能力。
/// 判定规则:(int)breakLevel >= (int)targetPoiseLevel 时发生打断(Unbreakable 例外)。
/// </summary>
public enum BreakLevel
{
None = 0, // 无打断力(弱攻击,只能打断 PoiseLevel.None)
Light = 1, // 轻打断(可打断 Light 及以下霸体)
Medium = 2, // 中打断(可打断 Medium 及以下霸体)
Heavy = 3, // 重打断(可打断 Heavy 及以下霸体)
Breaker = 4, // 破甲(可打断 Heavy 及以下,不能打断 Unbreakable)
}
}
打断关系速查矩阵
| BreakLevel → | None(0) | Light(1) | Medium(2) | Heavy(3) | Breaker(4) |
|---|---|---|---|---|---|
| PoiseLevel.None(0) | ✅打断 | ✅打断 | ✅打断 | ✅打断 | ✅打断 |
| PoiseLevel.Light(1) | ❌ | ✅打断 | ✅打断 | ✅打断 | ✅打断 |
| PoiseLevel.Medium(2) | ❌ | ❌ | ✅打断 | ✅打断 | ✅打断 |
| PoiseLevel.Heavy(3) | ❌ | ❌ | ❌ | ✅打断 | ✅打断 |
| PoiseLevel.Unbreakable | ❌ | ❌ | ❌ | ❌ | ❌ |
所有 ❌ 情况:仍扣血,但不进入 HurtState,不施加击退。
3. 霸体窗口配置(PoiseWindowConfig)
/// <summary>
/// 霸体窗口配置。定义某动作在哪段时间内(以动画时间轴为基准)拥有霸体。
/// - 若 windowStart = windowEnd = 0,则整个动作期间均拥有霸体。
/// - windowStart/End 使用归一化时间(0.0 = 动画起始,1.0 = 动画结束)。
/// </summary>
[Serializable]
public struct PoiseWindowConfig
{
[Tooltip("霸体等级(None = 无霸体,Unbreakable = 完全不可打断)")]
public PoiseLevel level;
[Tooltip("霸体生效起始时间(归一化,0 = 动画开始)。0+0 = 全程霸体。")]
[Range(0f, 1f)]
public float windowStart;
[Tooltip("霸体生效结束时间(归一化,0 = 动画结束 = 1.0 等价)。0+0 = 全程霸体。")]
[Range(0f, 1f)]
public float windowEnd;
/// <summary>是否在整个动作期间都有霸体(windowStart = windowEnd = 0 时视为全程)</summary>
public bool IsFullDuration => windowStart == 0f && windowEnd == 0f;
/// <summary>检查指定归一化时间是否在霸体窗口内</summary>
public bool IsActiveAt(float normalizedTime)
{
if (level == PoiseLevel.None) return false;
if (IsFullDuration) return true;
return normalizedTime >= windowStart && normalizedTime <= windowEnd;
}
/// <summary>预设:全程轻霸体</summary>
public static PoiseWindowConfig LightFull
=> new() { level = PoiseLevel.Light, windowStart = 0, windowEnd = 0 };
/// <summary>预设:全程中霸体</summary>
public static PoiseWindowConfig MediumFull
=> new() { level = PoiseLevel.Medium, windowStart = 0, windowEnd = 0 };
/// <summary>预设:全程重霸体</summary>
public static PoiseWindowConfig HeavyFull
=> new() { level = PoiseLevel.Heavy, windowStart = 0, windowEnd = 0 };
/// <summary>预设:无霸体</summary>
public static PoiseWindowConfig None
=> new() { level = PoiseLevel.None, windowStart = 0, windowEnd = 0 };
}
4. IPoiseSource — 霸体来源接口
所有可以提供霸体的对象(玩家状态、技能执行器、Boss 技能执行器)实现此接口:
/// <summary>
/// 霸体来源接口。HurtBox 在打断判定时调用此接口查询当前霸体等级。
/// </summary>
public interface IPoiseSource
{
/// <summary>当前霸体等级(实时,随动画帧变化)</summary>
PoiseLevel CurrentPoise { get; }
}
玩家端实现:PlayerController 汇总多个 IPoiseSource(当前状态 + 技能执行器)并对外暴露最高霸体等级:
public class PlayerController : MonoBehaviour, IPoiseSource
{
// 汇总当前所有霸体来源,取最高等级
public PoiseLevel CurrentPoise
{
get
{
PoiseLevel best = _currentState?.CurrentPoise ?? PoiseLevel.None;
PoiseLevel skill = _skillManager.CurrentPoise;
return (int)skill > (int)best ? skill : best;
}
}
}
5. HurtBox 打断判定流水线
HurtBox.ReceiveDamage(DamageInfo) 新增霸体检查步骤:
public void ReceiveDamage(DamageInfo info)
{
// ── Step 1: 无敌帧检查 ──────────────────────────────────────────────────
if (_owner is IInvincible inv && inv.IsInvincible && !info.Flags.HasFlag(DamageFlags.IgnoreIFrame))
return;
// ── Step 2: 计算最终伤害 ─────────────────────────────────────────────────
int finalDamage = info.DamageType == DamageType.True
? info.RawDamage
: Mathf.Max(1, info.RawDamage - _defenseStat);
// ── Step 3: 霸体打断检查 ─────────────────────────────────────────────────
bool interrupted = ShouldInterrupt(info);
// ── Step 4: 应用伤害 ─────────────────────────────────────────────────────
_owner.TakeDamage(finalDamage);
OnHitConfirmedChannel.Raise(info);
OnHurt.Invoke(info);
// ── Step 5: 条件性打断 ────────────────────────────────────────────────────
if (interrupted)
{
_owner.ApplyKnockback(info);
_owner.ForceState(HurtState); // 取消当前动作,进入硬直
}
else
{
// 仅播放受击闪烁/震屏,不打断动作
_owner.PlayHitFlash();
}
}
/// <summary>综合三层规则判断是否发生打断</summary>
bool ShouldInterrupt(DamageInfo info)
{
// 获取当前霸体等级
PoiseLevel poise = (_owner as IPoiseSource)?.CurrentPoise ?? PoiseLevel.None;
// Unbreakable 不可打断(即使有 ForceBreak 标记)
if (poise == PoiseLevel.Unbreakable) return false;
// Layer 1: 显式 PoiseOverrideTable 查询
if (_overrideTable != null)
{
PoiseOverrideResult? ov = _overrideTable.Query(info.SourceId, _owner.StateId);
if (ov == PoiseOverrideResult.AlwaysInterrupt) return true;
if (ov == PoiseOverrideResult.NeverInterrupt) return false;
}
// Layer 2: DamageFlags.ForceBreak — 无视霸体等级(Unbreakable 已在上面拦截)
if (info.Flags.HasFlag(DamageFlags.ForceBreak)) return true;
// Layer 3: 默认数值比较
return (int)info.BreakLevel >= (int)poise;
}
新增 DamageFlags
public enum DamageFlags
{
// ... 原有 flags ...
CanBeParried = 1 << 0,
Unblockable = 1 << 1,
IgnoreIFrame = 1 << 2,
PerfectParryOnly = 1 << 3,
IsProjectile = 1 << 4,
CanClash = 1 << 5,
// 新增
ForceBreak = 1 << 6, // 强制打断目标当前动作(忽略霸体等级,Unbreakable 除外)
NoKnockback = 1 << 7, // 打断时不施加击退(仅进入 HurtState 硬直)
}
6. DamageInfo / DamageSourceSO 扩展
DamageInfo 新增字段
public struct DamageInfo
{
// ... 原有字段 ...
/// <summary>
/// 此次攻击的打断等级。由 DamageSourceSO.breakLevel 赋值,
/// 弹射物等特殊攻击由创建者手动指定。
/// </summary>
public BreakLevel BreakLevel;
/// <summary>
/// 攻击来源标识(用于 PoiseOverrideTable 查询)。
/// 格式:DamageSourceSO.sourceId 或 SkillSO.skillId。
/// </summary>
public string SourceId;
}
DamageSourceSO 新增字段
public class DamageSourceSO : ScriptableObject
{
// ... 原有字段 ...
[Header("霸体系统")]
[Tooltip("此攻击的打断等级(决定能打断多高的霸体)")]
public BreakLevel breakLevel = BreakLevel.None;
[Tooltip("是否强制打断(ForceBreak)—— 无视目标霸体等级,Unbreakable 除外")]
public bool forceBreak = false;
}
HitBox 构建 DamageInfo 时:
var info = new DamageInfo
{
// ... 原有赋值 ...
BreakLevel = _damageSource.breakLevel,
SourceId = _damageSource.sourceId,
// ForceBreak 标记
DamageFlags = _damageSource.forceBreak
? _damageSource.DamageFlags | DamageFlags.ForceBreak
: _damageSource.DamageFlags,
};
7. 玩家霸体配置
7.1 攻击状态霸体
PlayerStateBase 提供默认实现;AttackState 根据当前武器动画帧动态更新霸体等级:
public abstract class PlayerStateBase : StateObject, IPoiseSource
{
/// <summary>此状态的默认霸体等级(子类可覆盖)</summary>
public virtual PoiseLevel CurrentPoise => PoiseLevel.None;
/// <summary>外部查询时使用的状态 ID(用于 PoiseOverrideTable)</summary>
public virtual string StateId => GetType().Name;
}
public class AttackState : PlayerStateBase
{
// 从当前武器 SO 读取当前段的霸体配置
public override PoiseLevel CurrentPoise
{
get
{
WeaponSO w = _weaponManager.ActiveWeapon;
PoiseWindowConfig cfg = _comboState switch
{
ComboState.Attack1 => w.attack1PoiseWindow,
ComboState.Attack2 => w.attack2PoiseWindow,
ComboState.Attack3 => w.attack3PoiseWindow,
ComboState.AirAttack => w.airAttackPoiseWindow,
ComboState.UpAttack => w.upAttackPoiseWindow,
ComboState.DownAttack => w.downAttackPoiseWindow,
_ => PoiseWindowConfig.None,
};
float t = _animancer.Layers[0].CurrentState?.NormalizedTime ?? 0f;
return cfg.IsActiveAt(t) ? cfg.level : PoiseLevel.None;
}
}
}
WeaponSO 新增攻击霸体窗口字段(见 53_WeaponSystem §2):
[Header("霸体配置(每段攻击)")]
public PoiseWindowConfig attack1PoiseWindow; // 默认 None(普通轻击无霸体)
public PoiseWindowConfig attack2PoiseWindow;
public PoiseWindowConfig attack3PoiseWindow; // 通常配置 Light 霸体(重击前摇)
public PoiseWindowConfig airAttackPoiseWindow;
public PoiseWindowConfig upAttackPoiseWindow;
public PoiseWindowConfig downAttackPoiseWindow;
三形态武器攻击霸体预设
| 动作 | 天魂(SkyBlade) | 地魂(EarthHammer) | 命魂(LifeScythe) |
|---|---|---|---|
| Attack1 | None | None | None |
| Attack2 | None | None | None |
| Attack3 | Light(0.0-0.5 前摇) | Medium(全程) | Light(全程) |
| AirAttack | None | None | None |
| UpAttack | None | None | None |
| DownAttack | None | None | None |
7.2 技能施放霸体(FormSkillSO)
FormSkillSO 新增 poiseWindow 字段:
[Header("霸体配置")]
[Tooltip("技能施放期间的霸体窗口。None = 可被任何攻击打断。")]
public PoiseWindowConfig poiseWindow;
SkillManager 在技能施放期间作为 IPoiseSource:
public class SkillManager : MonoBehaviour, IPoiseSource
{
FormSkillSO _activeCastingSkill;
float _castStartTime;
public PoiseLevel CurrentPoise
{
get
{
if (_activeCastingSkill == null) return PoiseLevel.None;
float elapsed = Time.time - _castStartTime;
float duration = _activeCastingSkill.castLockDuration;
float normalized = Mathf.Clamp01(duration > 0 ? elapsed / duration : 1f);
return _activeCastingSkill.poiseWindow.IsActiveAt(normalized)
? _activeCastingSkill.poiseWindow.level
: PoiseLevel.None;
}
}
}
九种技能施放霸体预设:
| 技能 | 形态 | 效果类型 | poiseWindow |
|---|---|---|---|
| 裂空掌 | 天魂 | MeleeAoE | Light(0.0-0.6) — 出手前摇有轻霸体 |
| 漩灵击 | 天魂 | BarrierAura | Medium(全程) — 护盾持续期间中霸体 |
| 灵踪弹 | 天魂 | Projectile | None — 远程技能无前摇霸体 |
| 地行术 | 地魂 | GroundDive | Unbreakable(全程) — 入地期间完全无敌 |
| 霸山拳 | 地魂 | MeleeAoE | Heavy(0.0-0.4) — 蓄力起手重霸体 |
| 魂元爆 | 地魂 | DelayedExplosion | Light(0.0-0.3) — 放置前摇轻霸体 |
| 登龙蹴 | 命魂 | DragonKick | Heavy(全程) — 升龙整段重霸体 |
| 太虚斩 | 命魂 | WraithDash | Medium(全程) — 冲刺中霸体 |
| 残阴术 | 命魂 | ShadowDecoy | None — 残影技能无霸体 |
7.3 能力状态霸体
| 状态类 | CurrentPoise 返回值 |
说明 |
|---|---|---|
IdleState |
None |
站立无霸体 |
RunState |
None |
跑动无霸体 |
AttackState |
见 §7.1(动态) | 武器 SO 配置 |
DashState |
None(使用 IFrame 代替) |
冲刺靠无敌帧保护 |
AirState |
None |
空中无霸体 |
SpringState |
Heavy |
灵泉治疗全程重霸体(不可轻易打断) |
WallGrabState |
Light |
墙壁悬挂轻霸体(强击可推下) |
ParryState |
Medium |
弹反动作中霸体(弹反窗口内) |
HurtState |
None |
受击硬直无霸体 |
DeathState |
Unbreakable |
死亡动画完整播放 |
8. 敌人 / Boss 霸体配置(BossSkillSO)
BossSkillSO 新增霸体配置:
// ─────────────────────────────
// 8. 霸体配置(新增)
// ─────────────────────────────
[Header("霸体配置")]
[Tooltip("此技能执行期间的霸体窗口(None = 可被玩家攻击打断)")]
public PoiseWindowConfig poiseWindow;
AttackPatternSO(19_BossPatternLibrary)也添加打断等级,以描述单次动作模式的打断能力:
[Header("打断能力")]
[Tooltip("此攻击动作对玩家霸体的打断等级")]
public BreakLevel breakLevel = BreakLevel.Light;
Boss 技能霸体分类建议
| Boss 技能类型 | 推荐 poiseWindow |
|---|---|
Melee 近战普通攻击 |
Light(全程) |
Charge 冲刺突进 |
Medium(全程) |
AoE 大范围爆炸 |
Heavy(0.0-0.5 蓄力段) |
Phase 阶段转换 |
Unbreakable(全程) |
Reactive 反制技 |
Medium(全程) |
Buff 自身增益 |
Heavy(全程) |
Summon 召唤技 |
Light(全程) |
普通敌人霸体(EnemyBase 扩展)
普通敌人通过 EnemyConfigSO 配置站立/攻击状态的霸体等级:
[Header("霸体配置")]
public PoiseLevel idlePoise = PoiseLevel.None; // 站立/游荡时
public PoiseLevel attackPoise = PoiseLevel.Light; // 攻击动作时
public PoiseLevel staggerThreshold = PoiseLevel.None; // 受到同级霸体时触发僵直动画
9. 显式打断关系表(PoiseOverrideTableSO)
当默认数值规则不满足精细设计需求时,PoiseOverrideTableSO 允许指定特定攻击 vs 特定状态的强制规则:
namespace BaseGames.Combat
{
/// <summary>
/// 显式打断关系配置表。HurtBox 在数值比较前优先查询此表。
/// 用于设计"某 Boss 技能无论玩家霸体多高都必须打断"等特殊场合。
/// </summary>
[CreateAssetMenu(menuName = "Combat/PoiseOverrideTable")]
public class PoiseOverrideTableSO : ScriptableObject
{
public List<PoiseOverrideEntry> entries;
public PoiseOverrideResult? Query(string attackSourceId, string targetStateId)
{
foreach (var e in entries)
{
bool matchAtk = string.IsNullOrEmpty(e.attackSourceId)
|| e.attackSourceId == attackSourceId;
bool matchTarget = string.IsNullOrEmpty(e.targetStateId)
|| e.targetStateId == targetStateId;
if (matchAtk && matchTarget)
return e.alwaysInterrupt
? PoiseOverrideResult.AlwaysInterrupt
: PoiseOverrideResult.NeverInterrupt;
}
return null; // 无显式规则,走默认数值逻辑
}
}
[Serializable]
public class PoiseOverrideEntry
{
[Tooltip("攻击来源 ID(DamageSourceSO.sourceId 或 skillId)。留空 = 匹配所有攻击来源。")]
public string attackSourceId;
[Tooltip("被打断状态 ID(PlayerStateBase.StateId 或 BossSkillSO.skillId)。留空 = 匹配所有状态。")]
public string targetStateId;
[Tooltip("true = 强制打断(无视目标霸体等级,Unbreakable 除外)")]
public bool alwaysInterrupt;
[Tooltip("true = 永不打断(无视打断等级,受击仅扣血)")]
public bool neverInterrupt;
[TextArea(1, 2)]
[Tooltip("记录此规则的设计原因")]
public string designNote;
}
public enum PoiseOverrideResult { AlwaysInterrupt, NeverInterrupt }
}
资产存放:Assets/ScriptableObjects/Combat/PoiseOverrideTable.asset
配置示例:
// 规则 1: Boss"虚空起源"的阶段2核心技能"星陨重压"强制打断玩家地行术(即使地行术是 Unbreakable)
attackSourceId = "VoidOrigin_StarCrash"
targetStateId = "GroundDiveState"
alwaysInterrupt = true ← 注意:此处会覆盖 Unbreakable(慎用)
designNote = "设计意图:玩家不能通过地行术无伤躲过阶段技"
// 规则 2: 玩家弹反成功后的反击(ParryCounter)永不被任何敌人打断
attackSourceId = "" // 空 = 所有攻击来源
targetStateId = "ParryCounterState"
neverInterrupt = true
designNote = "弹反反击动作不应被打断,维护弹反奖励感"
// 规则 3: 精英敌人"石甲虫"的普通攻击对玩家施放天魂所有技能均无法打断
attackSourceId = "StoneArmadillo_Attack"
targetStateId = "" // 空 = 所有玩家状态
neverInterrupt = true
designNote = "石甲虫攻击较弱,不应打断任何玩家行动"
10. 全动作霸体参考表
玩家攻击打断等级
| 动作 | 天魂 BreakLevel | 地魂 BreakLevel | 命魂 BreakLevel |
|---|---|---|---|
| Attack1 | Light | Medium | Light |
| Attack2 | Light | Medium | Light |
| Attack3 | Medium | Heavy | Medium |
| AirAttack | Light | Medium | Light |
| UpAttack | Light | Medium | Light |
| DownAttack(Pogo) | Light | Medium | Light |
| ParryCounter | Heavy | Heavy | Heavy |
地魂武器整体打断等级高一级,体现"重击"特性。
玩家技能打断等级
| 技能 | BreakLevel | 说明 |
|---|---|---|
| 裂空掌 | Heavy | 近战 AoE,高打断 |
| 漩灵击 | Medium | 护体,打断中等 |
| 灵踪弹 | Light | 弹射物,轻打断 |
| 地行术 | None | 入地,无接触打断 |
| 霸山拳 | Breaker | 破甲重拳 |
| 魂元爆 | Medium | 爆炸,中等打断 |
| 登龙蹴 | Heavy | 升龙,高打断 |
| 太虚斩 | Medium | 冲刺斩,中打断 |
| 残阴术(残影攻击) | Light | 残影,轻打断 |
能力状态打断等级(玩家被击时视角)
(参见 §7.3 能力状态霸体表)
11. 平衡设计准则
玩家侧
- 普通连击段(Attack1/2) 一般不给霸体,保持高风险高收益的近身博弈感
- 第三段(Attack3) 给
Light或Medium霸体,奖励打完完整连击的玩家 - 重要技能施放(霸山拳、登龙蹴)给
Medium–Heavy霸体,让技能"值得放" - 灵泉治疗 给
Heavy霸体,保证玩家有机会用完一个治疗不被打断 - 冲刺 使用 IFrame 而非霸体(短距离无敌,不受霸体系统管辖)
敌人侧
- 普通敌人攻击 BreakLevel 统一为
Light(只能打断无霸体动作) - 精英怪攻击 BreakLevel 可到
Medium(能打断玩家轻霸体) - Boss 核心技能 BreakLevel 可到
Heavy或Breaker(压制玩家大部分动作) - Boss 蓄力/前摇 poiseWindow 给
Heavy,让玩家意识到"这招不能被随意取消"
禁止事项
| 禁止 | 原因 |
|---|---|
给 Unbreakable 的攻击设置 PoiseOverrideEntry.alwaysInterrupt |
会破坏设计安全感,须经负责人审核 |
| 玩家普通攻击 BreakLevel ≥ Heavy | 普通攻击打断 Boss 重霸体会让 Boss 失去压迫感 |
| BreakLevel = Breaker 的弹射物 | 远程破甲会使近战霸体设计失去意义 |
12. 编辑器友好设计
HurtBox Gizmo 可视化
运行时暂停时,HurtBox 的 Gizmo 显示:
受击对象: Player
当前状态: AttackState (Attack3)
当前霸体: Medium [窗口 0.0 ~ 1.0 全程]
最近受击: DS_Boss_Charge (BreakLevel: Heavy)
打断结果: ✅ Interrupted (Heavy >= Medium)
PoiseOverrideTable 编辑器窗口
Tools → Zeling → Poise Override Table:
┌─ Poise Override Table ─────────────────────────────────────┐
│ [自动验证:检查 attackSourceId / targetStateId 是否存在] │
│ │
│ # | 攻击来源 | 目标状态 | 类型 │
│ 1 | VoidOrigin_Star | GroundDiveState | AlwaysBreak │
│ 2 | (全部) | ParryCounterState | NeverBreak │
│ ... │
│ [+ 添加规则] [导出 CSV] [验证全部] │
└────────────────────────────────────────────────────────────┘
自动验证会检查:
attackSourceId对应的DamageSourceSO/FormSkillSO/BossSkillSO是否存在targetStateId对应的PlayerStateBase子类或BossSkillSO.skillId是否存在- 是否同时勾选
alwaysInterrupt和neverInterrupt(互斥,报错)