docs(enemy): Boss AI 单轨落地——新增作者指南,清理描述已删除系统的长期文档
新增 Docs/Guides/09_BossAi_Authoring_Guide.md: 定制路径写法([AiDefinition] + AiScript)、建态原语(AiStateFragments + BossFragments + IBossControl)、阶段=换招池、一招怎么配(EnemyAbilitySO + EnemyAttackSO + 动画事件)、开战触发、死亡归物理层, 以已落地的 ChaoFengAi 为逐段范例,附 Boss 专属陷阱与已知缺口。 08 号指南加交叉引用。 删除两份整份描述已删除且从未实现的体系的文档: Docs/Architecture/23_BossSkillModule.md、Docs/Design/47_BossSkillSystem.md。 删前已确认全库无 Markdown 链接残留,索引行与关联文档行改指新指南或 spec。 修订:25_CharacterArchitectureOverview §4 Boss 章节按实际代码重写; 07_EnemyModule 加过时提示、§11 改重定向;02_EventSystem 修正 Boss 事件发送方; 19_BossPatternLibrary 加废止提示(设计意图仍有效,类型名已废); AssetFolderSpec 删旧 Boss 技能编辑器条目;三处 README/索引同步。 Docs_Dev/ 历史记录保留不动。 spec 标记为已实施,并记录实施期偏差(无 Boss 骨架、Telegraph 枚举保留、 阶段直查不走黑板、BossSkillEvent 一并删除)与八项已知未完成项, 其中 EnemyHurtState 无受击动画永久卡死为最高优先级、且与 Boss 轨无关。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
| 16 | MapSystem | 15_MapShopModule §1 | ✅ | 完整 |
|
||||
| 17 | EquipmentSystem | 09_ProgressionModule | ✅ | 完整 |
|
||||
| 18 | CutsceneSystem | 14_NarrativeModule §7 | ✅ | CutsceneTrigger/CutsceneSO 已定义 |
|
||||
| 19 | BossPatternLibrary | **23_BossSkillModule** | ✅ | BossSkillSO/SkillSequenceSO/WeakPointSystem 全部定义 |
|
||||
| 19 | BossPatternLibrary | **07_EnemyModule** · `Docs/Guides/09_BossAi_Authoring_Guide` | ⚠️ | 旧 Boss 技能轨(BossSkillSO/SkillSequenceSO/WeakPointSystem)已于 2026-07-30 整体退役,Boss 归并到敌人能力轨。Design 19 仍是设计意图文档,实现见作者指南 |
|
||||
| 20 | AnimationEventSystem | **24_AnimEventModule** | ✅ | PlayerAnimationEvents/EnemyAnimationEvents/AnimationEventBinder 全部定义 |
|
||||
| 21 | SpellSystem | 09_ProgressionModule | ✅ | 完整 |
|
||||
| 22 | LocalizationSystem | 16_SupportingModules §1 | ✅ | 完整 |
|
||||
@@ -81,7 +81,7 @@
|
||||
| 44 | LevelDesignGuide | — | 📖 | 关卡设计规范,无需 Architecture |
|
||||
| 45 | TutorialSystem | **21_LiquidPuzzleModule** §Tutorial | ✅ | TutorialManager/ContextualHintTrigger 已定义 |
|
||||
| 46 | PlatformIntegration | 16_SupportingModules §3 | ✅ | IPlatformService/SteamPlatformService/NullPlatformService(ServiceLocator 模式)已定义 |
|
||||
| 47 | BossSkillSystem | **23_BossSkillModule** | ✅ | BossSkillSO/SkillSequenceSO/BossSkillExecutor/WeakPointSystem 全部定义 |
|
||||
| 47 | ~~BossSkillSystem~~ | — | ❌ | 已废止:Design 47 与 Architecture 23 于 2026-07-30 一并删除。Boss 与小怪统一走 `EnemyAbilitySO` + `EnemyAiBrain`,写法见 `Docs/Guides/09_BossAi_Authoring_Guide.md`,设计依据见 `Docs_Dev/superpowers/specs/2026-07-30-boss-ai-single-track-design.md` |
|
||||
| 48 | EnemyRoster | — | 📖 | 敌人名单(策划),无需 Architecture |
|
||||
| 49 | AntiSoftlockSystem | 16_SupportingModules §5 | ✅ | 完整 |
|
||||
| 50 | NarrativeDesignSystem | — | 📖 | 叙事结构设计,无需 Architecture |
|
||||
@@ -130,7 +130,7 @@
|
||||
| [20_ShieldModule.md](20_ShieldModule.md) | 30 | ShieldComponent、ShieldConfigSO、IShieldable、伤害管道修正 |
|
||||
| [21_LiquidPuzzleModule.md](21_LiquidPuzzleModule.md) | 40、35、36、45 | LiquidZone、SwimState、PuzzleSwitch/Receiver/Wire、WorldMarker、TutorialManager |
|
||||
| [22_QuestChallengeModule.md](22_QuestChallengeModule.md) | 38、39 | QuestSO、QuestManager、QuestGiver、ChallengeRoomSO、ChallengeRoomManager |
|
||||
| [23_BossSkillModule.md](23_BossSkillModule.md) | 47、19 | BossSkillSO、SkillSequenceSO、BossSkillExecutor、WeakPointSystem |
|
||||
| ~~23_BossSkillModule.md~~ | — | 已于 2026-07-30 删除(旧 Boss 技能轨退役)。Boss 实现并入 07_EnemyModule 的能力体系,作者指南见 `Docs/Guides/09_BossAi_Authoring_Guide.md` |
|
||||
| [24_AnimEventModule.md](24_AnimEventModule.md) | 20 | PlayerAnimationEvents、EnemyAnimationEvents、AnimationEventBinder |
|
||||
|
||||
---
|
||||
@@ -163,7 +163,7 @@
|
||||
| [16_SupportingModules.md](16_SupportingModules.md) | **§1.1** LanguageManagerSO(SO 单例,PlayerPrefs 持久化,SetLocale/GetCurrentLocaleCode/LoadSavedLocale 三方法);与静态 LocalizationManager 职责对比说明(文本查询 vs 语言切换+持久化) | ✅ 已应用 |
|
||||
| [12_SaveModule.md](12_SaveModule.md) | EquipmentSaveData 移除重复工具字段(ToolSlot0/ToolSlot1/OwnedToolIds/ToolStates)——这些字段仅属于 ToolsSaveData(顶层 SaveData.Tools);添加注释说明归属 | ✅ 已应用 |
|
||||
| [09_ProgressionModule.md](09_ProgressionModule.md) | ToolSlotManager.OnSave() 数据写入路径从 `data.Equipment.ToolSlotX` 修正为 `data.Tools.ToolSlotX`;OnLoad 注释同步为"从 data.Tools 恢复" | ✅ 已应用 |
|
||||
| [23_BossSkillModule.md](23_BossSkillModule.md) | BossSkillSO 补全 `attackPatterns: AttackPatternSO[]`、`counterResponses: PlayerCounterResponse[]`、`arenaEvents: ArenaEventTrigger[]`、`resourceCost: BossResourceCost`、`buildsRage: bool`、`poiseWindow: PoiseWindowConfig` 六个缺失字段;新增 §4.1 PlayerCounterResponse + CounterType 枚举、§4.2 ArenaEventTrigger/ArenaEventType/ArenaEventParams/ArenaEventData/IArenaInteractable、§4.3 BossResourceCost + BossResourceConfigSO 定义 | ✅ 已应用 |
|
||||
| `23_BossSkillModule.md`(该文档已于 2026-07-30 删除,本行仅存历史) | BossSkillSO 补全 `attackPatterns: AttackPatternSO[]`、`counterResponses: PlayerCounterResponse[]`、`arenaEvents: ArenaEventTrigger[]`、`resourceCost: BossResourceCost`、`buildsRage: bool`、`poiseWindow: PoiseWindowConfig` 六个缺失字段;新增 §4.1 PlayerCounterResponse + CounterType 枚举、§4.2 ArenaEventTrigger/ArenaEventType/ArenaEventParams/ArenaEventData/IArenaInteractable、§4.3 BossResourceCost + BossResourceConfigSO 定义 | ✅ 已应用 |
|
||||
| [16_SupportingModules.md](16_SupportingModules.md) | §2 AchievementManager 完全重写(对齐 Design/32 SO 策略模式):AchievementDef/AchievementDatabaseSO 替换为 AchievementSO + AchievementType/AchievementTier 枚举 + AchievementCondition 抽象基类(RegisterListeners/UnregisterListeners/IsMet)+ 内置 12 种条件类型表 + DefeatedBossCondition 示例 + AchievementManager(_allAchievements: AchievementSO[],中继 C# 事件,EvaluateAll/Unlock)+ AchievementRuntimeState | ✅ 已应用 |
|
||||
| [24_AnimEventModule.md](24_AnimEventModule.md) | `IAnimEventReceiver` 重命名为 `IAnimationEventHandler`;方法签名 `OnAnimationEvent(type, data)` 改为 `HandleEvent(type, payload)`;AnimationEventBinder.Bind() 参数类型、PlayerAnimationEvents/EnemyAnimationEvents 实现声明及方法体内 payload 用法全部同步 | ✅ 已应用 |
|
||||
| [16_SupportingModules.md](16_SupportingModules.md) | §5 AntiSoftlockSystem 后新增 §5.1 RoomEscapeInfoSO(设计时房间逃离 SO,含 EscapeRoute 嵌套类,对齐 Design/49 §3)+ §5.2 HardAbilityGate(AbilityGate 子类,_requirePhysicalValidation + _sequenceBreakRisk,对齐 Design/49 §4.2) | ✅ 已应用 |
|
||||
|
||||
@@ -140,12 +140,6 @@ public class ShopPurchaseEventChannelSO : BaseEventChannelSO<ShopPurchaseEvent>
|
||||
[CreateAssetMenu(menuName = "Events/DialogueRequest")]
|
||||
public class DialogueEventChannelSO : BaseEventChannelSO<DialogueDataSO> { }
|
||||
|
||||
// Assets/Scripts/Core/Events/BossSkillEventChannelSO.cs
|
||||
[System.Serializable]
|
||||
public struct BossSkillEvent { public string BossId; public string SkillId; }
|
||||
[CreateAssetMenu(menuName = "Events/BossSkill")]
|
||||
public class BossSkillEventChannelSO : BaseEventChannelSO<BossSkillEvent> { }
|
||||
|
||||
// Assets/Scripts/Core/Events/BossPhaseEventChannelSO.cs
|
||||
[System.Serializable]
|
||||
public struct BossPhaseEvent { public string BossId; public int Phase; }
|
||||
@@ -246,16 +240,12 @@ public class StatusEffectEventChannelSO : BaseEventChannelSO<StatusEffectType> {
|
||||
| `EVT_EnemyDied` | `TransformEventChannelSO` | `EnemyBase`(HP ≤ 0) | `PlayerStats`(击杀点)、`QuestManager` |
|
||||
| `EVT_HitConfirmed` | `HitConfirmedEventChannelSO`(HitInfo) | `HurtBox.ReceiveDamage` | `HitFXSpawner`、`AudioManager`、`PlayerFeedback`(受击方) |
|
||||
| `EVT_DamageDealt` | `DamageInfoEventChannelSO` | `HurtBox.ReceiveDamage` | `AnalyticsManager` |
|
||||
| `EVT_BossFightStarted` | `StringEventChannelSO`(bossId) | `BossOrchestrator` | `GameManager`(切换 BossFight 状态)、`AudioManager` |
|
||||
| `EVT_BossFightEnded` | `BoolEventChannelSO`(胜利/失败) | `BossBase.Die()` | `GameManager`、`AudioManager`、`UIManager` |
|
||||
| `EVT_BossFightToggled` | `BoolEventChannelSO`(true=开始,false=结束) | `BossOrchestrator`(开始)、`BossBase.Die()`(结束) | `BossHPBar`(显示/隐藏 Boss 血条) |
|
||||
| `EVT_BossFightStarted` | `StringEventChannelSO`(bossId) | `BossFightTrigger`(玩家进入竞技场触发区) | `GameManager`(切换 BossFight 状态)、`AudioManager` |
|
||||
| `EVT_BossFightEnded` | `BoolEventChannelSO`(true=开始 / false=结束) | `BossFightTrigger`(开始)、`BossBase.Die()`(结束) | `BossHPBar`(显示/隐藏血条)、`AudioManager`、`UIManager` |
|
||||
| `EVT_BossHPChanged` | `IntEventChannelSO` | `BossBase`(受击/回血) | `BossHPBar`(HP 进度条更新) |
|
||||
| `EVT_BossNameSet` | `StringEventChannelSO`(bossName) | `BossOrchestrator`(战斗开始时) | `BossHPBar`(显示 Boss 名称标签) |
|
||||
| `EVT_BossHPMaxSet` | `IntEventChannelSO` | `BossOrchestrator`(战斗开始时) | `BossHPBar`(初始化满血值) |
|
||||
| `EVT_BossNameSet` | `StringEventChannelSO`(bossName) | ⚠️ 暂无发送方(旧编排器已删除) | `BossHPBar`(显示 Boss 名称标签) |
|
||||
| `EVT_BossHPMaxSet` | `IntEventChannelSO` | ⚠️ 暂无发送方(旧编排器已删除) | `BossHPBar`(初始化满血值) |
|
||||
| `EVT_BossPhaseChanged` | `BossPhaseEventChannelSO`(bossId, phase) | `BossBase.EnterPhase()` | `BossHUD`(相机切换通过 `CameraStateController.Instance` 直接调用,不订阅事件)|
|
||||
| `EVT_BossSkillStarted` | `BossSkillEventChannelSO`(bossId, skillId) | `BossSkillExecutor` | `BossHUD`(显示技能名)(震动通过 `CameraStateController.Instance.TriggerImpulse()` 直接调用)|
|
||||
| `EVT_BossSkillEnded` | `BossSkillEventChannelSO`(bossId, skillId) | `BossSkillExecutor` | `BossOrchestrator`(BD 决策推进) |
|
||||
| `EVT_BossVulnerabilityWindowOpened` | `StringEventChannelSO`(bossId) | `WeakPointSystem` | `PlayerFeedback`(提示音效)、`HUDController` |
|
||||
| `EVT_NailClash` | `VoidEventChannelSO` | `ClashResolver`(玩家与敌人 HitBox 对碰) | `VFXSpawner`(拼刀特效)、`AudioManager`(拼刀音效)、`CameraStateController`(轻振动) |
|
||||
| `EVT_StatusEffectApplied` | `StatusEffectEventChannelSO` | `StatusEffectManager.ApplyEffect()` | `HUDController`(状态图标)、`PlayerFeedback`(特效) |
|
||||
| `EVT_StatusEffectExpired` | `StatusEffectEventChannelSO` | `StatusEffectManager.Tick()` | `HUDController`(移除状态图标) |
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
# 07 · 敌人模块
|
||||
|
||||
> **命名空间** `BaseGames.Enemies`、`BaseGames.Enemies.AI`、`BaseGames.Enemies.Navigation`、`BaseGames.Enemies.Boss.Patterns`
|
||||
> **命名空间** `BaseGames.Enemies`、`BaseGames.Enemies.Abilities`、`BaseGames.Enemies.Navigation`、`BaseGames.AI`
|
||||
> **程序集** 见各 asmdef
|
||||
> **路径** `Assets/Scripts/Enemies/`
|
||||
> **依赖** `BaseGames.Combat`、`Kybernetik.Animancer`、`BehaviorDesigner.Runtime`、`PathBerserker2d`
|
||||
> **路径** `Assets/_Game/Scripts/Enemies/`
|
||||
> **依赖** `BaseGames.Combat`、`Kybernetik.Animancer`
|
||||
|
||||
---
|
||||
|
||||
> ## ⚠️ 本文部分章节已过时(2026-07-30)
|
||||
>
|
||||
> 决策层与 Boss 轨已两度重构,以下章节描述的类型**在代码库中已不存在**,保留仅供追溯历史,
|
||||
> **不要照着它们去找类型或写新代码**:
|
||||
>
|
||||
> | 章节 | 状态 |
|
||||
> |---|---|
|
||||
> | §8 `Behavior Designer 任务类目录` | 第三方行为树插件已移除。决策层现为自研 `BrainGraph`(`AiScript` / `BrainBuilder` / `AiRuntime` / `EnemyAiBrain`) |
|
||||
> | §10 `BossOrchestrator` | 已删除。开战由 `BossFightTrigger` 发 `AiSignal.Engaged`,阶段由 `BossBase.EnterPhase` + `BossPhaseAbilityGate` 承担 |
|
||||
> | §11 `AttackPatternSO 与 TelegraphSystem` | 整节已删除的类型;预警统一改为动画时间轴上的事件 |
|
||||
> | §9 `BossBase` 的字段清单 | 已大幅瘦身:技能执行器、预警系统、弹反反制均已移除;新增 `IBossControl` 实现与阶段门引用 |
|
||||
>
|
||||
> **当前有效的写法**(这两份是权威):
|
||||
> - 小怪:[`Docs/Guides/08_EnemyAi_Authoring_Guide.md`](../Guides/08_EnemyAi_Authoring_Guide.md)
|
||||
> - Boss:[`Docs/Guides/09_BossAi_Authoring_Guide.md`](../Guides/09_BossAi_Authoring_Guide.md)
|
||||
> - 设计依据:`Docs_Dev/superpowers/specs/2026-07-30-boss-ai-single-track-design.md`
|
||||
>
|
||||
> 本文其余章节(`EnemyBase` / `EnemyStats` / `EnemyMovement` / 感知 / 掉落 / 池化等)仍然有效。
|
||||
|
||||
---
|
||||
|
||||
@@ -16,10 +37,10 @@
|
||||
5. [EnemyNavAgent](#5-enemynavagent)
|
||||
6. [EnemyStatsSO](#6-enemystatsso)
|
||||
7. [EnemyAnimationConfigSO](#7-enemyanimationconfigso)
|
||||
8. [Behavior Designer 任务类目录](#8-behavior-designer-任务类目录)
|
||||
9. [BossBase](#9-bossbase)
|
||||
10. [BossOrchestrator](#10-bossorchestrator)
|
||||
11. [AttackPatternSO 与 TelegraphSystem](#11-attackpatternso-与-telegraphsystem)
|
||||
8. ~~[决策层任务类目录](#8-behavior-designer-任务类目录)~~(已过时,见页首提示)
|
||||
9. [BossBase](#9-bossbase)(字段清单已过时)
|
||||
10. ~~[BossOrchestrator](#10-bossorchestrator)~~(已删除)
|
||||
11. ~~[AttackPatternSO 与 TelegraphSystem](#11-attackpatternso-与-telegraphsystem)~~(已删除)
|
||||
12. [DeathShade(死亡遗骸)](#12-deathshade)
|
||||
13. [Enemy Prefab 层级结构](#13-enemy-prefab-层级结构)
|
||||
14. [LootTableSO 与 LootResolver](#14-loottableso-与-lootresolver)
|
||||
@@ -551,147 +572,17 @@ public class BossOrchestrator : MonoBehaviour
|
||||
|
||||
---
|
||||
|
||||
## 11. AttackPatternSO 与 TelegraphSystem
|
||||
## 11. ~~AttackPatternSO 与 TelegraphSystem~~(已删除)
|
||||
|
||||
```csharp
|
||||
// 路径: Assets/Scripts/Enemies/Boss/Patterns/AttackPatternSO.cs
|
||||
[CreateAssetMenu(menuName = "Enemies/Boss/AttackPattern")]
|
||||
public class AttackPatternSO : ScriptableObject
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct AttackEntry
|
||||
{
|
||||
public string AttackId; // BD 任务通过此 ID 触发
|
||||
public float Weight; // 随机权重(模式随机选择)
|
||||
public float Cooldown;
|
||||
public float TelegraphDuration; // 0 = 无预警
|
||||
public string TelegraphVfxKey; // Addressable 键
|
||||
public DamageSourceSO DamageSource;
|
||||
}
|
||||
这两个类型连同整套旧 Boss 技能轨已于 2026-07-30 删除。当前等价物:
|
||||
|
||||
public AttackEntry[] Attacks;
|
||||
public float PhaseSpeedMultiplier = 1f; // 此阶段移速倍率
|
||||
}
|
||||
| 旧类型 | 现在由谁承担 |
|
||||
|---|---|
|
||||
| `AttackPatternSO`(攻击条目 + 权重 + 冷却 + 预警时长) | `EnemyAbilitySO`(id / 冷却 / 权重 / 优先级 / 触发范围 / 中断规则)+ `EnemyAttackSO`(clip + 归一化时机);选招由 `EnemyAttackSelector` 负责 |
|
||||
| `AttackPatternEditor`(命中帧可视化 Inspector) | 暂无替代。能力资产的编辑器总览(`EnemyAbilityModule`)是已记录的待办 |
|
||||
| `TelegraphSystem`(预警 VFX 协程) | 动画时间轴:预警是 clip 的一段,判定 / VFX / 音效 / 无敌帧全部挂动画事件(见 `EnemyAnimationEvents`) |
|
||||
|
||||
// 路径: Assets/Scripts/Enemies/Boss/Patterns/TelegraphSystem.cs
|
||||
// 攻击预警系统:在攻击前若干帧显示视觉提示
|
||||
public class TelegraphSystem : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private ObjectPoolManager _pool;
|
||||
|
||||
// 开始预警(BD_TelegraphAttack 调用)
|
||||
public IEnumerator ShowTelegraph(string vfxKey, float duration, Vector2 position);
|
||||
// 1. 从对象池取出预警 VFX
|
||||
// 2. 等待 duration 秒
|
||||
// 3. 归还 VFX(攻击开始)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 11.1 AttackPatternEditor(命中帧可视化 Inspector)
|
||||
|
||||
> **路径**:`Assets/Editor/Enemies/AttackPatternEditor.cs`
|
||||
> **目标用户**:Boss 战斗设计师(配置攻击权重、预警时长、伤害数值时,无需对照原始 Inspector 多层嵌套)
|
||||
|
||||
```csharp
|
||||
[CustomEditor(typeof(AttackPatternSO))]
|
||||
public class AttackPatternEditor : UnityEditor.Editor
|
||||
{
|
||||
// ── 折叠状态 ─────────────────────────────────────────────────────
|
||||
private bool[] _foldouts;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var so = (AttackPatternSO)target;
|
||||
var prop = serializedObject;
|
||||
prop.Update();
|
||||
|
||||
// ── 整体参数 ─────────────────────────────────────────────────
|
||||
EditorGUILayout.PropertyField(prop.FindProperty("PhaseSpeedMultiplier"));
|
||||
EditorGUILayout.Space(6);
|
||||
|
||||
// ── 攻击条目列表(可视化条形图 + 折叠面板) ─────────────────
|
||||
EditorGUILayout.LabelField("AttackEntries", EditorStyles.boldLabel);
|
||||
var attacks = so.Attacks;
|
||||
if (attacks == null || attacks.Length == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("尚无攻击条目。", MessageType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_foldouts == null || _foldouts.Length != attacks.Length)
|
||||
_foldouts = new bool[attacks.Length];
|
||||
|
||||
float totalWeight = 0f;
|
||||
foreach (var a in attacks) totalWeight += Mathf.Max(a.Weight, 0.001f);
|
||||
|
||||
for (int i = 0; i < attacks.Length; i++)
|
||||
{
|
||||
var entry = attacks[i];
|
||||
float ratio = entry.Weight / totalWeight;
|
||||
|
||||
// 折叠标题行:「[Bar████░░] AttackId 权重%」
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
var barRect = GUILayoutUtility.GetRect(0, 16, GUILayout.Width(80));
|
||||
EditorGUI.DrawRect(barRect, new Color(0.2f, 0.4f, 0.8f, 0.3f));
|
||||
EditorGUI.DrawRect(new Rect(barRect.x, barRect.y, barRect.width * ratio, barRect.height),
|
||||
new Color(0.2f, 0.6f, 1f, 0.8f));
|
||||
|
||||
_foldouts[i] = EditorGUILayout.Foldout(_foldouts[i],
|
||||
$" {entry.AttackId} ({ratio:P0})", true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (_foldouts[i])
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
var arrayProp = prop.FindProperty("Attacks").GetArrayElementAtIndex(i);
|
||||
EditorGUILayout.PropertyField(arrayProp.FindPropertyRelative("AttackId"));
|
||||
EditorGUILayout.PropertyField(arrayProp.FindPropertyRelative("Weight"));
|
||||
EditorGUILayout.PropertyField(arrayProp.FindPropertyRelative("Cooldown"));
|
||||
|
||||
// 预警时长:0 = 无预警(灰色提示)
|
||||
float tele = entry.TelegraphDuration;
|
||||
EditorGUILayout.PropertyField(arrayProp.FindPropertyRelative("TelegraphDuration"));
|
||||
if (tele <= 0f)
|
||||
EditorGUILayout.HelpBox("TelegraphDuration = 0:此攻击无预警(即时)", MessageType.None);
|
||||
|
||||
EditorGUILayout.PropertyField(arrayProp.FindPropertyRelative("TelegraphVfxKey"));
|
||||
EditorGUILayout.PropertyField(arrayProp.FindPropertyRelative("DamageSource"));
|
||||
|
||||
// 快速展示 DamageSource 摘要(避免策划必须展开嵌套 SO)
|
||||
if (entry.DamageSource != null)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.LabelField(
|
||||
$"伤害预览: {entry.DamageSource.BaseDamage} × {entry.DamageSource.DamageMultiplier:F1} " +
|
||||
$"= {Mathf.RoundToInt(entry.DamageSource.BaseDamage * entry.DamageSource.DamageMultiplier)} [{entry.DamageSource.Type}]",
|
||||
EditorStyles.miniLabel);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// 一键 Ping 关联 SO
|
||||
if (entry.DamageSource != null && GUILayout.Button("Ping DamageSourceSO", GUILayout.Height(18)))
|
||||
EditorGUIUtility.PingObject(entry.DamageSource);
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**提供能力一览**:
|
||||
|
||||
| 功能 | 收益 |
|
||||
|------|------|
|
||||
| 随机权重百分比 + 条形图 | 策划直观感受攻击频率分布 |
|
||||
| TelegraphDuration=0 警告 | 防止无意做成即时攻击 |
|
||||
| DamageSource 内联摘要 | 查看伤害值无需展开嵌套 SO |
|
||||
| Ping 关联 SO 按钮 | 快速定位引用资产 |
|
||||
配招写法见 [`Docs/Guides/09_BossAi_Authoring_Guide.md`](../Guides/09_BossAi_Authoring_Guide.md) §4。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# 25 · 角色系统架构全景图
|
||||
|
||||
> **命名空间** `BaseGames.Player`、`BaseGames.Player.States`、`BaseGames.Enemies`、`BaseGames.Enemies.AI`、`BaseGames.Boss`、`BaseGames.Combat`
|
||||
> **命名空间** `BaseGames.Player`、`BaseGames.Player.States`、`BaseGames.Enemies`、`BaseGames.Enemies.Abilities`、`BaseGames.AI`、`BaseGames.Combat`
|
||||
> **路径** `Assets/_Game/Scripts/Player/`、`Assets/_Game/Scripts/Enemies/`、`Assets/_Game/Scripts/Combat/`
|
||||
> **关联文档** [05_PlayerModule](05_PlayerModule.md) · [06_CombatModule](06_CombatModule.md) · [07_EnemyModule](07_EnemyModule.md) · [09_ProgressionModule](09_ProgressionModule.md) · [23_BossSkillModule](23_BossSkillModule.md)
|
||||
> **建立日期** 2026-05-17
|
||||
> **关联文档** [05_PlayerModule](05_PlayerModule.md) · [06_CombatModule](06_CombatModule.md) · [07_EnemyModule](07_EnemyModule.md) · [09_ProgressionModule](09_ProgressionModule.md) · [`Docs/Guides/08_EnemyAi_Authoring_Guide`](../Guides/08_EnemyAi_Authoring_Guide.md) · [`Docs/Guides/09_BossAi_Authoring_Guide`](../Guides/09_BossAi_Authoring_Guide.md)
|
||||
> **建立日期** 2026-05-17 **§4 Boss 章节重写** 2026-07-30(Boss 与小怪单轨统一)
|
||||
>
|
||||
> ⚠️ §3.3「AI — Behavior Designer 节点库」仍描述已移除的第三方行为树插件,尚未重写;
|
||||
> 当前决策层是自研 `BrainGraph`,写法以上方两份作者指南为准。
|
||||
|
||||
本文档是跨模块的**角色系统实现全景图**,侧重三类角色(玩家 / 小怪 / Boss)在 Scene 中的节点结构、脚本职责划分、子系统数据流与相互协作关系。各模块深度细节请参阅上方关联文档。
|
||||
|
||||
@@ -28,7 +31,7 @@
|
||||
4. [Boss](#4-boss)
|
||||
- 4.1 [继承关系](#41-继承关系)
|
||||
- 4.2 [Scene 节点结构](#42-scene-节点结构)
|
||||
- 4.3 [技能执行流 BossSkillSO + BossSkillExecutor](#43-技能执行流-bossskillso--bossskillexecutor)
|
||||
- 4.3 [一招的数据流](#43-一招的数据流)
|
||||
- 4.4 [阶段切换](#44-阶段切换)
|
||||
5. [共享战斗层 Combat Module](#5-共享战斗层-combat-module)
|
||||
- 5.1 [核心接口](#51-核心接口)
|
||||
@@ -444,100 +447,110 @@ EnemyBase.TakeDamage(DamageInfo)
|
||||
```
|
||||
MonoBehaviour
|
||||
└── EnemyBase(IDamageable / ILOSRequester)
|
||||
└── BossBase
|
||||
├── 多阶段切换:EnterPhase(int) + BossPhaseEventChannelSO 广播
|
||||
├── IsHPBelow(float ratio) → BD_IsHPBelow 轮询条件
|
||||
└── override Die() → _onBossFightEnded.Raise(true)
|
||||
└── BossBase(+ BaseGames.AI.IBossControl)
|
||||
├── 阶段:CurrentPhase / EnterPhase(int) + BossPhaseEventChannelSO 广播
|
||||
├── 阶段过渡:BeginPhaseTransition(targetPhase, invincibleDuration)
|
||||
│ → IsPhaseTransitioning(期间 IsInvincible 为真)→ EnterPhase
|
||||
├── IsHPBelow(float ratio):供 AI 图的条件边读取
|
||||
├── 竞技场锚点:AnchorAt(i) / DistanceToAnchor(i)(转发 BossArenaAnchors)
|
||||
└── override Die() → 中止阶段过渡 + _onBossFightEnded.Raise(true)
|
||||
└── [具体 Boss 类]
|
||||
override EnterPhase → 额外过渡逻辑(动画/无敌帧/BD 子树切换)
|
||||
override EnterPhase / OnBeginPhaseTransition → 额外过渡演出
|
||||
```
|
||||
|
||||
**Boss 没有独立的技能体系。** 招式即敌人能力(`EnemyAbilitySO` + `EnemyAbilityBase`),
|
||||
选招即 `EnemyAttackSelector`,决策即 `EnemyAiBrain` 上的 `AiScript` 图。
|
||||
Boss 专属的只有 `IBossControl` 这一个决策面加几个旁挂 MonoBehaviour。
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Scene 节点结构
|
||||
|
||||
```
|
||||
[Boss_XxxGuardian]
|
||||
│ BossBase(具体 Boss 脚本,继承 BossBase)
|
||||
│ ├── EnemyStats / EnemyMovement / EnemyCombat / EnemyFeedback
|
||||
│ ├── BossSkillExecutor 接收 BD/Orchestrator 指令,执行 BossSkillSO 协程
|
||||
│ ├── WeakPointSystem 弱点激活窗口管理(BossSkillExecutor 技能后开启)
|
||||
│ ├── TelegraphSystem 攻击预兆提示(激光标线 / 范围高亮 / 地面警示)
|
||||
│ ├── BehaviorTree 含 BD_EnterPhase 的行为树资产
|
||||
[ENM_XxxBoss]
|
||||
│ 具体 Boss 脚本(继承 BossBase,实现 IBossControl)
|
||||
│ ├── EnemyStats / EnemyMovement / EnemyLocomotion / EnemyFeedback
|
||||
│ ├── GroundNavigator(或 FlyingNavigator)
|
||||
│ ├── PhysicsPerceptionSystem 感知(追逐区 / 视野 / 攻击范围)
|
||||
│ ├── EnemyAiBrain 决策层(_definitionId 指向 [AiDefinition] 的 AiScript)
|
||||
│ ├── BossPhaseAbilityGate 阶段 = 换招池:按阶段启停能力组件
|
||||
│ ├── BossArenaAnchors(可选) 竞技场定点走位的锚点集合
|
||||
│ ├── EnemyAbilityBase × N 每招一个组件,各自引用一份 EnemyAbilitySO
|
||||
│ ├── BossResource(可选) 怒气 / 充能;是否已满经 IBossControl.ResourceFull 读取
|
||||
│ └── AnimancerComponent
|
||||
│
|
||||
├── HurtBox 主体受击盒(Layer=EnemyHurtBox)
|
||||
│ └── 弱点受击盒同样是 HurtBox,靠 _damageMultiplier 表达倍率,无独立弱点系统
|
||||
│
|
||||
├── WeakPoint_Head 弱点受击盒
|
||||
│ └── HurtBox(弱点专属,WeakPointSystem 控制激活/关闭)
|
||||
├── ContactDamageZone 身体接触伤害(常驻,Layer=EnemyHitBox)
|
||||
├── HitBox_XXX × N 各近战招的判定盒(默认禁用,由动画事件按时机开关)
|
||||
├── XxxMuzzle × N 弹体发射点
|
||||
│
|
||||
├── HitBox_Slam 近战攻击 HitBox(Layer=EnemyHitBox)
|
||||
├── HitBox_Sweep 横扫 HitBox(可与 BossSkillSO 绑定)
|
||||
│
|
||||
└── BossArenaBlocker(可选) 竞技场封锁触发器(Boss 战开始时封门)
|
||||
└── [场景侧] BossFightTrigger 房间入口触发区:发开战事件 + AiSignal.Engaged
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.3 技能执行流 BossSkillSO + BossSkillExecutor
|
||||
### 4.3 一招的数据流
|
||||
|
||||
```
|
||||
BossSkillSO(CreateAssetMenu: BaseGames/Boss/BossSkill)
|
||||
├── skillId / displayName
|
||||
├── BossSkillType(枚举)
|
||||
├── AttackPatternSO
|
||||
│ ├── DamageSource(DamageSourceSO)
|
||||
│ ├── KnockbackAngle
|
||||
│ ├── 弹幕参数:ProjectilePrefab / Count / SpreadAngle / Speed
|
||||
│ ├── AoE 参数:Radius / Offset
|
||||
│ └── 时序:WindupDuration / ActiveDuration / RecoveryDuration
|
||||
├── VulnerabilityWindowDuration 技能结束后弱点暴露时长(秒)
|
||||
└── SkillSequenceSO(可选) 组合技序列(按顺序或随机排列多个 BossSkillSO)
|
||||
EnemyAbilitySO(CreateAssetMenu: BaseGames/Enemies/Enemy Ability,前缀 ABL_)
|
||||
├── abilityId / designNote
|
||||
├── attackSequence: EnemyAttackSO[] 一招内的多段
|
||||
├── cooldown 从执行结束起计
|
||||
├── interruptOnHurt / interruptOnStagger 中断规则
|
||||
├── category / weight / priority 选招器用
|
||||
├── rangeRadius / rangeOffset 招式自管的圆形触发范围
|
||||
└── requiresGrounded / requiresLineOfSight 选招硬门
|
||||
|
||||
BossSkillExecutor.ExecuteSkill(BossSkillSO)
|
||||
│ if _isExecuting → return
|
||||
│
|
||||
└── StartCoroutine(ExecuteSkillCoroutine)
|
||||
├── _onBossSkillStarted.Raise(BossSkillEvent)
|
||||
├── TelegraphSystem.ShowTelegraph(skill.pattern) 预兆提示激活
|
||||
├── WaitForSeconds(WindupDuration) 前摇等待
|
||||
├── 激活 HitBox[] / ProjectileManager.Spawn(pattern) 伤害输出
|
||||
├── WaitForSeconds(ActiveDuration) 活跃帧等待
|
||||
├── 关闭 HitBox / 清理弹幕
|
||||
├── WeakPointSystem.OpenWindow(VulnerabilityWindowDuration) 弱点窗口
|
||||
├── WaitForSeconds(RecoveryDuration) 后摇等待
|
||||
└── _onBossSkillEnded.Raise(BossSkillEvent)
|
||||
EnemyAttackSO(前缀 EATK_)—— 一段动作的时间轴
|
||||
├── clip: ClipTransition(Animancer)
|
||||
├── hitBoxSlot / hitBoxEnterT / hitBoxExitT 判定开关的归一化时机
|
||||
├── damageSource: DamageSourceSO
|
||||
├── projectileConfig / projectileCount / projectileFireT
|
||||
└── hasPoiseWindow / poiseLevel / poiseStartT / poiseEndT
|
||||
|
||||
WaitForSeconds 缓存:
|
||||
static Dictionary<float, WaitForSeconds> _wfsCache
|
||||
[RuntimeInitializeOnLoadMethod] ClearWFSCache()
|
||||
→ 避免协程每次 new WaitForSeconds 的 GC 分配
|
||||
执行链:
|
||||
AI 图的攻击态 OnEnter
|
||||
└── IAiContext.Combat.UseBestAttack()
|
||||
└── EnemyAttackSelector 从 category==Attack 且 CanUse 的能力里选一个
|
||||
(CanUse 含 enabled、冷却、射程、grounded / LOS 硬门;
|
||||
WeightedRandomAntiRepeat 模式对上次选中的招施加权重折扣)
|
||||
└── EnemyAbilityBase.Execute():逐段播 clip,
|
||||
判定 / 生成 / 音效 / 无敌帧全部由 clip 上的动画事件驱动
|
||||
(EnemyAnimationEvents.HandleEvent)
|
||||
```
|
||||
|
||||
**InterruptCurrentSkill()**:阶段切换时强制停止当前协程并调用 `FinishExecution()`,确保状态一致性。
|
||||
|
||||
---
|
||||
|
||||
### 4.4 阶段切换
|
||||
|
||||
```
|
||||
BD_IsHPBelow(每帧轮询)
|
||||
└── BossBase.IsHPBelow(ratio) = CurrentHP / MaxHP < ratio
|
||||
→ true 时 BD 子树激活 BD_EnterPhase
|
||||
AI 图的条件边(如 x.Vitals.HpBelow(0.5f))
|
||||
└── 转入阶段过渡态(BossFragments.PhaseTransition)
|
||||
OnEnter:Locomotion.Stop() + Combat.InterruptAbilities()
|
||||
+ IBossControl.BeginPhaseTransition(targetPhase, invincibleDuration)
|
||||
|
||||
BD_EnterPhase → BossBase.EnterPhase(phase)
|
||||
├── _currentPhase = phase
|
||||
├── BossPhaseEventChannelSO _onBossPhaseChanged.Raise(BossPhaseEvent{BossId, Phase})
|
||||
│ → Boss HP 条分段动画(UI)
|
||||
│ → 音乐系统切换 BGM 段落
|
||||
│ → VFX 场景效果触发
|
||||
└── [子类重写 EnterPhase]
|
||||
├── BossSkillExecutor.InterruptCurrentSkill() 打断当前技能
|
||||
├── 切换 BD 行为树活跃子树(换招式库)
|
||||
├── 播放阶段过渡动画(Animancer)
|
||||
└── 短暂无敌帧(保护阶段切换不被秒杀)
|
||||
BossBase.BeginPhaseTransition
|
||||
├── IsPhaseTransitioning = true → IsInvincible 随之为真
|
||||
├── OnBeginPhaseTransition(targetPhase) [子类重写:浮空 / 过渡动画]
|
||||
├── 等待 invincibleDuration
|
||||
├── EnterPhase(targetPhase)
|
||||
│ ├── _currentPhase = phase
|
||||
│ ├── BossPhaseAbilityGate.ApplyPhase(phase)
|
||||
│ │ → 按阶段表设置各能力组件的 enabled
|
||||
│ │ → 被禁用的能力 CanUse 为 false,自动从选招器候选消失
|
||||
│ └── _onBossPhaseChanged.Raise(BossPhaseEvent{BossId, Phase})
|
||||
│ → Boss HP 条分段动画 / BGM 段落切换 / 场景 VFX
|
||||
└── IsPhaseTransitioning = false
|
||||
→ AI 图上 .To(下一态).When(x => !x.Boss.IsPhaseTransitioning) 放行
|
||||
```
|
||||
|
||||
**阶段不是 SO 上的字段,也不是选招器里的过滤条件——阶段就是"哪些能力组件当前启用"。**
|
||||
`BossBase.OnSpawn` 会 `ApplyPhase(0)`,保证对象池复用时回到初始招池。
|
||||
|
||||
作者写法详见 [`Docs/Guides/09_BossAi_Authoring_Guide.md`](../Guides/09_BossAi_Authoring_Guide.md)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 共享战斗层 Combat Module
|
||||
@@ -613,10 +626,10 @@ StatusEffectEventChannelSO 广播效果开始/结束(UI 状态图标)
|
||||
| `ProjectileConfigSO` | `BaseGames.Combat` | 投射物速度/碰撞层/生命时长/弹幕参数 |
|
||||
| `EnemyStatsSO` | `BaseGames.Enemies` | 敌人 HP/Defense/速度/攻击冷却 |
|
||||
| `EnemyAnimationConfigSO` | `BaseGames.Enemies` | 敌人动画 Clip 集合 |
|
||||
| `AttackPatternSO` | `BaseGames.Enemies`(Boss) | 攻击图案:伤害/弹幕/AoE/时序 |
|
||||
| `BossSkillSO` | `BaseGames.Enemies`(Boss) | Boss 技能全量配置 |
|
||||
| `SkillSequenceSO` | `BaseGames.Enemies`(Boss) | Boss 组合技序列(有序/随机) |
|
||||
| `BossResourceConfigSO` | `BaseGames.Enemies`(Boss) | Boss 阶段资源(HP 阈值/技能池) |
|
||||
| `EnemyAbilitySO` | `BaseGames.Enemies.Abilities` | 一招的全量配置(id/冷却/权重/射程/中断规则);小怪与 Boss 共用 |
|
||||
| `EnemyAttackSO` | `BaseGames.Enemies.Abilities` | 一段动作的时间轴(clip + 判定/弹体/霸体的归一化时机) |
|
||||
| `AiRecipeSO` | `BaseGames.Enemies` | 小怪 AI 配方(未发现层 + 交战层两个可插拔模块)。Boss 不用配方,走 `[AiDefinition]` 定制图 |
|
||||
| `BossResourceConfigSO` | `BaseGames.Enemies`(Boss) | Boss 资源(怒气/充能)配置 |
|
||||
|
||||
**设计原则**:所有运行时组件在 `Awake` 中通过 `Initialize(SO)` 接收配置,与数据资产完全解耦,支持 Inspector 热替换和难度 A/B 测试,无需修改脚本代码。
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
| [20](./20_ShieldModule.md) | 护盾模块 | ShieldComponent、ShieldConfigSO、IShieldable、护盾破碎/恢复管道 | 05、13 |
|
||||
| [21](./21_LiquidPuzzleModule.md) | 液体谜题模块 | LiquidZone、LiquidPhysicsConfigSO、SwimState、PuzzleSwitch/PuzzleReceiver、WorldMarker | 08、41 |
|
||||
| [22](./22_QuestChallengeModule.md) | 任务与挑战模块 | QuestManager、QuestSO、QuestObjectiveSO、ChallengeRoom、QuestEventChannelSO | 37、38、39 |
|
||||
| [23](./23_BossSkillModule.md) | Boss 技能模块 | BossSkillSO、BossSkillExecutor、SkillSequenceSO、VulnerabilityWindow、WeakPointSystem | 19、47、48 |
|
||||
| ~~23~~ | ~~Boss 技能模块~~ | **已于 2026-07-30 删除。** 旧 Boss 技能轨(`BossSkillSO` / `BossSkillExecutor` / `SkillSequenceSO` / `WeakPointSystem`)整体退役,Boss 与小怪统一走 `EnemyAbilitySO` + `EnemyAiBrain`。实现见 07;写法见 [`Docs/Guides/09_BossAi_Authoring_Guide.md`](../Guides/09_BossAi_Authoring_Guide.md) | 07 |
|
||||
| [24](./24_AnimEventModule.md) | 动画事件模块 | PlayerAnimationEvents、EnemyAnimationEvents、AnimEventBridge、Animancer 事件回调 | 03 |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user