ProtypeProject/GAMEPLAY_EDITOR_SOLUTION.md

8.4 KiB
Raw Permalink Blame 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 包

# 在 Unity 项目中安装(需要配置 NuGet
Install-Package EPPlus

API

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

// 在某个 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 中的节点结构:

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. 节点类型过滤

schema.nodeTypeFilter = new List<string> { "SkillNode", "BuffNode" };
// 只同步这两种类型的节点

2. 嵌套字段支持

// 节点中有嵌套对象
public class SkillNode : FlowNode
{
    public SkillData data;
}

public class SkillData
{
    public float duration;
}

// Schema 配置支持嵌套路径
fieldName = "data.duration"

3. 自定义字段类型转换

// 在 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. 启用自动同步

// 在 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 表格,支持拖拽编辑