3.创建-安装-运行插件

创建安装扩展

在编辑器的菜单栏中找到 扩展 -> 创建扩展 菜单,打开新建插件面板。
image

Cocos Creator 提供了 4 种扩展模板,用于快速创建一个新的扩展项目。

  • Blank:空扩展。
  • HTML Panel:基于 HTML 的扩展模板,并带有一个弹出面板。
  • Vue2.x Panel:基于 Vue2.x 的扩展模板,并带有一个弹出面板。
  • Vue3.x Panel:基于 Vue3.x 的扩展模板,并带有一个弹出面板。
    4种方式创建的插件只在技术上有差别,功能按需都是一致的。

image

插件创建后的位置:${你的项目地址}/extensions

这里选择创建一个空扩展作为示例。
创建完成后打开扩展管理器 -> 已安装扩展,就可以看到刚才创建的扩展。
image
新创建的扩展默认是未启用状态,点击启用按钮即可启用此扩展。

package.json

package.json是一个插件必要的配置文件,它用于描述扩展的用途。
只有完整定义了描述文件 package.json 后,编辑器才能知道这个扩展里定义的具体功能、加载入口等信息。
在package.json有相比重要的3个文件

  • main
  • panels
  • contributions
    新建空模版的package.json是没有panels的,这个后面再说。

打开上面创建的${你的项目地址}/extensions/插件/package.json
image

  • package_version:Number - 版本号数值
  • version:String - 版本号字符串,推荐使用 semver 格式管理你的包版本。
  • name:String - 定义了包的名字,包的名字是全局唯一的。命名规则请参考 选项说明。
  • description:Stirng - 扩展描述,用于简要介绍扩展关键特性、用途等信息,支持 i18n 多语言设置。
  • main:String - 入口程序文件,也决定了插件能不能正常启动
  • devDependencies:{} - 扩展依赖。如本示例中,扩展依赖的 NodeJS 版本为 18.17.1,依赖的 TypeScript 版本为 4.3.4。
  • author:String - 作者信息。
  • editor:String - 支持的 Cocos Creator 编辑器版本。
  • scripts:{} - 脚本编译相关命令。
  • contributions:object -对编辑器已有功能进行扩展的相关配置,大部分的插件功能配置都会在这里定义。示例中contributions分别有一个menu字段(对象数组)和一个messages字段
    • menu:[],注册菜单,并绑定消息
    • messages:[] - 注册编辑器消息,可以绑定一个或多个的扩展内定义的方法。
      关于这两个字段也是下面要说的定义菜单和消息

定义菜单和消息

自定义主菜单:

编辑器顶部有一栏主菜单,在package.json中的contributions字段中添加menu 对象,如示例,配置信息将会在编辑器的 "扩展" 菜单里新增一个 "i18n:blank-template-001.show_log" 菜单。
可以看到menu对象是一个数组,也就是说一个menu对象中可以添加多个“主菜单”
image
每个“主菜单”有3个必选字段,一个可选字段icon,默认创建的package.json中没有添加该字段。

  • path :类型 {string} ,填写格式为:[顶部已有菜单路径][/路径1][/路径2],以下写法都是合理的:
    如以下写法都是可以的。
    • i18n:menu.extension - 以扩展菜单作为父菜单
    • i18n:menu.extension/Hello World - 在扩展菜单中添加一个 Hello World 菜单项作为父菜单
    • MyMenu - 在顶部菜单栏添加一个 MyMenu 菜单作为父菜单
    • MyMenu/Hello World - 在顶部菜单栏添加一个 MyMenu,并再添加一个 Hello World 菜单项作为父菜单
      在顶部菜单栏中,预设的菜单有:
    • i18n:menu.project - “项目” 菜单
    • i18n:menu.node - “节点” 菜单
    • i18n:menu.panel - “面板” 菜单
    • i18n:menu.extension - “扩展” 菜单
    • i18n:menu.develop - “开发者” 菜单
  • label 类型 {string} 必填,菜单项目的名称,支持 i18n:key 语法。
  • message 类型 {string} 可选,菜单点击后触发的消息,此消息需要在 contributions.messsages 中先定义
  • icon 类型 {string} 可选。菜单图标相对路径,扩展使用的素材一般放在名为 static 的文件夹下面,如果不存在可以新建一个。

自定义消息

在自定义主菜单中的菜单对象有一个message属性,作为菜单点击后触发的消息。
那么这个触发的过程是怎样的呢?事件传递一般有注册监听->触发->回调的流程。
在 Cocos Creator 编辑器架构中,所有的交互都是通过消息通信实现的,插件的创建也不例外
menu中的要触发的消息需要在contributions.messsages中注册监听。

定义一条消息(监听消息)

