【AI编码】生成文档

main
刘涛 2026-02-06 16:56:51 +08:00
parent 1e2faa664b
commit ed30e9238f
1 changed files with 222 additions and 0 deletions

View File

@ -0,0 +1,222 @@
# 载具科技树生成 功能说明
## 一、功能概述
载具科技树生成是一个 **Unity 编辑器工具**,用于根据配置表数据自动构建载具科技树和组件(部件)树的 UI 预制体。生成的预制体供运行时 UI 界面加载使用。
编辑器菜单入口:`Tools / *UI / 载具科技树生成`
---
## 二、核心文件一览
### 编辑器侧
| 文件路径 | 类名 | 职责 |
|---------|------|------|
| `Assets/EditorHelper/AreaEditor/TreeEditor/TreeEditorWindow.cs` | `TreeEditorWindow` | Odin 编辑器窗口,提供派系/载具选择菜单 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/TreeEditPreload.cs` | `TreeEditPreload` | 预加载器,加载配置表、打开编辑场景、触发树生成 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/VehicleTreeManager.cs` | `VehicleTreeManager` | **核心管理器**,负责树数据构建、节点创建、布局计算、连线绘制 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/TreeEditorManager.cs` | `TreeEditorManager` | 抽象基类,提供分层树 / 非分层树的通用布局算法 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/Editor/VehicleTreeManagerEditor.cs` | `VehicleTreeManagerEditor` | 自定义 Inspector提供"重新生成连线"和"保存为预制体"按钮 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/Node.cs` | `Node` / `TreeData` | 节点数据类NodeId、父子关系、深度、对应 GameObject |
| `Assets/EditorHelper/AreaEditor/TreeEditor/TileManager.cs` | `TileManager` | 管理节点 UI 模板预制体列表,按索引实例化 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/LineDrawer.cs` | `LineDrawer` | 连线绘制辅助 |
| `Assets/EditorHelper/AreaEditor/TreeEditor/PloegTreeLayout.cs` | `PloegTreeLayout` | Ploeg 布局算法(非分层树使用) |
| `Assets/EditorHelper/AreaEditor/TreeEditor/Reingold-Tilford/TreeHelpers.cs` | `TreeHelpers` | Reingold-Tilford 布局算法(分层树使用) |
| `Assets/EditorHelper/AreaEditor/TreeEditor/Reingold-Tilford/TreeNodeModel.cs` | `TreeNodeModel` | 布局算法的树节点模型 |
### 运行时侧
| 文件路径 | 类名 | 职责 |
|---------|------|------|
| `Assets/Code/Scripts/GamePlay/UI/VehicleCultivate/VehicleCultivateManager.cs` | `VehicleCultivateManager` | 运行时数据管理器,包含静态方法 `LoadVehicleTreeNode` 加载树节点数据(编辑器和运行时共用) |
| `Assets/Code/Scripts/GamePlay/UI/UI_VehicleTechTreeController.cs` | `UI_VehicleTechTreeController` | 运行时科技树 UI 控制器,管理派系切换、节点状态显示 |
---
## 三、两种树类型
`VehicleTreeManager` 通过枚举 `TreeContent` 区分两种树:
### 1. 载具树 (`TreeContent.Vehicle`)
- **作用**:按派系(`VehicleType`)展示所有载具的层级关系
- **布局算法**:分层布局(`TreeType.layered`),基于 **Reingold-Tilford** 算法
- **节点深度**:由配置表中的 `VehicleLevel` 决定(非自然树深度)
- **特殊处理**`Buy` 类型载具按等级排序后串联成链
### 2. 组件树 / 部件树 (`TreeContent.Component`)
- **作用**:展示某个载具下的子载具和子部件的树形结构
- **布局算法**:非分层布局(`TreeType.non_layered`),基于 **Ploeg** 算法
- **根节点**:指定载具 ID 作为根
- **遍历方式**BFS 遍历根载具的 `VehicleChildren``ComponentChildren`
- **额外调整**:支持自定义根节点位置(`componentTreeRootPosition`)和深层节点间距(`deepNodeVerticalSpacing`
---
## 四、生成流程详解
### 4.1 总体调用链
```
TreeEditorWindow.OpenWindow() ← 菜单入口
└── 用户选择派系/载具后点击按钮
└── TreeEditPreload.OpenScene()
├── EditorTableManager.ForceReload() ← 加载配置表
├── EditorSceneManager.OpenScene(TreeEditorScene.unity) ← 打开编辑场景
└── VehicleTreeManager.ForceInit() ← 初始化并生成树
├── ClearCurrentTree() ← 清理旧数据
└── LoadOrInit()
├── VehicleCultivateManager.LoadVehicleTreeNode() ← 从配置表加载节点数据
└── TreeInit() ← 构建并布局树
```
### 4.2 TreeInit() 核心流程
```
TreeInit()
├── 1. CreateTree() ← 根据配置创建 Node 对象,建立父子关系
│ ├── [载具树] 循环遍历所有 VehicleTreeNode
│ │ ├── 创建 ID=0 的虚拟根节点
│ │ ├── 按父子依赖逐轮添加节点while 循环直到无新节点)
│ │ ├── 对每个节点:判断 UnlockType 选择模板 → 设置图标/名称/类型标识
│ │ └── Buy 类型节点按 VehicleLevel 排序后重新串联父子关系
│ │
│ └── [组件树] BFS 遍历根载具的子节点
│ ├── 创建根载具节点
│ ├── 将 VehicleChildren 和 ComponentChildren 入队
│ ├── BFS 循环:创建节点、区分子载具/子部件选择不同模板
│ └── 设置图标、部件类型图标等属性
├── 2. CreatePrefab(treeGameObject) ← 将所有 Node.tile 挂载到树 GameObject 下
│ └── BFS 遍历所有节点,设置 parent、localScale、命名为 "v_{NodeId}"
├── 3. 布局计算
│ ├── [分层树 layered]
│ │ ├── GetSampleTree() ← 构建 TreeNodeModel 树结构
│ │ ├── TreeHelpers.CalculateNodePositions() ← Reingold-Tilford 算法计算 X/Y
│ │ └── PrintPos() ← 设置 RectTransform.anchoredPosition
│ │ └── 深度取自 VehicleLevel 而非自然树深度
│ │
│ └── [非分层树 non_layered]
│ ├── calculateDepth() ← BFS 计算各节点深度
│ ├── SetNonLayeredTreeLayout() ← 初步布局
│ ├── PloegLayout() ← Ploeg 算法精确布局
│ ├── AdjustDeepNodeSpacing() ← 深层节点额外间距调整
│ └── AdjustComponentTreePosition() ← 整体偏移使根节点到指定位置
└── 4. DrawLine(treeGameObject) ← 绘制连线
├── 创建/获取 LineParent 子对象上的 UILineRenderer
├── 遍历所有节点 → 遍历其 childrenIDs
│ ├── Buy→Buy 连线跳过
│ ├── 直线模式:起点→终点
│ └── 折线模式起点→中间点1→中间点2→终点
└── lineRenderer.SetPoints(points) 提交连线数据
```
### 4.3 保存为预制体
通过 Inspector 上的按钮或 OnGUI 按钮触发:
```csharp
PrefabUtility.SaveAsPrefabAsset(
m_shownTree,
"Assets/Art_Out/UI/Prefab/Interface_Vehicle/TechTree/" + m_shownTree.name + ".prefab"
);
```
- 载具树命名格式:`{VehicleType}_0.prefab`
- 组件树命名格式:`TechTree_{VehicleID}.prefab`
---
## 五、使用的资源文件
### 5.1 编辑场景
| 资源 | 路径 |
|------|------|
| 编辑器场景 | `Assets/Editor/UIEditor/TreeEditorScene.unity` |
| 编辑器预制体 | `Assets/EditorHelper/AreaEditor/TreeEditor/Editor/Vehicle_Editor_Prefab.prefab` |
### 5.2 节点模板预制体TileManager.TilePrefabs
配置在 `Vehicle_Editor_Prefab.prefab``TileManager` 组件中,共 5 个模板:
| 索引 | Prefab 文件 | 用途 |
|------|------------|------|
| **0** | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/VehicleTechTreeList_VehicleItemRMB_New.prefab` | 载具树 - Buy 类型载具节点 / 虚拟根节点 |
| **1** | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/VehicleTechTreeList_VehicleItemNormal_New.prefab` | 载具树 - 普通解锁类型载具节点 |
| **2** | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/VehiclePartTreeList_PartItem_New.prefab` | 组件树 - 子部件节点 |
| **3** | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/VehiclePartTreeList_VehicleItem_New.prefab` | 组件树 - 子载具节点 |
| **4** | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/VehiclePartTreeList_VehicleItemRoot.prefab` | 组件树 - 根节点(当前载具) |
### 5.3 图标资源
| 用途 | 路径模式 |
|------|---------|
| 载具头像图标 | `Assets/Art_Out/UI/Texture/Icon/Vehicle/NewHeadPic/{UIHeadPath}` |
| 载具类型图标 | `Assets/Art_Out/UI/Texture/Icon/Vehicle/VehicleType/{TypeIcon}.png` |
| 部件图标 | `Assets/Art_Out/UI/Texture/Icon/Vehicle/VehiclePart/{Icon}` |
| 部件类型图标 | `Assets/Art_Out/UI/Texture/Icon/Vehicle/VehiclePartType/{VehiclePartIcon}.png` |
| 默认头像(隐藏载具) | `Assets/Art_Out/UI/Texture/Icon/Vehicle/NewHeadPic/Icon_Vehicle_C00000.png` |
### 5.4 配置表(数据源)
| 配置表 | 提供数据 |
|-------|---------|
| `VehicleConfig` | 载具 ID、名称、派系类型、等级、解锁类型、图标路径、是否隐藏 |
| `VehicleComponent` | 部件 ID、所属载具、部件类型、图标 |
| `ConditionConfig` | 解锁条件(用于构建父子关系) |
| `GlobalConfig` | 部件类型图标路径配置 |
### 5.5 生成产物(输出)
| 产物 | 路径 |
|------|------|
| 科技树预制体 | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/TechTree/TechTree_{VehicleID}.prefab` |
| 派系树预制体 | `Assets/Art_Out/UI/Prefab/Interface_Vehicle/TechTree/{VehicleType}_0.prefab` |
---
## 六、运行时加载
运行时由 `UI_VehicleTechTreeController``Interface_Vehicle/TechTree/` 路径加载对应预制体,实例化到 UI 界面中显示。控制器负责:
- 按派系VehicleType切换不同的科技树
- 显示载具解锁状态
- 处理节点点击事件(跳转到部件树详情)
- 动态更新节点和箭头状态
---
## 七、关键类关系图
```
TreeEditorWindow (Odin编辑器窗口)
└── TreeEditPreload (预加载器/单例)
├── EditorTableManager (配置表加载)
└── VehicleTreeManager : TreeEditorManager (核心管理器)
├── TileManager (节点模板管理)
│ └── TilePrefabs[0..4] (5个模板预制体)
├── Node (节点数据)
│ ├── NodeId, parentsID, childrenIDs, depth
│ └── tile (对应的 GameObject)
├── UILineRenderer (连线绘制)
├── TreeHelpers (Reingold-Tilford 分层布局)
└── PloegTreeLayout (Ploeg 非分层布局)
VehicleCultivateManager (运行时 & 编辑器共用)
└── LoadVehicleTreeNode() ← 静态方法,解析配置表生成 VehicleTreeNode / VehicleComponentTreeNode
```