Cocos Creator 蓝图编辑器
本文档介绍如何在 Cocos Creator 项目中安装和使用蓝图可视化脚本编辑器扩展。
1. 下载扩展
Section titled “1. 下载扩展”从发布页面下载 cocos-node-editor.zip 扩展包。
2. 导入扩展
Section titled “2. 导入扩展”- 打开 Cocos Creator
- 进入 扩展 → 扩展管理器
- 点击 导入扩展包 按钮
- 选择下载的
cocos-node-editor.zip文件 - 导入后启用扩展
打开蓝图编辑器
Section titled “打开蓝图编辑器”通过菜单 面板 → Node Editor 打开蓝图编辑器面板。
首次打开 - 安装依赖
Section titled “首次打开 - 安装依赖”首次打开面板时,插件会检测项目中是否安装了 @esengine/blueprint 依赖包。如果未安装,会显示 “缺少必要的依赖包” 提示,点击 “安装依赖” 按钮即可自动安装。
| 按钮 | 快捷键 | 功能 |
|---|---|---|
| 新建 | - | 创建空白蓝图 |
| 加载 | - | 从文件加载蓝图 |
| 保存 | Ctrl+S | 保存蓝图到文件 |
| 撤销 | Ctrl+Z | 撤销上一步操作 |
| 重做 | Ctrl+Shift+Z | 重做操作 |
| 剪切 | Ctrl+X | 剪切选中节点 |
| 复制 | Ctrl+C | 复制选中节点 |
| 粘贴 | Ctrl+V | 粘贴节点 |
| 删除 | Delete | 删除选中项 |
| 重新扫描 | - | 重新扫描项目中的蓝图节点 |
- 右键单击画布:打开节点添加菜单
- 拖拽节点:移动节点位置
- 点击节点:选中节点
- Ctrl+点击:多选节点
- 拖拽引脚到引脚:创建连接
- 滚轮:缩放画布
- 中键拖拽:平移画布
右键单击画布后会显示节点菜单:
- 顶部搜索框可以快速搜索节点
- 节点按类别分组显示
- 按
Enter快速添加第一个搜索结果 - 按
Esc关闭菜单
蓝图文件格式
Section titled “蓝图文件格式”蓝图保存为 .blueprint.json 文件,格式与运行时完全兼容:
{ "version": 1, "type": "blueprint", "metadata": { "name": "My Blueprint", "createdAt": 1704307200000, "modifiedAt": 1704307200000 }, "variables": [], "nodes": [ { "id": "node-1", "type": "PrintString", "position": { "x": 100, "y": 200 }, "data": {} } ], "connections": [ { "id": "conn-1", "fromNodeId": "node-1", "fromPin": "exec", "toNodeId": "node-2", "toPin": "exec" } ]}在游戏中运行蓝图
Section titled “在游戏中运行蓝图”@esengine/blueprint 包已提供完整的 ECS 集成,包括 BlueprintComponent 和 BlueprintSystem,可以直接使用。
1. 添加蓝图系统到场景
Section titled “1. 添加蓝图系统到场景”import { BlueprintSystem } from '@esengine/blueprint';
// 在场景初始化时添加蓝图系统scene.addSystem(new BlueprintSystem());2. 加载蓝图并添加到实体
Section titled “2. 加载蓝图并添加到实体”import { resources, JsonAsset } from 'cc';import { BlueprintComponent, validateBlueprintAsset, BlueprintAsset } from '@esengine/blueprint';
// 加载蓝图资产async function loadBlueprint(path: string): Promise<BlueprintAsset | null> { return new Promise((resolve) => { resources.load(path, JsonAsset, (err, asset) => { if (err || !asset) { console.error('Failed to load blueprint:', err); resolve(null); return; }
const data = asset.json; if (validateBlueprintAsset(data)) { resolve(data as BlueprintAsset); } else { console.error('Invalid blueprint format'); resolve(null); } }); });}
// 创建带蓝图的实体async function createBlueprintEntity(scene: IScene, blueprintPath: string): Promise<Entity> { const entity = scene.createEntity('BlueprintEntity');
const bpComponent = entity.addComponent(BlueprintComponent); bpComponent.blueprintPath = blueprintPath; bpComponent.blueprintAsset = await loadBlueprint(blueprintPath);
return entity;}BlueprintComponent 属性
Section titled “BlueprintComponent 属性”| 属性 | 类型 | 说明 |
|---|---|---|
blueprintAsset | BlueprintAsset | null | 蓝图资产数据 |
blueprintPath | string | 蓝图资产路径(用于序列化) |
autoStart | boolean | 是否自动开始执行(默认 true) |
debug | boolean | 是否启用调试模式 |
BlueprintComponent 方法
Section titled “BlueprintComponent 方法”| 方法 | 说明 |
|---|---|
start() | 手动开始执行蓝图 |
stop() | 停止蓝图执行 |
cleanup() | 清理蓝图资源 |
创建自定义节点
Section titled “创建自定义节点”使用装饰器标记组件
Section titled “使用装饰器标记组件”推荐使用装饰器让组件自动生成蓝图节点:
import { Component, ECSComponent } from '@esengine/ecs-framework';import { BlueprintExpose, BlueprintProperty, BlueprintMethod } from '@esengine/blueprint';
@ECSComponent('Health')@BlueprintExpose({ displayName: '生命值组件' })export class HealthComponent extends Component { @BlueprintProperty({ displayName: '当前生命值', category: 'number' }) current: number = 100;
@BlueprintProperty({ displayName: '最大生命值', category: 'number' }) max: number = 100;
@BlueprintMethod({ displayName: '治疗', isExec: true }) heal(amount: number): void { this.current = Math.min(this.current + amount, this.max); }
@BlueprintMethod({ displayName: '受伤', isExec: true }) takeDamage(amount: number): void { this.current = Math.max(this.current - amount, 0); }
@BlueprintMethod({ displayName: '是否死亡' }) isDead(): boolean { return this.current <= 0; }}注册组件节点
Section titled “注册组件节点”import { registerAllComponentNodes } from '@esengine/blueprint';
// 在应用启动时注册所有标记的组件registerAllComponentNodes();手动定义节点(高级)
Section titled “手动定义节点(高级)”如需完全自定义节点逻辑:
import { BlueprintNodeTemplate, INodeExecutor, RegisterNode, ExecutionContext, ExecutionResult} from '@esengine/blueprint';
const MyNodeTemplate: BlueprintNodeTemplate = { type: 'MyCustomNode', title: '我的自定义节点', category: 'custom', description: '自定义节点示例', inputs: [ { name: 'exec', type: 'exec', direction: 'input', isExec: true }, { name: 'value', type: 'number', direction: 'input', defaultValue: 0 } ], outputs: [ { name: 'exec', type: 'exec', direction: 'output', isExec: true }, { name: 'result', type: 'number', direction: 'output' } ]};
@RegisterNode(MyNodeTemplate)class MyNodeExecutor implements INodeExecutor { execute(node: BlueprintNode, context: ExecutionContext): ExecutionResult { const value = context.getInput<number>(node.id, 'value'); return { outputs: { result: value * 2 }, nextExec: 'exec' }; }}| 类别 | 说明 | 颜色 |
|---|---|---|
event | 事件节点 | 红色 |
flow | 流程控制 | 灰色 |
entity | 实体操作 | 蓝色 |
component | 组件访问 | 青色 |
math | 数学运算 | 绿色 |
logic | 逻辑运算 | 红色 |
variable | 变量访问 | 紫色 |
time | 时间工具 | 青色 |
debug | 调试工具 | 灰色 |
custom | 自定义节点 | 蓝灰色 |
-
文件组织
- 将蓝图文件放在
assets/blueprints/目录下 - 使用有意义的文件名,如
player-controller.blueprint.json
- 将蓝图文件放在
-
组件设计
- 使用
@BlueprintExpose标记需要暴露给蓝图的组件 - 为属性和方法提供清晰的
displayName - 将执行方法标记为
isExec: true
- 使用
-
性能考虑
- 避免在 Tick 事件中执行重计算
- 使用变量缓存中间结果
- 纯函数节点会自动缓存输出
-
调试技巧
- 使用 Print 节点输出中间值
- 启用
vm.debug = true查看执行日志
Q: 节点菜单是空的?
Section titled “Q: 节点菜单是空的?”A: 点击 重新扫描 按钮扫描项目中的蓝图节点类。确保已调用 registerAllComponentNodes()。
Q: 蓝图不执行?
Section titled “Q: 蓝图不执行?”A: 检查:
- 实体是否添加了
BlueprintComponent BlueprintExecutionSystem是否注册到场景blueprintAsset是否正确加载autoStart是否为true
Q: 如何触发自定义事件?
Section titled “Q: 如何触发自定义事件?”A: 通过 VM 触发:
const bp = entity.getComponent(BlueprintComponent);bp.vm?.triggerCustomEvent('OnPickup', { item: itemEntity });