只有在 package.json 文件的 contributions.messages 字段里定义过的消息才能被使用。
消息定义的结构如下:
image
test-messasge是消息名称。

  • public,类型 {string} 可选,是否对外显示这条消息,如果为 true,则会在 开发者->消息列表 面板显示这条消息的基本信息。
  • description,类型 {string} 可选,消息摘要信息,如果 public 为 true,则会在消息管理面板显示,支持 i18n:key 语法。
  • doc,类型 {string} 可选,消息文档说明,如果 public 为 true,则会在消息管理面板显示,支持 i18n:key 语法。这个文档使用 markdown 格式撰写并渲染。
  • methods,类型 {string[]} 可选,消息触发的方法队列。
    这是一个字符串数组,字符串为扩展或者面板上的方法(methods)。 如果是触发扩展主程序的方法,则直接定义 methodName,如果要触发扩展里定义的面板上的方法,则要填写panelName.methodName。
{
    "name": "hello-world",
    "panels": {
        "test-panel": {
            "title": "HelloWorld",
            "main": "./dist/panel/index.js"
        }
    },
    "contributions": {
        "messages": {
            "package-message": {
                "public": true,
                "description": "Test Message: send to extension main.js",
                "doc": "Unable to find inheritance data. Please check the specified source for any missing or incorrect information.\nLine breaks are also supported.\n- options {any}",
                "methods": [
                    "receiveMessage"
                ]
            },
            "panel-message": {
                "methods": [
                    "test-panel.receiveMessage"
                ]
            },
            "hello-world:ready": {
                "public": true,
                "description": "Test Broadcast Message"
            }
        }
    }
}

如上述代码中,package-message 将触发扩展主程序中的 receiveMessage 方法,panel-message 将触发 test-panel 面板中的 receiveMessage 方法

image
定义完消息后,需要在扩展主入口和面板入口里,增加一个 sendMessage 方法:

export const methods: { [key: string]: (...any: any) => any } = {
    receiveMessage() {
        console.log('Received a message');
    },
};

export function load() { }

export function unload() { }

触发函数(执行消息)

上面定义了两个消息,package-message 和 panel-message。
在需要时,可以通过消息系统的 API 触发这个消息监听器:

// 不需要返回值
Editor.Message.send('hello-world', 'panel-message');
// Or 需要等待数据返回
const result = await Editor.Message.request('hello-world', 'panel-message');

在创建的空模版中,messages字段中注册监听了“show-log”消息和showLog方法,触发时会直接调用主程序中的showLog方法,也就是menu中绑定的消息show-log。

关于更复杂的自定义消息后面会再补充。

这里为了方便测试,修改一下新增的扩展

"contributions": {
        "menu": [{
            "path": "Develop",
            "label": "test",
            "message": "log"
        }],
        "messages": {
            "log": {
                "methods": ["log"]
            }
        }
    }

安装依赖和编译构建

由于插件会依赖 Node.js 的第三方库,所以在启用扩展之前需要先在扩展目录下执行 npm install 安装依赖模块才能正常编译。
另外一般插件包括默认创建的插件都是基于 TypeScript,需需要执行 npm run build 编译后才能运行。
打开扩展包所在目录,执行以下命令:

# 安装依赖模块
npm install
# 构建
npm run build

image

运行插件

编辑器,点击顶部菜单栏中的 扩展 -> 扩展管理器 -> 项目,找到之前创建的扩展。点击扩展右侧的 refresh(刷新) 按钮,使上面的修改内容生效。
若扩展已生效,在 Cocos Creator 顶部菜单栏区域会出现一个 Develop 菜单,并带有一个 test 菜单项,如下图所示:
image

如果菜单没有刷新,需要关闭插件,刷新并重新打开。

点击test菜单发现没有响应,并且控制台打印说没有找到log方法。
image

还记得上面自定义消息中说的,在消息注册监听后,需要在入口中定义对应的方法。

入口程序 main.ts

每一个扩展都有一个唯一的入口程序 main.ts
在package.json中的字段为main,也是入口程序的相对路径,不过是编译后的main.js
默认创建的模版,main.ts在插件目录/source/main.ts
打开:

/**
 * @en Registration method for the main process of Extension
 * @zh 为扩展的主进程的注册方法
 */
export const methods: { [key: string]: (...any: any) => any } = {
    /**
     * @en A method that can be triggered by message
     * @zh 通过 message 触发的方法
     */
    showLog() {
        console.log('Hello World');
    },
};

/**
 * @en Method Triggered on Extension Startup
 * @zh 扩展启动时触发的方法
 */
export function load() { }

/**
 * @en Method triggered when uninstalling the extension
 * @zh 卸载扩展时触发的方法
 */
export function unload() { }

export const methods 中定义的方法,将会作为操作的接口,通过 消息系统 跨扩展调用,或者是和面板通信。

入口程序是扩展的主进程,会在 Cocos Creator 的启动过程中被加载。

菜单消息处理

默认创建的main.ts中的export const methods 中只有一个showLog方法,事实上这也是没修改contributions之前定义的方法。
可以删掉它,并定义一个在package.json的messages中注册的方法(也是menu中绑定的方法)
log,让它打印“赛利亚:你好啊?”

/**
 * @en Registration method for the main process of Extension
 * @zh 为扩展的主进程的注册方法
 */
export const methods: { [key: string]: (...any: any) => any } = {
    /**
     * @en A method that can be triggered by message
     * @zh 通过 message 触发的方法
     */
    log() {
        console.log('赛利亚:你好啊?');
    },
};

/**
 * @en Method Triggered on Extension Startup
 * @zh 扩展启动时触发的方法
 */
export function load() { }

/**
 * @en Method triggered when uninstalling the extension
 * @zh 卸载扩展时触发的方法
 */
export function unload() { }

保存 -> 编译 -> 刷新
image
可以看到控制台成功打印了内容。

posted @ 2025-06-16 22:39  EricShx  阅读(47)  评论(0)    收藏  举报