# 玩法编辑器使用手册 ## 1. 设计目的 优化版本并行开发效率,缩短特殊玩法需求频繁迭代功能的开发周期。 --- ## 2. 工作流 对应负责人开启活动需求统筹表 → 下游各组资产制作完成后 → 根据需求统筹表描述放到对应路径提交上传 → **策划通过玩法编辑器进行配置好索引表并上传** → 在引擎内使用导入工具检查资源。 --- ## 3. 配置说明 活动玩法会涉及到场景资源、镜头资源、UI资源、特效资源。所有资源会配表做静态字典映射,在开启活动模块时根据映射加载对应资源。**行为树逻辑编辑器在节点引用时会从对应字典内进行查找引用。** --- ## 3.1 行为树配置表(自定义 name) ### 工作表1:玩法关卡配置表 用来索引玩法场景的逻辑 ID、场景资源、地图坐标打点 list、默认主相机。 | Doc | 行为树ID | 关卡备注 | 场景名称 | 地图打点组 | 是否关闭加载画面 | 默认相机ID | |------|------------------|---------|-------------|------------|--------------------------|----------| | Name | ActivityStageID | Doc | SceneName | MapInfo | CloseLoadingDelaySeconds | CameraID | | Type | Int | String | String | ID | Float | Int | > 打开:**功能编辑器** --- ### 工作表2:行为树逻辑表 配置行为树头文件和行为树逻辑本身。 | 列名 | 说明 | |-----------|-------------------------------------------------------------| | 行为树ID | 全局唯一标识(如 301502490) | | 说明(注释)| 行为树文件说明 | | 节点 | 各级子节点名称(可展开多列) | | 行索引ID | 行为节点在行为树中的引用 ID | **节点层级结构说明(树形):** ``` 行为树ID: 301502490 (行为树文件 平行) ├── 组合 方法:关卡通用关卡赋值 ├── 组合 方法:关卡初始化 └── 后面是你自己的逻辑 行为树ID: 30150249 (行为树逻辑正文 顺序) ├── 组合 方法:关卡预准备 ├── 平行 │ └── 组合 方法:关卡通用集合 └── 后面是你自己的逻辑 ``` **行为树关键说明:** 1. **【关卡ID+0】** 为头文件,里面的逻辑只执行一次,用来声明初始数据或执行一些初始化逻辑。 2. **【关卡ID】** 后开始是行为树正文,主要写正式逻辑,默认1秒运行60次(根据性能需求可调整到1秒20次)。 3. **【行索引】** 会在当前行有子功能节点时打表自动生成,方便报错时定位行数。 4. **【组合方法】** 封装函数或子树,类似行为树的子树结构一处理一些通用赋值,比如开场是否隐藏UI、是否播放某个入场动画、对多个字典进行赋值等等。 5. 行为树默认包含四个基础执行节点: - **平行**:执行该节点下的所有子节点并返回true,无论子节点是否执行成功。 - **顺序**:该节点下一旦有子节点返回false则停止执行返回false,子节点全部返回true该节点才返回true。 - **选择**:该节点下一旦有子节点返回true则停止执行返回true,子节点全部返回false该节点才返回false。 - **乱选**:随机执行一个子节点,结果为true则返回true,结果false返回false。 6. 需要一个组合方法在头文件里分别在黑板里创建1#(当前行为树域)、2#(角色域)、3#(自定义域)、4#(系统全局域)、UI、相机、特效、演出配置的映射字典(**或者是外部Data管理,功能节点默认找对应字典**)。 --- ### 工作表3:行为树节点查询与说明(注释用) | 节点类型 | 描述 | 中文节点映射 | 参数1 | 参数2 | 参数3 | 参数4 | 参数5 | |-------------------|----------------------------------------------------------|-------------|-------------|--------------|-------|-------|-------| | DoGetTime | 参数1(帧数)= 当前关卡时间(帧数)+ 参数2(秒转帧数) | int赋值时间 | int 帧数存值 | fix 时间单位秒 | | | | | CheckNpcCamp | 比较阵营是否相等或包含参数1NPC参数2阵营(包含、相交、相等都是队友) | 比较阵营 | int 自定义 | int 自定义 | | | | | DoSetFightTarget | 设置Npc1(参数1)的攻击目标为Npc2(参数2) | 设置战斗目标 | int Npc1 | int Npc2的Id | | | | --- ### 工作表4:组合节点说明(同工作表3) | 组合树ID | 组合树类型 | 注释 | |-----------|-----------|------| | String | 节点名称 | | | 200009 | 万法:关卡初始化 | | | 200010 | 万法:关卡预准备 | | --- ## 3.2 ActivityUiLut UI 资源。填写需要使用的关卡和映射 ID,可以填 String。 | 关卡ID | UI映射ID | Prefab路径 | |-------|---------|-----------| | int | int | path | --- ## 3.3 ActivityCameraLut 相机资源,配置同上。 | 关卡ID | Cam映射ID | Prefab路径 | |-------|----------|-----------| | int | int | path | --- ## 3.4 ActivityFXLut 特效资源,配置同上。 | 关卡ID | FX映射ID | Prefab路径 | |-------|---------|-----------| | int | int | path | --- ## 3.5 ActivityMapInfoLut 地图打点存储表,需要对应的地图点位编辑器。 | infoID | 点位ID | 坐标 | 点位ID | 坐标 | 点位ID | 坐标 | 点位ID | 坐标 | |--------|---------|---------|---------|---------|---------|---------|---------|---------| | int | String | Vector3 | String | Vector3 | String | Vector3 | String | Vector3 | --- ## 3.6 ActivityDialogInfoByStage 活动文本 UI 配置索引表。文本配置 ID 就是下面 DialogInfo 配置表的 name。 | 玩法关卡ID | 对应文本配置表 | |----------|-------------| | int | String | --- ## 3.7 DialogInfo + 自定义序号 具体文本配置(**与行为树一样,每个策划一张自己的 dialoginfo,需要先跟本地化管线讨论**)。 | id | isMask | MaskTarget | ClickKey | DialogType | UIType | PrefabPath | Name | Text | Duration | Params1 | Params2 | Params3 | Params4 | Params5 | |--------|--------|---------------|---------|------------|--------|----------------------|---------|-----------|---------|---------|---------|---------|---------|---------| | 配置ID | 是否开启蒙层 | 蒙层位置(万分比屏幕坐标) | 关闭蒙层键值 | 战中类型 | UI样式(变同类型战中样式) | UI预制体路径(默认不填写) | 显示角色名 | 正文(支持富文本) | 显示时间 | 特殊参数1 | 特殊参数2 | 特殊参数3 | 特殊参数4 | 特殊参数5 | | int | bool | 万分比屏幕坐标 | int | int | int | | String | 对话正文 | float | | | | | | **行为树对应功能节点:** | 节点名称 | 参数1 | |--------------|-------------| | DoShowDialog | DialogInfoID | | int | int | --- ## 4. QA & Debug 1. 上传对应行为树前需要策划自检,流程是否可以整跑通,过程中是否有节点报错,根据对应报错 ID 进行 Debug。 2. 资源检查:需要策划导入时自行检查资源是否与需求对应,是否在导入时出现失索引。 3. 提测 QA 后,QA 如发现流程卡死或报错,需要先向策划负责人提单,策划检查判断确定是非配置问题,再向其他对应下游提出修改需求。 --- ## 5. 玩法编辑器工具操作指南 ### 5.1 文件结构 ``` Assets/BP_Scripts/GameplayEditor/ ├── Core/ │ ├── ActivityNodeBase.cs ← 所有节点的抽象基类 │ ├── GameplayNode.cs ← 行为树逻辑节点(工作表2) │ ├── ActivityStageNode.cs ← 关卡配置节点(工作表1) │ ├── BehaviourDocNodes.cs ← 节点说明 + 组合节点(工作表3/4) │ ├── LutNodes.cs ← UI/Camera/FX资源映射(3.2/3.3/3.4) │ ├── DataNodes.cs ← 地图/对话配置节点(3.5/3.6/3.7) │ ├── GameplayGraph.cs ← 自定义 Graph 类型 │ └── GameplayConnection.cs ← 节点连线类型 ├── Export/ │ ├── ExcelExporter.cs ← Canvas → 多个 CSV 导出 │ └── ExcelImporter.cs ← 多个 CSV → Canvas 导入 ├── GameplayEditorWindow.cs ← 编辑器窗口 UI(支持表格选择) ├── GraphDataSchema.cs ← 字段映射配置(ScriptableObject) ├── GraphExcelSyncManager.cs ← 运行时同步组件 └── ExcelDataProvider.cs ← CSV 读写基础工具 ``` --- ### 5.2 快速开始(完整流程) **第一步:创建 GameplayGraph Asset** 在 Project 窗口中右键 → **Create → NodeCanvas → Gameplay Graph**,命名为 `ActivityGraph`。 **第二步:打开玩法编辑器窗口** 菜单栏 → **Window → Gameplay Editor** ``` ┌──────────────────────────────────────────────────────────────┐ │ [Graph 拖槽] [Schema 拖槽] [导出所有表→CSV] [导入CSV→Canvas] │ ← 工具栏 ├─────────────────────┬────────────────────────────────────────┤ │ Canvas 节点列表 │ 表格选择 + 字段映射 │ │ 按表格分组显示所有 │ 下拉菜单选择要查看的表格 │ │ 节点(10种类型) │ 显示该表的字段结构 │ └─────────────────────┴────────────────────────────────────────┘ ``` 将 `ActivityGraph` 拖入工具栏左侧的 **Graph 拖槽**。 **第三步:在 Canvas 中添加节点** 双击 `ActivityGraph.asset` 打开 NodeCanvas 编辑器,右键画布 → **Add Node → GameplayEditor → [节点类型]** 支持的节点类型(10种): | 节点类型 | 对应表格 | 用途 | |---------|---------|------| | GameplayNode | BehaviourTree | 行为树逻辑节点 | | ActivityStageNode | ActivityStage | 关卡配置(场景、地图、相机) | | BehaviourNodeDocNode | BehaviourNodeDoc | 节点类型说明(注释用) | | ActivityGroupNode | ActivityGroup | 组合节点说明 | | UiLutNode | ActivityUiLut | UI资源映射 | | CameraLutNode | ActivityCameraLut | 相机资源映射 | | FXLutNode | ActivityFXLut | 特效资源映射 | | MapInfoNode | ActivityMapInfoLut | 地图打点(支持8个点) | | DialogByStageNode | ActivityDialogInfoByStage | 对话索引 | | DialogInfoNode | DialogInfo | 对话详细配置 | **第四步:编辑节点字段** 点击节点在 Inspector 中填写对应字段。每种节点的字段不同,参考下方字段说明。 **第五步:导出所有表 → CSV** 工具栏点击 **"导出所有表 → CSV"**,自动生成 10 个 CSV 文件到 `Assets/` 目录: ``` Assets/ ├── BehaviourTree.csv ├── ActivityStage.csv ├── BehaviourNodeDoc.csv ├── ActivityGroup.csv ├── ActivityUiLut.csv ├── ActivityCameraLut.csv ├── ActivityFXLut.csv ├── ActivityMapInfoLut.csv ├── ActivityDialogInfoByStage.csv └── DialogInfo.csv ``` 每个 CSV 格式(行1=字段名,行2=类型,行3=说明,行4起=数据): ``` LevelID,NodeID,NodeLayer,EventTypeGroup,Priority,EventMappingID,InteractVisible,NodeState,ParentNodeID int,int,int,string,string,int,bool,bool,int 关卡编号ID,节点ID(唯一),节点层级,节点事件类型组(|分隔),优先级权重(|分隔),存储事件ID映射,交互是否可见,节点是否可进入,父节点ID(-1表示根节点) 1,101,0,1|2,10|20,5001,True,True,-1 1,102,1,3,30,5002,True,True,101 ``` **第六步:用 Excel 批量编辑** 1. 用 Excel 打开任意 CSV(打开时选 UTF-8 编码) 2. 修改数据(**不要删除前3行表头**) 3. 保存文件 **第七步:导入 CSV → Canvas** 回到 Unity,点击 **"导入 CSV → Canvas"** > **注意:导入会清空当前 Canvas 中的所有节点后重建。** 导入后自动根据 `ParentNodeID` 重建 GameplayNode 连线。 --- ### 5.3 各表字段说明 #### 工作表1:ActivityStage(关卡配置) | 字段 | 类型 | 说明 | |------|------|------| | ActivityStageID | int | 行为树ID(全局唯一) | | Doc | string | 关卡备注 | | SceneName | string | 场景名称 | | MapInfo | string | 地图打点组ID | | CloseLoadingDelaySeconds | float | 关闭加载画面延迟(秒) | | CameraID | int | 默认相机ID | #### 工作表2:BehaviourTree(行为树逻辑) | 字段 | 类型 | 说明 | |------|------|------| | LevelID | int | 关卡编号ID | | NodeID | int | 节点唯一ID(**同一Graph内不重复**) | | NodeLayer | int | 节点层级(0=顶层) | | EventTypeGroup | string | 事件类型组(`\|`分隔,如 `1\|2\|3`) | | Priority | string | 优先级权重(`\|`分隔,如 `10\|20`) | | EventMappingID | int | 事件ID映射值 | | InteractVisible | bool | 交互时是否显示 | | NodeState | bool | 节点是否可进入 | | ParentNodeID | int | 父节点ID(**-1=根节点**) | #### 工作表3:BehaviourNodeDoc(节点说明) | 字段 | 类型 | 说明 | |------|------|------| | NodeType | string | 节点类型(如 DoGetTime) | | Description | string | 节点描述 | | ChineseMapping | string | 中文节点映射 | | Param1~5 | string | 参数1~5说明 | #### 工作表4:ActivityGroup(组合节点) | 字段 | 类型 | 说明 | |------|------|------| | GroupTreeID | string | 组合树ID | | GroupTreeType | string | 组合树类型/节点名称 | | Comment | string | 注释 | #### 3.2:ActivityUiLut(UI资源映射) | 字段 | 类型 | 说明 | |------|------|------| | StageID | int | 关卡ID | | UIMappingID | int | UI映射ID | | PrefabPath | string | Prefab路径 | #### 3.3:ActivityCameraLut(相机资源映射) | 字段 | 类型 | 说明 | |------|------|------| | StageID | int | 关卡ID | | CamMappingID | int | 相机映射ID | | PrefabPath | string | Prefab路径 | #### 3.4:ActivityFXLut(特效资源映射) | 字段 | 类型 | 说明 | |------|------|------| | StageID | int | 关卡ID | | FXMappingID | int | 特效映射ID | | PrefabPath | string | Prefab路径 | #### 3.5:ActivityMapInfoLut(地图打点) 支持最多8个打点,每个打点包含 ID 和 Vector3 坐标(格式:`x\|y\|z`) | 字段 | 类型 | 说明 | |------|------|------| | InfoID | int | 地图信息ID | | PointID_1~8 | string | 打点ID | | Coord_1~8 | Vector3 | 坐标(x\|y\|z) | #### 3.6:ActivityDialogInfoByStage(对话索引) | 字段 | 类型 | 说明 | |------|------|------| | StageID | int | 玩法关卡ID | | DialogConfigTable | string | 对应文本配置表名称 | #### 3.7:DialogInfo(对话详细配置) 行为树对应节点:`DoShowDialog(DialogInfoID)` | 字段 | 类型 | 说明 | |------|------|------| | id | int | 配置ID | | isMask | bool | 是否开启蒙层 | | MaskTarget | string | 蒙层位置(万分比坐标 x,y) | | ClickKey | int | 关闭蒙层键值 | | DialogType | int | 战中类型 | | UIType | int | UI样式 | | PrefabPath | string | UI预制体路径(默认空) | | Name | string | 显示角色名 | | Text | string | 正文(支持富文本) | | Duration | float | 显示时间 | | Params1~5 | string | 特殊参数1~5 | --- ### 5.4 嵌套节点示例(仅 GameplayNode) **CSV 数据:** ``` LevelID,NodeID,NodeLayer,...,ParentNodeID int,int,int,...,int (doc行) 1,100,0,...,-1 1,101,1,...,100 1,102,1,...,100 1,103,2,...,101 ``` **Canvas 连线结构:** ``` [NodeID:100](根节点,ParentNodeID=-1) ├── [NodeID:101](ParentNodeID=100) │ └── [NodeID:103](ParentNodeID=101) └── [NodeID:102](ParentNodeID=100) ``` --- ### 5.5 运行时自动同步(可选) 如需在运行时自动同步,将 `GraphExcelSyncManager` 组件挂到场景中的 GameObject 上: 1. **Add Component → GraphExcelSyncManager** 2. Inspector 中绑定 `Target Graph` 和 `Schema` 之后每�� Graph 触发序列化事件时会自动写入 CSV。 --- ## 6. 常见问题 | 问题 | 原因 | 解决方法 | |------|------|---------| | 导入后节点全部重叠 | 导入时节点默认位置为 Vector2.zero | 在 Canvas 中手动排布节点位置 | | CSV 用 Excel 打开乱码 | 编码不一致 | Excel → 数据 → 从文本/CSV 导入 → 选 UTF-8 | | 导入报错 "CSV file format invalid" | 缺少前3行表头 | 保留 NAME/TYPE/DOC 三行,数据从第4行开始 | | 点击导出提示"请选择 Graph" | Graph 拖槽为空 | Graph 拖槽必须赋值 | | 导入时提示"Unknown table name" | CSV 文件名不匹配 | 确保 CSV 文件名为标准表名(BehaviourTree.csv 等) | | 某个表导入失败 | 该表的 CSV 格式错误 | 检查前3行表头是否完整,数据行是否有缺失 | | 导出后找不到 CSV 文件 | 导出路径不对 | CSV 文件生成在 Assets/ 目录,刷新 Project 窗口 | | ParentNodeID 连线没有重建 | 只有 GameplayNode 支持嵌套 | 其他节点类型不支持父子关系 |