fix: 修复 AttackState 动画结束后等待阶段的逻辑,确保播放新动画以避免重复触发事件

This commit is contained in:
2026-05-22 13:12:16 +08:00
parent af82b2b325
commit e7b44e1d60
2 changed files with 371 additions and 1 deletions

View File

@@ -171,7 +171,11 @@ namespace BaseGames.Player.States
// 已是最后一段:消耗掉多余输入,继续进入等待阶段(不 return // 已是最后一段:消耗掉多余输入,继续进入等待阶段(不 return
} }
// 进入动画后等待阶段 // 进入动画后等待阶段
// 必须播放新动画Idle否则 Animancer End Event 会在每帧重复触发 OnClipEnd。
if (AnimCfg?.Idle != null)
Anim.Play(AnimCfg.Idle);
var step = Owner.Weapon?.ActiveWeapon?.GetGroundStep(_comboIndex) ?? default; var step = Owner.Weapon?.ActiveWeapon?.GetGroundStep(_comboIndex) ?? default;
float spd = Stats?.AnimatorSpeedMultiplier ?? 1f; float spd = Stats?.AnimatorSpeedMultiplier ?? 1f;
float now = Time.time; float now = Time.time;

View File

@@ -0,0 +1,366 @@
# WeaponSO 武器调参指南
**配置文件**`Assets/_Game/Data/Combat/Weapons/WPN_*.asset`
**对应脚本**`WeaponSO.cs` · `ComboStepConfig` · `WeaponVFXConfig`
**创建工具**Unity 菜单 `BaseGames/Data/Weapon Editor`(勿直接在 Project 窗口创建)
**影响系统**`WeaponManager` · `WeaponHitBoxInstance` · `PlayerCombat` · `FormController`
---
## 一、架构概述
```
WeaponSO
├── 基础信息weaponId / displayName / icon / weaponType
├── groundComboSteps[] ── 地面连击(任意段数)
├── airComboSteps[] ── 空中攻击(通常 1 段)
├── upStep ── 上劈(固定单段)
├── downStep ── 下劈(固定单段)
├── hitBoxPrefab ── 武器 HitBox Prefab含 WeaponHitBoxInstance
├── vfxConfig ── 特效配置
└── soulPowerGain ── 命中灵力获取量
每段攻击的核心数据由 ComboStepConfig 描述:
ComboStepConfig
├── clip ── Animancer ClipTransition动画片段
├── damageSource ── DamageSourceSO伤害参数
├── hitBoxEnter/Exit ── HitBox 激活窗口(归一化 0-1
├── comboInputOpen/Close── 连击接受窗口(归一化 0-1
├── cancelWindowOpen ── 跳跃/冲刺取消窗口(归一化 0-1
├── recoveryTime ── 动画结束后硬直(秒)
├── comboTimeout ── 等待下一段连击的超时(秒)
└── hitBoxId ── 指定激活 Prefab 中的具名 HitBox空=方向默认)
```
**WeaponManager** 监听 `FormController.OnFormChanged`,依据当前形态或护符 Override 切换 `ActiveWeapon`,并在 `[WeaponSocket]` 下实例化/池化对应 `hitBoxPrefab`
---
## 二、基础信息字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `weaponId` | string | 全局唯一 ID命名规范`Weapon_<主题名>`,如 `Weapon_SkyBlade`。**必须唯一,运行时依此检索。** |
| `displayName` | string | UI 显示名,如 `天裂刃`。 |
| `icon` | Sprite | HUD / 物品栏图标。 |
| `weaponType` | WeaponType | 枚举,影响动画控制器分支和特殊逻辑:`TianHun`(天魂)/ `DiHun`(地魂)/ `MingHun`(命魂)/ `Custom`。 |
---
## 三、ComboStepConfig 字段详解
### 3.1 动画 & 伤害
| 字段 | 类型 | 说明 |
|---|---|---|
| `clip` | ClipTransition | Animancer 动画片段引用。在 Inspector 中直接拖入 AnimationClip 资产Animancer 自动包装为 Transition。 |
| `damageSource` | DamageSourceSO | 本段攻击的伤害数据 SO详见第五节。**每段连击可独立配置不同伤害参数**,如首段轻击、末段重击。 |
### 3.2 HitBox 激活窗口(归一化 0-1
> 所有归一化时间均相对于该段动画片段的**总时长**。0 = 动画开始1 = 动画结束。
| 字段 | 范围 | 说明 |
|---|---|---|
| `hitBoxEnter` | [0, 1] | HitBox Collider2D 开启时间点。过早会导致判定在动作启动前已生效(容易打中玩家不期待的时机)。 |
| `hitBoxExit` | [0, 1] | HitBox Collider2D 关闭时间点。`hitBoxExit > hitBoxEnter`,差值越大判定活跃窗口越长。 |
**经验准则**
- 轻击:窗口宽度约 `0.25-0.35`(如 `Enter=0.25, Exit=0.55`
- 重击:窗口宽度约 `0.35-0.55`动作前摇长Enter 较晚)
- 判定窗口开始前应能看到挥砍动作的启动帧,避免"隐形打击"
### 3.3 连击输入窗口(归一化 0-1
| 字段 | 范围 | 说明 |
|---|---|---|
| `comboInputOpen` | [0, 1] | 从此时间点起**开始接受**下一段连击输入。设为 `0` = 动画一开始就可以缓冲输入。 |
| `comboInputClose` | [0, 1] | 从此时间点起**停止接受**连击输入(必须在 `comboInputOpen` 之后)。设为 `0` = 持续到动画结束。 |
**经验准则**
- `comboInputOpen` 建议设在 HitBox 激活之后(让玩家确认打中后才能输入连击)
- 对于高速连击,`comboInputOpen = 0`(从头缓冲)可提升流畅感
- `comboInputClose = 0`(持续到动画结束)是最宽松的设定,适合友好手感
### 3.4 取消窗口(归一化 0-1
| 字段 | 范围 | 说明 |
|---|---|---|
| `cancelWindowOpen` | [0, 1] | 从此时间点起**允许跳跃/冲刺打断**本段攻击。设为 `0` = 仅在动画结束后的恢复期内允许取消。 |
**经验准则**
- 过早打开(如 `0.2`)会让攻击感觉"没有重量",玩家容易意外取消
- 推荐在动画进入收招阶段时开放,约 `0.5-0.6`
- 下劈攻击Pogo 跳)通常设得较早(`0.3`),便于空中快速接跳
### 3.5 时间参数(秒,受攻速倍率缩放)
| 字段 | 最小值 | 说明 |
|---|---|---|
| `recoveryTime` | 0 | 动画结束后的**硬直时间**(秒),期间跳跃/冲刺无法打断。模拟挥空后的惯性/踉跄。 |
| `comboTimeout` | 0 | 硬直结束后**等待连击输入的时间**(秒)。超时则返回 Idle 状态。设为 `0` = 立即返回 Idle。 |
> ⚠️ 这两个参数受攻速倍率缩放。`recoveryTime = 0.05f` 是默认最低有效值,不建议设 `0`(否则帧序列可能出现单帧状态切换问题)。
### 3.6 HitBox 绑定 ID
| 字段 | 说明 |
|---|---|
| `hitBoxId` | 留空 → 使用该方向的**默认 HitBox**WeaponHitBoxInstance 中对应方向的字段);<br>非空 → **按 Id 精确激活** Prefab 中对应子节点的 HitBox可为每段连击配置不同的判定形状。 |
**使用时机**
- 连击首段和末段的判定范围不同时(如末段范围更大)
- 需要多个独立判定区域时(如武器特殊技能)
---
## 四、DamageSourceSO 关键参数
每个 `ComboStepConfig.damageSource` 引用一个独立的 `DamageSourceSO` 资产,资产命名规范:`CMB_DmgSrc_<武器ID>_<段序号>.asset`,存放于 `_Game/Data/Combat/DamageSources/`
| 字段 | 默认值 | 说明 |
|---|---|---|
| `BaseDamage` | 10 | 本段攻击基础伤害值(整型)。 |
| `DamageMultiplier` | 1.0 | 倍率,最终伤害 = `Round(BaseDamage × DamageMultiplier)`。 |
| `Type` | Normal | 伤害元素类型(`Normal` / `Fire` / `Poison` / `Ice` / `Lightning` / `Void` / `True`)。`True` = 无视防御的真实伤害。 |
| `Category` | NormalAttack | 来源分类,影响护符/技能的条件判断(如"普通攻击命中时触发")。 |
| `Flags` | CanBeParried | 行为标志(可组合)。常见组合见下表。 |
| `Tags` | MeleeHit | 交互标签(可组合),配合 DamageTags 枚举使用。 |
| `KnockbackForce` | 5.0 | 击退力度(单位/秒,直接施加速度)。 |
| `HitStunDuration` | 0.1 | 击中后的受击硬直时间(秒)。 |
| `BreakLevel` | Light | 攻击方打断等级,与敌人 `PoiseLevel` 比较决定是否打断霸体。 |
| `FxType` | Slash | 命中特效类型,决定播放哪套打击感反馈预设。 |
**DamageFlags 常用组合**
| 组合 | 适用场景 |
|---|---|
| `CanBeParried` | 普通攻击(可被格挡) |
| `CanBeParried \| CanClash` | 可碰撞武器(弹反对碰) |
| `Unblockable` | 突破技/破防攻击 |
| `CanBeParried \| PerfectParryOnly` | 高危攻击,仅完美格挡才能弹反 |
| `NoKnockback` | 固定伤害(毒、灼烧等 DoT 不需要击退) |
---
## 五、WeaponVFXConfig 字段
| 字段 | 说明 |
|---|---|
| `onEquipPresetId` | 切换到此武器时播放的特效预设 ID对应 `IFeedbackPlayer.TriggerPreset`。空 = 不播放切换特效。 |
| `weaponTrailPrefab` | 挥斩拖尾 Prefabnull = 不显示拖尾)。拖尾 Prefab 应含 `TrailRenderer` 或自定义拖尾脚本。 |
| `trailColor` | 拖尾颜色,可在 Inspector 中用 HDR 色板设定发光颜色。默认白色。 |
---
## 六、战斗参数
| 字段 | 默认值 | 说明 |
|---|---|---|
| `soulPowerGain` | 10 | **命中确认时增加的灵力值**,覆盖 PlayerCombat 全局默认值(也为 10。可对强力武器设更高值如 DiHun 重击设 15-20鼓励玩家积极进攻。 |
---
## 七、推荐配置
### 7.1 时间轴可视化参考
以下图示展示一段典型地面连击的时间轴布局(归一化 0-1
```
0 ────────────────────────────────────── 1 (动画片段)
│←── HitBox 激活窗口 ──→│
hitBoxEnter(0.25) hitBoxExit(0.60)
│←── 连击输入开放 ─────────────────────→│
comboInputOpen(0.20) comboInputClose(0=持续到结束)
│← 取消窗口(可跳/冲) →│
cancelWindowOpen(0.50)
完整时间轴:
[动画] ────────────────────────── [recoveryTime] [comboTimeout]
|←─ 0.05s ──→||←── 0.25s ──→|
```
### 7.2 天魂 TianHun高频轻击如天裂刃
> 定位高频连击4 段地面 + 1 段空中,每段伤害低但命中频繁,玩家可快速积累灵力。
#### 地面连击4 段)
| 参数 | 第 1 段 | 第 2 段 | 第 3 段 | 第 4 段(末段) |
|---|---|---|---|---|
| `hitBoxEnter` | 0.25 | 0.20 | 0.20 | 0.30 |
| `hitBoxExit` | 0.55 | 0.50 | 0.55 | 0.70 |
| `comboInputOpen` | 0.20 | 0.15 | 0.15 | 0 |
| `comboInputClose` | 0 | 0 | 0 | 0 |
| `cancelWindowOpen` | 0.55 | 0.50 | 0.50 | 0.60 |
| `recoveryTime` | 0.05 | 0.05 | 0.05 | 0.08 |
| `comboTimeout` | 0.20 | 0.20 | 0.20 | 0.15 |
#### 空中攻击1 段)
| 参数 | 推荐值 |
|---|---|
| `hitBoxEnter` | 0.10 |
| `hitBoxExit` | 0.70 |
| `comboInputOpen` | 0 |
| `cancelWindowOpen` | 0.40 |
| `recoveryTime` | 0.05 |
#### 上劈 / 下劈
| 参数 | 上劈 | 下劈 |
|---|---|---|
| `hitBoxEnter` | 0.20 | 0.10 |
| `hitBoxExit` | 0.65 | 0.85 |
| `cancelWindowOpen` | 0.55 | 0.30(早开放,便于 Pogo |
| `recoveryTime` | 0.05 | 0.05 |
#### DamageSource 参数(天魂各段参考)
| 参数 | 第 1-3 段 | 第 4 段(末段) |
|---|---|---|
| `BaseDamage` | 8 | 12 |
| `DamageMultiplier` | 1.0 | 1.2 |
| `KnockbackForce` | 3.0 | 5.0 |
| `HitStunDuration` | 0.08 | 0.12 |
| `BreakLevel` | Light | Medium |
| `FxType` | Slash | Slash |
| `Flags` | CanBeParried | CanBeParried |
**soulPowerGain**`10`(每段命中均为标准值,高频命中本身已能快速积累)
---
### 7.3 地魂 DiHun低频重击如地震锤
> 定位2 段地面,前摇长、打击感强,单段伤害高,击退效果明显,适合破霸体。
#### 地面连击2 段)
| 参数 | 第 1 段 | 第 2 段(蓄力重击) |
|---|---|---|
| `hitBoxEnter` | 0.40 | 0.50 |
| `hitBoxExit` | 0.70 | 0.85 |
| `comboInputOpen` | 0.35 | 0 |
| `comboInputClose` | 0 | 0 |
| `cancelWindowOpen` | 0.65 | 0.70 |
| `recoveryTime` | 0.12 | 0.20 |
| `comboTimeout` | 0.30 | 0.20 |
#### 空中攻击1 段,范围攻击)
| 参数 | 推荐值 |
|---|---|
| `hitBoxEnter` | 0.20 |
| `hitBoxExit` | 0.80 |
| `cancelWindowOpen` | 0.60 |
| `recoveryTime` | 0.10 |
#### DamageSource 参数(地魂各段参考)
| 参数 | 第 1 段 | 第 2 段 |
|---|---|---|
| `BaseDamage` | 18 | 28 |
| `DamageMultiplier` | 1.0 | 1.3 |
| `KnockbackForce` | 7.0 | 12.0 |
| `HitStunDuration` | 0.15 | 0.25 |
| `BreakLevel` | Medium | Heavy |
| `FxType` | Heavy | Heavy |
| `Flags` | CanBeParried \| CanClash | CanBeParried \| CanClash |
**soulPowerGain**`18`(重击命中奖励更多灵力,鼓励玩家进行高风险的大招命中)
---
### 7.4 命魂 MingHun穿透直线斩命镰
> 定位3 段地面,带穿透 Tag直线攻击范围长无强力击退适合多目标清线。
#### 地面连击3 段)
| 参数 | 第 1 段 | 第 2 段 | 第 3 段(穿透斩) |
|---|---|---|---|
| `hitBoxEnter` | 0.20 | 0.20 | 0.25 |
| `hitBoxExit` | 0.55 | 0.55 | 0.75 |
| `comboInputOpen` | 0.20 | 0.20 | 0 |
| `comboInputClose` | 0 | 0 | 0 |
| `cancelWindowOpen` | 0.50 | 0.50 | 0.60 |
| `recoveryTime` | 0.06 | 0.06 | 0.10 |
| `comboTimeout` | 0.25 | 0.25 | 0.20 |
#### DamageSource 参数(命魂各段参考)
| 参数 | 第 1-2 段 | 第 3 段(穿透) |
|---|---|---|
| `BaseDamage` | 10 | 16 |
| `DamageMultiplier` | 1.0 | 1.1 |
| `KnockbackForce` | 2.0 | 3.0 |
| `HitStunDuration` | 0.10 | 0.12 |
| `BreakLevel` | Light | Light |
| `FxType` | Slash | Void |
| `Flags` | CanBeParried | CanBeParried |
| `Tags` | MeleeHit | MeleeHit \| DeathFormOnly |
**soulPowerGain**`12`(中等收益,穿透多目标时单次激活返回较多灵力)
---
## 八、三武器横向对比
| 属性 | TianHun天魂 | DiHun地魂 | MingHun命魂 |
|---|---|---|---|
| 连击段数 | 4 段 | 2 段 | 3 段 |
| 单段基础伤害 | 8-12 | 18-28 | 10-16 |
| 击退力度 | 低3-5 | 高7-12 | 极低2-3 |
| HitStun | 短0.08-0.12s | 长0.15-0.25s | 中0.10-0.12s |
| BreakLevel | Light → Medium | Medium → Heavy | Light |
| HitBox 窗口宽度 | 窄(~0.30 | 宽(~0.35 | 中(~0.35-0.50 |
| recoveryTime 末段 | 0.08s | 0.20s | 0.10s |
| soulPowerGain | 10 | 18 | 12 |
| 特色 | 高频灵力积累 | 破霸体/强力击退 | 穿透多目标 |
---
## 九、HitBox Prefab 配置要点
命名规范:`WPN_{weaponId}_HitBox.prefab`,存放于 `Assets/_Game/Prefabs/Weapons/`
```
[WPN_SkyBlade_HitBox] ← WeaponHitBoxInstance 脚本
├── [HitBox_Ground] Id="" ← 方向默认Inspector 引用到 _hitBoxGround
├── [HitBox_Ground_3] Id="g3" ← 第 3 段专属判定(更大范围)
├── [HitBox_Up] Id="" ← 上劈默认Inspector 引用到 _hitBoxUp
├── [HitBox_Down] Id="" ← 下劈默认Inspector 引用到 _hitBoxDown
└── [HitBox_Air] Id="" ← 空中默认Inspector 引用到 _hitBoxAir
```
- **不要**在 HitBox Prefab 上挂 Rigidbody2D由父节点 Player 提供物理)
- Collider2D 默认 **disabled**,由 `HitBox.Activate()` 开启
- 多段攻击需要不同判定形状时,添加具名子节点,在对应 `ComboStepConfig.hitBoxId` 中填写对应 Id
---
## 十、常见调参问题排查
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 攻击时判定出现太早,感觉"不对" | `hitBoxEnter` 过小 | 调高至 0.25-0.35,与动画挥砍帧对齐 |
| 连击无法触发,只能打第 1 段 | `comboInputOpen` 太晚或 `comboInputClose` 太早 | 调低 `comboInputOpen`(或设 0确认 `comboInputClose` 为 0 |
| 攻击后无法立即跳跃/冲刺 | `cancelWindowOpen` 过大或 `recoveryTime` 过长 | 降低 `cancelWindowOpen`0.50-0.55),减小 `recoveryTime` |
| 末段后角色卡顿太久才能动 | `recoveryTime` + `comboTimeout` 总计过长 | 减小其中一个或两者都减小 |
| HitBox 命中范围与动画不匹配 | HitBox Prefab 中 Collider2D 形状未对齐 | 在 Scene 视图的 Gizmos 开启后,逐帧检查碰撞体位置 |
| 连击结束后立刻返回 Idle没有残影感 | `comboTimeout = 0` | 设为 `0.15-0.25s`,让玩家有余裕进行下一段连击 |
| 重击前摇太短,没有"蓄力感" | `hitBoxEnter` 过小(前摇太短就进入判定) | 调高至 0.40-0.55,延长前摇 |
| 空中攻击结束后角色位移异常 | HitBox 取消窗口过早,冲刺接入空攻状态 | 调高 `cancelWindowOpen`(≥ 0.50)或检查状态机过渡条件 |
| 命中无灵力回复 | `damageSource` 引用为空,或 `soulPowerGain = 0` | 检查每个 ComboStepConfig 的 `damageSource` 字段不为 null |
---
## 十一、修改历史
| 日期 | 修改内容 |
|---|---|
| 2026-05-22 | 初版:覆盖 WeaponSO 全部字段说明、三武器推荐配置及调参排查表 |