ProtypeProject/GAMEPLAY_EDITOR_SOLUTION.md

313 lines
8.4 KiB
Markdown
Raw Normal View History

# 玩法编辑器系统 — 完整实现方案
## 系统架构
```
┌─────────────────────────────────────────────────────────────────┐
│ GameplayEditorWindow (Editor) │
│ ┌──────────────────────────┐ ┌────────────────────────────┐ │
│ │ Canvas 可视化编辑 │ │ Excel 表格映射 │ │
│ │ (FlowCanvas/NodeCanvas) │ │ (GraphDataSchema) │ │
│ └──────────┬───────────────┘ └─────────────┬──────────────┘ │
│ │ │ │
│ └──────────────┬─────────────────┘ │
│ │ │
│ GraphExcelSyncManager (Runtime) │
│ (双向同步: Graph JSON ↔ Excel 表格) │
│ │ │
│ ┌──────────────────┴──────────────────┐ │
│ │ │ │
│ ExcelDataProvider Graph.onGraphSerialized │
│ (EPPlus 读写 .xlsx) (自动触发同步) │
└─────────────────────────────────────────────────────────────────┘
```
---
## 核心模块说明
### 1. **GraphDataSchema** (`GraphDataSchema.cs`)
定义 Canvas 节点字段 ↔ Excel 列的映射关系
**使用方式:**
```
在 Unity Editor 中:
1. 右键 → Create → GameplayEditor/GraphDataSchema
2. 配置字段映射:
- fieldName: 节点中的字段名(支持嵌套如 'task.duration'
- excelColumnName: Excel 表格列名
- fieldType: 数据类型String/Int/Float/Bool/Vector3/Color
3. 指定 sheetName对应 Excel 中的 Sheet 名称)
```
**示例配置:**
```
Sheet: "技能"
字段映射:
- ID → NodeID (Int)
- name → NodeName (String)
- comment → 描述 (String)
- task.duration → 持续时间 (Float)
```
---
### 2. **ExcelDataProvider** (`ExcelDataProvider.cs`)
负责读写 .xlsx 文件的底层操作
**依赖:** EPPlus NuGet 包
```bash
# 在 Unity 项目中安装(需要配置 NuGet
Install-Package EPPlus
```
**API**
```csharp
var provider = new ExcelDataProvider("Assets/玩法编辑器.xlsx");
// 读取 Sheet
var data = provider.ReadSheet("技能");
// 写入 Sheet
provider.WriteSheet("技能", nodeDataList);
// 获取所有 Sheet 名称
var sheets = provider.GetSheetNames();
```
---
### 3. **GraphExcelSyncManager** (`GraphExcelSyncManager.cs`)
运行时双向同步管理器
**工作流程:**
**Canvas → Excel自动**
```
Graph.SelfSerialize()
↓ (触发 onGraphSerialized 事件)
GraphExcelSyncManager.OnGraphChanged()
ExtractNodeData() (遍历所有节点,按 Schema 提取字段)
ExcelDataProvider.WriteSheet() (写入 Excel)
```
**Excel → Canvas手动触发**
```
SyncExcelToGraph()
ExcelDataProvider.ReadSheet() (读取 Excel 数据)
ApplyDataToGraph() (按 NodeID 匹配节点,更新字段)
Graph 节点更新完成
```
---
### 4. **GameplayEditorWindow** (`GameplayEditorWindow.cs`)
编辑器窗口 UI
**打开方式:** `Window → Gameplay Editor`
**功能:**
- 左侧Canvas 节点列表(实时显示)
- 右侧Schema 字段映射(配置参考)
- 工具栏同步按钮Canvas ↔ Excel
---
## 使用流程
### 第一步:创建 Schema 配置
```
1. 在 Assets 中右键 → Create → GameplayEditor/GraphDataSchema
2. 命名为 "SkillGraphSchema"
3. 配置字段映射(对应你的 Graph 节点结构)
4. 保存
```
### 第二步:配置 SyncManager
```csharp
// 在某个 MonoBehaviour 中
public class GameplayController : MonoBehaviour
{
public Graph skillGraph;
public GraphDataSchema skillSchema;
private void Start()
{
var syncManager = gameObject.AddComponent<GraphExcelSyncManager>();
syncManager.targetGraph = skillGraph;
syncManager.schema = skillSchema;
}
}
```
### 第三步:编辑工作流
```
1. 在 Canvas 中编辑节点 → 自动同步到 Excel
2. 在 Excel 中修改数据 → 点击"同步 Excel → Canvas"更新
3. 支持批量编辑:在 Excel 中修改多行数据,一次性导入
```
---
## 数据流向示例
### 场景:编辑技能节点
**Canvas 中的节点结构:**
```csharp
public class SkillNode : FlowNode
{
public int skillID;
public string skillName;
public float cooldown;
public int manaCost;
}
```
**Schema 配置:**
```
Sheet: "技能"
字段映射:
- skillID → 技能ID (Int)
- skillName → 技能名称 (String)
- cooldown → 冷却时间 (Float)
- manaCost → 魔法消耗 (Int)
```
**Excel 表格:**
```
| 技能ID | 技能名称 | 冷却时间 | 魔法消耗 |
|--------|---------|---------|---------|
| 1 | 火球术 | 5.0 | 50 |
| 2 | 冰冻术 | 8.0 | 60 |
```
**同步流程:**
```
修改 Canvas 节点 → Graph.SelfSerialize()
→ onGraphSerialized 事件触发
→ ExtractNodeData() 提取 [skillID, skillName, cooldown, manaCost]
→ WriteSheet() 写入 Excel
→ Excel 自动更新
```
---
## 高级特性
### 1. 节点类型过滤
```csharp
schema.nodeTypeFilter = new List<string> { "SkillNode", "BuffNode" };
// 只同步这两种类型的节点
```
### 2. 嵌套字段支持
```csharp
// 节点中有嵌套对象
public class SkillNode : FlowNode
{
public SkillData data;
}
public class SkillData
{
public float duration;
}
// Schema 配置支持嵌套路径
fieldName = "data.duration"
```
### 3. 自定义字段类型转换
```csharp
// 在 ExcelDataProvider 中扩展
private object ConvertValue(object value, GraphDataSchema.FieldType type)
{
switch (type)
{
case GraphDataSchema.FieldType.Vector3:
// 自定义 Vector3 解析逻辑
break;
// ...
}
}
```
---
## 集成现有项目的步骤
### 1. 复制文件到项目
```
Assets/BP_Scripts/GameplayEditor/
├── GraphDataSchema.cs
├── ExcelDataProvider.cs
├── GraphExcelSyncManager.cs
└── GameplayEditorWindow.cs
```
### 2. 安装 EPPlus 依赖
```
在 Packages/manifest.json 中添加:
"com.epplus": "https://github.com/EPPlusSoftware/EPPlus.git"
```
### 3. 为现有 Graph 创建 Schema
```
对于每个 Graph 类型(技能、关卡、单位、行为树),
创建对应的 Schema 配置文件
```
### 4. 启用自动同步
```csharp
// 在 GameplayController 中
private void OnEnable()
{
Graph.onGraphSerialized += OnGraphChanged;
}
```
---
## 与参考项目的对应关系
| 参考项目文件 | 我们的实现 | 用途 |
|---|---|---|
| `行为树教程.xlsx` | `GraphDataSchema` | 定义表格结构 |
| `x效果C054.xlsm` | `ExcelDataProvider` | 读写 Excel |
| `g关卡C036.xlsm` | `GameplayEditorWindow` | 编辑界面 |
| `d单位G071.xlsm` | `GraphExcelSyncManager` | 数据同步 |
---
## 故障排查
### 问题 1Excel 文件被锁定
**原因:** 文件被其他程序打开
**解决:** 关闭 Excel重新同步
### 问题 2字段映射不生效
**原因:** fieldName 拼写错误或字段不存在
**解决:** 检查 Schema 配置中的 fieldName 是否与节点字段名完全匹配
### 问题 3数据类型转换失败
**原因:** Excel 中的数据类型与 Schema 定义不符
**解决:** 在 ExcelDataProvider 中添加类型转换逻辑
---
## 扩展方向
1. **支持多 Graph 同时编辑** → 在 GameplayEditorWindow 中添加 Tab 页
2. **版本控制** → 记录每次同步的时间戳和变更内容
3. **冲突解决** → 当 Canvas 和 Excel 同时修改时的合并策略
4. **导出配置** → 将 Graph 导出为 JSON/Protobuf 供游戏运行时使用
5. **可视化表格** → 在 Editor 中直接显示 Excel 表格,支持拖拽编辑