跳转到内容

Cocos Creator 蓝图编辑器

本文档介绍如何在 Cocos Creator 项目中安装和使用蓝图可视化脚本编辑器扩展。

从发布页面下载 cocos-node-editor.zip 扩展包。

  1. 打开 Cocos Creator
  2. 进入 扩展 → 扩展管理器
  3. 点击 导入扩展包 按钮
  4. 选择下载的 cocos-node-editor.zip 文件
  5. 导入后启用扩展

通过菜单 面板 → Node Editor 打开蓝图编辑器面板。

首次打开面板时,插件会检测项目中是否安装了 @esengine/blueprint 依赖包。如果未安装,会显示 “缺少必要的依赖包” 提示,点击 “安装依赖” 按钮即可自动安装。

按钮快捷键功能
新建-创建空白蓝图
加载-从文件加载蓝图
保存Ctrl+S保存蓝图到文件
撤销Ctrl+Z撤销上一步操作
重做Ctrl+Shift+Z重做操作
剪切Ctrl+X剪切选中节点
复制Ctrl+C复制选中节点
粘贴Ctrl+V粘贴节点
删除Delete删除选中项
重新扫描-重新扫描项目中的蓝图节点
  • 右键单击画布:打开节点添加菜单
  • 拖拽节点:移动节点位置
  • 点击节点:选中节点
  • Ctrl+点击:多选节点
  • 拖拽引脚到引脚:创建连接
  • 滚轮:缩放画布
  • 中键拖拽:平移画布

右键单击画布后会显示节点菜单:

  • 顶部搜索框可以快速搜索节点
  • 节点按类别分组显示
  • Enter 快速添加第一个搜索结果
  • Esc 关闭菜单

蓝图保存为 .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"
}
]
}

@esengine/blueprint 包已提供完整的 ECS 集成,包括 BlueprintComponentBlueprintSystem,可以直接使用。

import { BlueprintSystem } from '@esengine/blueprint';
// 在场景初始化时添加蓝图系统
scene.addSystem(new BlueprintSystem());
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;
}
属性类型说明
blueprintAssetBlueprintAsset | null蓝图资产数据
blueprintPathstring蓝图资产路径(用于序列化)
autoStartboolean是否自动开始执行(默认 true
debugboolean是否启用调试模式
方法说明
start()手动开始执行蓝图
stop()停止蓝图执行
cleanup()清理蓝图资源

推荐使用装饰器让组件自动生成蓝图节点:

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;
}
}
import { registerAllComponentNodes } from '@esengine/blueprint';
// 在应用启动时注册所有标记的组件
registerAllComponentNodes();

如需完全自定义节点逻辑:

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自定义节点蓝灰色
  1. 文件组织

    • 将蓝图文件放在 assets/blueprints/ 目录下
    • 使用有意义的文件名,如 player-controller.blueprint.json
  2. 组件设计

    • 使用 @BlueprintExpose 标记需要暴露给蓝图的组件
    • 为属性和方法提供清晰的 displayName
    • 将执行方法标记为 isExec: true
  3. 性能考虑

    • 避免在 Tick 事件中执行重计算
    • 使用变量缓存中间结果
    • 纯函数节点会自动缓存输出
  4. 调试技巧

    • 使用 Print 节点输出中间值
    • 启用 vm.debug = true 查看执行日志

A: 点击 重新扫描 按钮扫描项目中的蓝图节点类。确保已调用 registerAllComponentNodes()

A: 检查:

  1. 实体是否添加了 BlueprintComponent
  2. BlueprintExecutionSystem 是否注册到场景
  3. blueprintAsset 是否正确加载
  4. autoStart 是否为 true

A: 通过 VM 触发:

const bp = entity.getComponent(BlueprintComponent);
bp.vm?.triggerCustomEvent('OnPickup', { item: itemEntity });