559 lines
29 KiB
Markdown
559 lines
29 KiB
Markdown
# 09 · 编辑器扩展
|
||
|
||
> **命名空间** `BaseGames.Editor`
|
||
> **所属文档集** [← 返回索引](./README.md) · [总览](./00_Overview.md)
|
||
> **程序集** `BaseGames.Editor.asmdef`(Editor-only,不打包进 Runtime)
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [设计原则](#1-设计原则)
|
||
2. [自定义 Inspector 列表](#2-自定义-inspector-列表)
|
||
3. [EditorWindow 工具列表](#3-editorwindow-工具列表)
|
||
4. [Scene 视图 Gizmos 汇总](#4-scene-视图-gizmos-汇总)
|
||
5. [Play Mode 调试叠加层](#5-play-mode-调试叠加层)
|
||
6. [ContextMenu 工具](#6-contextmenu-工具)
|
||
7. [编辑器菜单结构](#7-编辑器菜单结构)
|
||
8. [自动化检查工具](#8-自动化检查工具)
|
||
9. [高级工具集(补充)](#9-高级工具集补充)
|
||
|
||
---
|
||
|
||
## 1. 设计原则
|
||
|
||
- **编辑器扩展与运行时代码完全分离**:所有编辑器扩展代码置于 `Editor/` 文件夹,使用独立 `.asmdef`
|
||
- **工具服务于制作流程**:每个工具针对具体的制作痛点,不做泛用性过度设计
|
||
- **视觉化优先**:Gizmos 和自定义 Inspector 的目标是"**看一眼就知道配置是否正确**"
|
||
- **不破坏运行时行为**:所有 Inspector 修改通过 `SerializedObject.ApplyModifiedProperties()` 标准流程,支持撤销(Undo)
|
||
- **UI 技术选型**:所有编辑器扩展统一使用 **Unity UI Toolkit(UIElements)**,不使用 IMGUI(`OnGUI` / `EditorGUILayout`)
|
||
|
||
### UI Toolkit 统一规范
|
||
|
||
**自定义 Inspector** — 使用 `CreateInspectorGUI()` + `BindProperty()`:
|
||
|
||
```csharp
|
||
[CustomEditor(typeof(PlayerController))]
|
||
public class PlayerControllerEditor : Editor
|
||
{
|
||
public override VisualElement CreateInspectorGUI()
|
||
{
|
||
var root = new VisualElement();
|
||
|
||
// 默认字段绑定(替代 DrawDefaultInspector)
|
||
InspectorElement.FillDefaultInspector(root, serializedObject, this);
|
||
|
||
// 自定义运行时状态区
|
||
var statusFoldout = new Foldout { text = "运行时状态(Play Mode)" };
|
||
var stateLabel = new Label();
|
||
stateLabel.schedule.Execute(() =>
|
||
{
|
||
if (!EditorApplication.isPlaying) return;
|
||
var t = target as PlayerController;
|
||
stateLabel.text = $"State: {t.CurrentStateName} HP: {t.HP}/{t.MaxHP}";
|
||
}).Every(100); // 100ms 轮询
|
||
statusFoldout.Add(stateLabel);
|
||
|
||
// 调试按钮(Play Mode only)
|
||
var debugGroup = new VisualElement();
|
||
debugGroup.SetEnabled(false);
|
||
EditorApplication.playModeStateChanged += state =>
|
||
debugGroup.SetEnabled(state == PlayModeStateChange.EnteredPlayMode);
|
||
var hurtBtn = new Button(() => (target as PlayerController)?.TakeDamage(2)) { text = "Hurt 2" };
|
||
debugGroup.Add(hurtBtn);
|
||
|
||
root.Add(statusFoldout);
|
||
root.Add(debugGroup);
|
||
return root;
|
||
}
|
||
}
|
||
```
|
||
|
||
**EditorWindow** — 使用 `CreateGUI()` + 内置控件:
|
||
|
||
```csharp
|
||
public class MyTool : EditorWindow
|
||
{
|
||
[MenuItem("BaseGames/My Tool")]
|
||
public static void Open() => GetWindow<MyTool>("My Tool");
|
||
|
||
public void CreateGUI()
|
||
{
|
||
var splitView = new TwoPaneSplitView(0, 260f, TwoPaneSplitViewOrientation.Horizontal);
|
||
var left = new ScrollView();
|
||
var right = new VisualElement();
|
||
splitView.Add(left);
|
||
splitView.Add(right);
|
||
rootVisualElement.Add(splitView);
|
||
}
|
||
}
|
||
```
|
||
|
||
**§2–§9 各工具使用的关键 UI Toolkit 控件**:
|
||
|
||
| 工具 | 关键控件 | 说明 |
|
||
|------|---------|------|
|
||
| §2.x 自定义 Inspector | `ProgressBar`、`Foldout`、`Button`、`Label` | `CreateInspectorGUI()` 替代 `OnInspectorGUI()` |
|
||
| §2.3 ParrySystem(时间轴)| 自绘 `VisualElement`(`generateVisualContent` + `Painter2D`)| 替代 `GUI.Box` 手绘条 |
|
||
| §3.1–3.4 简单 EditorWindow | `ListView`、`Button`、`TextField` | `CreateGUI()` 替代 `OnGUI()` |
|
||
| §9.1 BT 验证器 | `TreeView` | 原生树形控件 |
|
||
| §9.2 进程流程图 | `GraphView`(`UnityEditor.Experimental.GraphView`)| 节点图;见注意事项 |
|
||
| §9.3 GameState 分析器 | `MultiColumnListView` | 矩阵视图 |
|
||
| §9.4 伤害模拟器 | `TwoPaneSplitView` + 自绘直方图(`Painter2D`)| 参数面板 + 分布图 |
|
||
| §9.7 装备预览 | `TwoPaneSplitView` + `DropdownField` | 响应式分栏 |
|
||
| §9.8 构建验证器 | `MultiColumnListView` + 可点击 `Label` | 多列结果 + 跳转 |
|
||
|
||
> **GraphView 注意**:`UnityEditor.Experimental.GraphView` 标注为 Experimental,API 可能在 Unity 版本间变动。如遇稳定性问题,9.2 进程流程图可改为 `VisualElement` 手绘节点(`generateVisualContent` + `Painter2D.DrawBezierCurve`),无需依赖 Experimental API。
|
||
|
||
**USS 样式文件存放**:`Assets/Editor/UI/USS/` — 统一样式变量(颜色、间距、字体大小),通过 `styleSheets.Add()` 挂载。
|
||
|
||
---
|
||
|
||
## 2. 自定义 Inspector 列表
|
||
|
||
### 2.1 PlayerController Inspector
|
||
|
||
**目标**:Play Mode 下直观监控玩家状态,快速触发测试。
|
||
|
||
**布局规划**:
|
||
|
||
```
|
||
┌─ PlayerController ─────────────────────────────────┐
|
||
│ ◈ 状态信息 │
|
||
│ ┌──────────────────────────────────────────────┐ │
|
||
│ │ Current State RunState │ │
|
||
│ │ HP ████████████░░ 8 / 10 │ │
|
||
│ │ Soul ███████░░░░░░░ 66 / 99 │ │
|
||
│ │ Geo 340 │ │
|
||
│ │ IsGrounded ✓ FacingDir → (+1) │ │
|
||
│ │ Invincible ░░░░░░░░░░ (0.00s remaining) │ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
│ ◈ 已解锁能力 │
|
||
│ ┌──────────────────────────────────────────────┐ │
|
||
│ │ [✓ Parry] [✓ DoubleJump] [✗ WallJump] │ │
|
||
│ │ [✗ AerialDash] [✗ Swim] │ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
│ ◈ 调试工具(Play Mode Only) │
|
||
│ [Force Idle] [Force Run] [Force Air] │
|
||
│ [Deal Damage: 2] [Deal Damage: 10] [Instant Kill] │
|
||
│ [Add Soul: 33] [Add Geo: 100] │
|
||
│ [Unlock All Abilities] [Lock All Abilities] │
|
||
└────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**实现方式**:继承 `Editor`,重写 `CreateInspectorGUI()` 返回 `VisualElement` 树。进度条使用 UI Toolkit `ProgressBar` 控件;Play Mode 限定区域通过 `debugGroup.SetEnabled(EditorApplication.isPlaying)` + `EditorApplication.playModeStateChanged` 回调控制显隐。
|
||
|
||
---
|
||
|
||
### 2.2 EnemyBase Inspector
|
||
|
||
**目标**:快速查看敌人 AI 状态,测试战斗参数。
|
||
|
||
```
|
||
┌─ EnemyBase ──────────────────────────────────────┐
|
||
│ ◈ 运行时状态(Play Mode) │
|
||
│ State: Controlled HP: █████████░ 90/100 │
|
||
│ BD Node: BD_MoveToPlayer (Running) │
|
||
│ Nav Status: Moving → (12.5, -3.0) [0.8m left] │
|
||
│ ◈ 属性配置 │
|
||
│ Stats SO: [ES_GruntWarrior ▼] │
|
||
│ AnimCfg : [EA_GruntWarrior ▼] │
|
||
│ ◈ 调试工具(Play Mode Only) │
|
||
│ [Force Stagger] [Force Death] [Reset HP] │
|
||
│ [Disable BD] [Enable BD] [Reload BD Tree] │
|
||
└──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 2.3 ParrySystem Inspector
|
||
|
||
**目标**:可视化弹反时间轴,测试弹反参数。
|
||
|
||
```
|
||
┌─ ParrySystem ────────────────────────────────────┐
|
||
│ ◈ 时间轴预览 │
|
||
│ [▌ Startup ▌▌▌▌▌▌▌ Active Window ▌▌ Endlag ▌] │
|
||
│ 0.05s 0.28s 0.10s │
|
||
│ ◈ 运行时状态(Play Mode) │
|
||
│ State: Active Timer: 0.19s / 0.28s │
|
||
│ Window: ████████████░░░ 68% │
|
||
│ CounterW: ────────────── (Inactive) │
|
||
│ ◈ 调试工具 │
|
||
│ [Trigger Parry Success] [Trigger Parry Fail] │
|
||
│ [Open Counter Window] [Reset] │
|
||
└──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**时间轴预览** 在 Edit Mode 下也可显示(根据 `ParryConfigSO` 参数计算比例),方便策划调整数值时直观预览窗口比例。
|
||
|
||
---
|
||
|
||
### 2.4 RoomCameraBounds Inspector
|
||
|
||
**目标**:防止镜头边界配置错误。
|
||
|
||
```
|
||
┌─ RoomCameraBounds ───────────────────────────────┐
|
||
│ ◈ 边界检查 │
|
||
│ Bounds Size: (32.0, 18.0) │
|
||
│ Camera View (4.22 OrthoSize): (29.9, 16.8) │
|
||
│ Status: ✓ 边界大于镜头视野 │
|
||
│ ─────────────────────────────────────────────── │
|
||
│ [Preview Camera View in Scene] │
|
||
│ [自动调整 PolygonCollider2D 至最小安全尺寸] │
|
||
└──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 2.5 DamageSourceSO Inspector
|
||
|
||
**目标**:策划配置攻击参数时,即时预览伤害计算和属性。
|
||
|
||
```
|
||
┌─ DamageSourceSO ─────────────────────────────────┐
|
||
│ ◈ 伤害预览 │
|
||
│ BaseDamage × Multiplier = Final │
|
||
│ 5 × 1.0 = 5 │
|
||
│ ◈ 击退预览 │
|
||
│ KnockbackForce: 8.0 Direction: → │
|
||
│ HitStun: 0.30s │
|
||
│ ◈ 属性标记 │
|
||
│ [CanBeParried ✓] [Unblockable ✗] [IgnoreIFrame ✗]│
|
||
│ ◈ 伤害类型 │
|
||
│ Type: Normal (物理) │
|
||
│ HitFxType: Slash │
|
||
└──────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 3. EditorWindow 工具列表
|
||
|
||
### 3.1 房间连接验证工具
|
||
|
||
**菜单路径**:`BaseGames > World > Room Connection Validator`
|
||
|
||
**功能**:
|
||
|
||
```
|
||
┌─ Room Connection Validator ──────────────────────────────────────┐
|
||
│ 扫描所有 Room_*.unity 场景中的 RoomTransition 组件 │
|
||
│ │
|
||
│ 房间 出口ID 目标场景 │
|
||
│ ────────────────────────────────────────────────────────────── │
|
||
│ Room_Forest_01 Door_To_Forest_02 ✓ Room_Forest_02 存在 │
|
||
│ Room_Forest_02 Door_To_Cave_01 ✓ Room_Cave_01 存在 │
|
||
│ Room_Cave_01 Door_To_Boss ✗ Boss_Cave 不存在 ⚠ │
|
||
│ │
|
||
│ SpawnPoint 检查: │
|
||
│ Room_Forest_02 缺少 SpawnPoint "SP_From_Forest_01_Door" ⚠ │
|
||
│ │
|
||
│ [重新扫描] [选中有错误的场景] [导出验证报告.md] │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 3.2 SO 事件频道监视器
|
||
|
||
**菜单路径**:`BaseGames > Core > Event Channel Monitor`
|
||
|
||
**功能**:Play Mode 下实时监听所有 SO 事件频道的触发情况。
|
||
|
||
```
|
||
┌─ Event Channel Monitor ──────────────────────────────────────────┐
|
||
│ [▶ Play Mode Only] [清除日志] [暂停记录] │
|
||
│ │
|
||
│ 时间 事件频道 数据 │
|
||
│ ────────────────────────────────────────────────────────────── │
|
||
│ 0.012s OnPlayerHPChanged value: 8 │
|
||
│ 0.013s OnHitConfirmed DMG:5, Knockback:8.0 │
|
||
│ 1.245s OnParrySuccess DMG:5, Flags: CanBeParried │
|
||
│ 1.248s OnPlayerHPChanged value: 8 (no change) │
|
||
│ 2.001s OnRoomEntered Transform: Room_Forest_01 │
|
||
│ │
|
||
│ [筛选频道: ___________] [仅显示Player] [仅显示Combat] │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 3.3 NavSurface 快速烘焙工具
|
||
|
||
**菜单路径**:`BaseGames > Navigation > Quick Bake All Rooms`
|
||
|
||
一键遍历所有场景中的 `NavSurface`,按顺序烘焙 PathBerserker2d 导航网格并保存场景:
|
||
|
||
```
|
||
┌─ NavSurface Bake Tool ──────────────────────────────────────────┐
|
||
│ 扫描到 NavSurface 数量: 12 │
|
||
│ │
|
||
│ Room_Forest_01: ✓ 已烘焙 (2024-01-01 12:00) │
|
||
│ Room_Forest_02: ⚠ 需要重新烘焙(场景已修改) │
|
||
│ Room_Cave_01: ✓ 已烘焙 │
|
||
│ │
|
||
│ [烘焙全部] [仅烘焙已修改] [验证所有路径连通性] │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 3.4 SaveData 查看器
|
||
|
||
**菜单路径**:`BaseGames > World > SaveData Viewer`
|
||
|
||
```
|
||
┌─ SaveData Viewer ───────────────────────────────────────────────┐
|
||
│ Slot 0 | Slot 1 | Slot 2 │
|
||
│ ───────────────────────────────────────────────────────────── │
|
||
│ Player: HP 5/5 | Geo 340 | Soul 66/99 │
|
||
│ Scene: Room_Forest_01 @ SP_Forest_01_Entry │
|
||
│ Abilities: Parry✓ DoubleJump✓ WallJump✗ Dash✗ Swim✗ │
|
||
│ Discovered: 3 rooms | Cleared: 1 | Bosses Defeated: 0 │
|
||
│ ───────────────────────────────────────────────────────────── │
|
||
│ [JSON 原始视图] [编辑并保存] [删除此存档] │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Scene 视图 Gizmos 汇总
|
||
|
||
| 组件 | Gizmo 形状 | 颜色 | 说明 |
|
||
|------|-----------|------|------|
|
||
| `HitBox` | BoxWire | 橙色(激活:实心50%透明)| 攻击判定区域 |
|
||
| `HurtBox` | BoxWire | 绿色(受击中:红色闪烁)| 受击区域 |
|
||
| `SpawnPoint` | 旗帜Icon + 文字 | 绿色 | 玩家出生点标识 |
|
||
| `RoomTransition` | 箭头 → 目标场景文字 | 蓝色 | 房间出口方向 |
|
||
| `RoomCameraBounds` | Polygon + 内层相机视野矩形 | 青色 | 镜头约束范围 |
|
||
| `EnemyBase` 检测范围 | 圆圈 | 黄色 | 玩家检测半径 |
|
||
| `EnemyBase` 攻击范围 | 圆圈 | 红色(实线)| 攻击触发范围 |
|
||
| `EnemyBase` 巡逻路径 | 线段 + 端点 | 蓝色虚线 | 巡逻 A~B 路径 |
|
||
| `EnemyBase` 寻路目标 | 箭头 | 绿色 | 当前导航目标 |
|
||
| `EnemyBase` 视线检测 | 射线 | 青色(遮挡:红色)| Raycast 视线 |
|
||
| `NavLink` | 弧形箭头 | 紫色 | 导航跳跃链接 |
|
||
| `HazardZone` | BoxWire | 红色(实心30%透明)| 危险区域范围 |
|
||
| `AbilityUnlock` | 星形Icon | 金色 | 能力解锁物件标识 |
|
||
| `SavePoint` | 旗帜Icon(已激活/未激活)| 蓝色/灰色 | 存档点状态 |
|
||
| `ParrySystem`(窗口中)| 圆圈动画 | 黄色 | 弹反窗口激活指示 |
|
||
|
||
---
|
||
|
||
## 5. Play Mode 调试叠加层
|
||
|
||
`DebugOverlayWindow`:按 F1 键(仅 Development Build 和 Editor 中)显示调试叠加层。
|
||
|
||
### 叠加层布局
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ [F1 关闭] FPS: 144 │
|
||
│ │
|
||
│ Player State: RunState HP: 8/10 Soul: 66 Geo: 340 │
|
||
│ IsGrounded: ✓ Facing: → Invincible: ✗ │
|
||
│ │
|
||
│ Active Camera: VCam_Explore Blend: Complete │
|
||
│ Current Room: Room_Forest_01 │
|
||
│ │
|
||
│ Enemies in Scene: 2 Alive: 1 Dead: 1 │
|
||
│ │
|
||
│ ─────────── 快捷键 ─────────────────────────────────────── │
|
||
│ F2 切换无敌 F3 加满 Soul F4 下一检查点 F5 重新加载场景 │
|
||
│ F6 切换 Gizmos F7 切换碰撞体显示 F8 切换 AI 暂停 │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 6. ContextMenu 工具
|
||
|
||
通过 Inspector 右键菜单(`[ContextMenu]`)调用,无需进入 Play Mode:
|
||
|
||
| 组件 | 右键菜单项 | 说明 |
|
||
|------|----------|------|
|
||
| `EnemyStatsSO` | `Print Stats Summary` | Console 打印该敌人完整属性表 |
|
||
| `DamageSourceSO` | `Calculate DPS` | Console 打印理论 DPS(BaseDamage / AttackCooldown)|
|
||
| `RoomCameraBounds` | `Fit to Room Tilemap` | 自动调整 PolygonCollider2D 以包裹 Tilemap 边界 |
|
||
| `NavSurface` | `Bake NavMesh` | 立即烘焙此 NavSurface |
|
||
| `SavePoint` | `Mark As Activated` | 设置 SavePoint 为已激活状态(用于测试继续游戏场景)|
|
||
| `RoomTransition` | `Validate Target Scene` | 检查目标场景是否存在于 BuildSettings |
|
||
|
||
---
|
||
|
||
## 7. 编辑器菜单结构
|
||
|
||
Unity 菜单栏 `BaseGames/` 下的所有工具入口:
|
||
|
||
```
|
||
BaseGames/
|
||
├── Core/
|
||
│ └── Event Channel Monitor → EventChannelMonitorWindow
|
||
│
|
||
├── World/
|
||
│ ├── Room Connection Validator → RoomConnectionValidatorWindow
|
||
│ ├── SaveData Viewer → SaveDataViewerWindow
|
||
│ └── Rebuild All Spawn Points → 扫描并重新生成 SpawnPoint ID 索引
|
||
│
|
||
├── Navigation/
|
||
│ ├── Quick Bake All Rooms → NavSurfaceBakeTool
|
||
│ └── Validate Path Connectivity → 检查所有房间 NavLink 连通性
|
||
│
|
||
├── Combat/
|
||
│ └── DPS Calculator → 输入 DamageSourceSO + AttackCooldown,输出 DPS 表格
|
||
│
|
||
└── Settings/
|
||
├── Open Project Layer Matrix → 快速跳转到 ProjectSettings > Physics2D Layer Matrix
|
||
└── Validate Assembly Definitions → 检查 .asmdef 依赖关系是否符合零耦合原则
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 自动化检查工具
|
||
|
||
### 场景验证检查(保存场景时自动运行)
|
||
|
||
`SceneValidationProcessor`(继承 `AssetModificationProcessor`),在保存场景时自动检查:
|
||
|
||
| 检查项 | 错误级别 | 说明 |
|
||
|--------|---------|------|
|
||
| 场景是否有 `RoomCameraBounds` | Warning | 遗漏镜头约束 |
|
||
| 场景是否有 `NavSurface` | Warning | 有敌人的场景必须有 NavSurface |
|
||
| 所有 `RoomTransition` 目标场景是否在 BuildSettings | Error | 目标场景不存在 |
|
||
| 所有 `HitBox` 是否有对应 `DamageSourceSO` | Error | 攻击参数未配置 |
|
||
| 所有 `EnemyBase` 是否有 `EnemyStatsSO` | Error | 敌人属性未配置 |
|
||
|
||
检查结果在 Console 窗口输出,并在 `Scene Validation` 浮窗中汇总。
|
||
|
||
### Assembly Definition 依赖校验
|
||
|
||
`BaseGames > Settings > Validate Assembly Definitions` 检查 `.asmdef` 是否遵循零耦合原则(如 `BaseGames.Player` 不应直接依赖 `BaseGames.Enemies`),输出依赖图 Mermaid 格式并在 Console 报警。
|
||
|
||
---
|
||
|
||
## 9. 高级工具集(补充)
|
||
|
||
### 9.1 Behavior Tree 验证器
|
||
|
||
`Tools > Zeling > BT Validator`(`BaseGames.Editor.BehaviorTreeValidator`):
|
||
|
||
扫描 `Assets/` 下所有 Behavior Designer `.asset` 文件,检测:
|
||
|
||
| 检查项 | 级别 | 说明 |
|
||
|--------|------|------|
|
||
| 孤立节点(无父节点且非根)| Warning | 表示悬空的设计草稿节点 |
|
||
| 缺失 TaskName 的 Action/Condition | Error | 会导致 BD 无法编译 |
|
||
| SharedVariable 引用为空 | Warning | 运行时会 NullRef |
|
||
| Action 节点最大深度 > 12 | Warning | 过深 BT 建议拆分子树 |
|
||
| 同一 Agent 上同时存在多个 BehaviorTree 组件 | Error | 会互相覆盖 |
|
||
|
||
输出到 Console,双击跳转到对应 BD 资产。
|
||
|
||
### 9.2 进程流程图(Progression Flow Graph)
|
||
|
||
`Tools > Zeling > Progression Flow Graph`(EditorWindow):
|
||
|
||
```
|
||
┌─ Progression Flow Graph ─────────────────────────────────────┐
|
||
│ [刷新] [导出为 PNG] [高亮未实现节点] │
|
||
│ │
|
||
│ ┌Forest──────┐ ─击败SpiderGuard→ ┌Cave───────────────┐ │
|
||
│ │SP_Forest_01│ │SP_Cave_01 │ │
|
||
│ │HP+2 Heart │ │WallJump Unlock │ │
|
||
│ └────────────┘ └───────────────────┘ │
|
||
│ │ │ │
|
||
│ └──────── 需要 Dash ─────────────────┘ │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
- 自动读取所有 `ProgressLock`/`AbilityGate` SO 及 `BossProgressTracker` 配置
|
||
- 用 Bezier 曲线绘制依赖关系(红色=未解锁,绿色=已解锁)
|
||
- 右键节点 → "模拟解锁" → 在 Editor 中测试后续节点是否变绿
|
||
|
||
### 9.3 GameState 转换分析器
|
||
|
||
`Tools > Zeling > GameState Analyzer`(EditorWindow):
|
||
|
||
- 列出 `GameManager` 中所有 `GameState` 枚举值
|
||
- 显示每个状态下:允许的输入 Action Map、哪些 SO 频道被监听
|
||
- 矩阵视图:行 = 事件频道,列 = 当前状态;标注"会触发"/"被忽略"
|
||
- 辅助排查"暂停状态下攻击事件仍被响应"等逻辑漏洞
|
||
|
||
### 9.4 伤害模拟器(Damage Simulator)
|
||
|
||
`DamageSourceSO` 右键菜单 → `Simulate Damage`,弹出快速面板:
|
||
|
||
```
|
||
┌─ Damage Simulator: DamageSource_PlayerAttack1 ──┐
|
||
│ 目标防御: 0 [ ] 格 受伤类型: Normal │
|
||
│ CharmBonus: × 1.5 + 12(剑尖魅力) │
|
||
│ 弱点: × 1.0 [✓] 骑士弱点(十字架) │
|
||
│ ───────────────────────────────────────────── │
|
||
│ 最终伤害: 14(基础 9 × 1.5 + 1 向上取整) │
|
||
│ [运行 1000 次随机伤害分布图] │
|
||
└─────────────────────────────────────────────────┘
|
||
```
|
||
|
||
不需要进入 Play Mode 即可快速验证伤害数值设计。
|
||
|
||
### 9.5 地图贴图验证器(Map Texture Validator)
|
||
|
||
`Tools > Zeling > Map Texture Validator`:
|
||
|
||
- 读取 `MapRoomDataSO.roomOutlineTexture` 与对应场景的实际 Tilemap 边界
|
||
- 对比边界框是否对齐(允许 ± 1 tile 误差)
|
||
- 检测 Texture 是否以 `Read/Write` 导入(SetPixels 需要)
|
||
- 批量输出不匹配的房间列表 + 截图预览
|
||
|
||
### 9.6 音频导入预处理器(Audio Import Preprocessor)
|
||
|
||
`BaseGames.Editor.AudioImportPreprocessor`(继承 `AssetPostprocessor`):
|
||
|
||
规则表(`AudioImportRulesSO`,可在 Inspector 配置):
|
||
|
||
| 文件名前缀 | 平台 | 采样率 | 压缩格式 | Load Type |
|
||
|-----------|------|--------|---------|-----------|
|
||
| `BGM_` | All | 44100 | Vorbis(q=0.4)| Streaming |
|
||
| `SFX_` | All | 22050 | ADPCM | CompressedInMemory |
|
||
| `AMB_` | All | 22050 | Vorbis(q=0.3)| Streaming |
|
||
| `Voice_` | All | 22050 | Vorbis(q=0.6)| CompressedInMemory |
|
||
|
||
导入音频时自动按文件名前缀应用对应设置,Console 输出 `[AudioPreprocessor] Applied: SFX rule → SFX_Player_Hurt.wav`。
|
||
|
||
### 9.7 装备预览工具(Equip Preview)
|
||
|
||
`Tools > Zeling > Equip Preview`(EditorWindow):
|
||
|
||
```
|
||
┌─ Equip Preview ──────────────────────────────────────────────┐
|
||
│ 选择魅力组合(最多 4 个槽位): │
|
||
│ 槽1: [剑之力量魅力 ▼] 槽2: [灵魂强化魅力 ▼] │
|
||
│ 槽3: [无 ] 槽4: [无 ] │
|
||
│ ───────────────────────────────────────────────────────── │
|
||
│ 最终属性: │
|
||
│ 攻击力: 9 × 1.5 = 13 法术消耗: 33 × 0.67 = 22 │
|
||
│ 弹反 Soul: 10 → 10 法术弹数: 3 → 3 │
|
||
│ 路径成本: 4 个通知(EquipmentManager.Apply × 4) │
|
||
│ [复制配置 JSON] [应用到 Player(Play Mode)] │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 9.8 构建验证器(Build Validator)
|
||
|
||
`Tools > Zeling > Validate Build`,在正式打包前执行完整检测:
|
||
|
||
| 检测项 | 级别 |
|
||
|--------|------|
|
||
| 所有场景已加入 Build Settings | Error |
|
||
| 所有 `AudioImportRulesSO` 规则已应用 | Warning |
|
||
| 所有 `AnimationEventConfigSO` 无超出范围的事件时间 | Error |
|
||
| 所有 `AbilityGate` 引用的能力 ID 存在于 `AbilityType` 枚举 | Error |
|
||
| 所有 `LocalizationKeys` 常量在 zh-CN StringTable 中有对应条目 | Warning |
|
||
| Player Prefab 已注册为 Addressable(address = `"Player"`,不使用 `Resources/`)| Error |
|
||
| 所有 Addressable Group 无缺失引用(Missing Reference)| Error |
|
||
| `SaveData` JSON Schema 与当前字段一致(版本检查)| Warning |
|
||
| 构建目标平台 Build Target 与发布目标匹配 | Warning |
|
||
|
||
输出结果为 Build Validation Report(Text + 每项跳转链接),只有零 Error 才允许继续打包。
|