5.插件间的通信
插件间的通信也是通过消息的监听/触发来实现的。
打开另一个扩展的面板
在实际需求中,有时候我们需要在自己写的扩展中打开另一个扩展,就需要通过消息系统来实现。
接下来以前面创建的菜单扩展为例,让它可以打开之前创建的面板插件。
修改菜单插件的package.json
按照需求,我们在消息字段中注册一个“open-other”的消息,并绑定一个openOther的方法,然后在main.ts 里定义 openOther 函数处理此消息。
同时在menu中新增一个菜单项open other,绑定在messages中注册的open-other消息。
考虑到操作ui的简洁和组织性,把之前的test菜单和新增的open other菜单都放在Develop/HelloWorld菜单下
修改后的菜单插件的package.json如下:
{
"$schema": "./@types/schema/package/index.json",
"package_version": 2,
"name": "blank-template-001",
"version": "1.0.0",
"author": "Cocos Creator",
"editor": ">=3.8.5",
"scripts": {
"preinstall": "node ./scripts/preinstall.js",
"build": "tsc",
"watch": "tsc -w"
},
"description": "i18n:blank-template-001.description",
"main": "./dist/main.js",
"devDependencies": {
"@cocos/creator-types": "^3.8.5",
"@types/node": "^18.17.1",
"typescript": "^4.3.4"
},
"contributions": {
"menu": [
{
"path": "Develop/HelloWorld",
"label": "test",
"message": "log"
},
{
"path": "Develop/HelloWorld",
"label": "open other",
"message": "open-other"
}
],
"messages": {
"log": {
"methods": ["log"]
},
"open-other": {
"methods": ["openOther"]
}
}
}
}
面板插件 中的扩展名为 first-panel,因此我们使用 Editor.Panel.open('扩展名')API 来打开它的默认面板。
打开菜单插件的入口源码文件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 触发的方法
*/
log() {
console.log('赛利亚:你好啊?');
},
openOther() {
Editor.Panel.open('first-panel');
}
};
/**
* @en Method Triggered on Extension Startup
* @zh 扩展启动时触发的方法
*/
export function load() { }
/**
* @en Method triggered when uninstalling the extension
* @zh 卸载扩展时触发的方法
*/
export function unload() { }
保存->编译->刷新->点击 Develop -> HelloWorld -> open other 菜单项


可以看到示例面板被打开.
在该示例中,通过 Editor.Panel.open('扩展名') 来打开 first-panel 的面板,但是如果想要做其他操作,这种方案就不行了。
这也是接下来要说的,与其他扩展通信
与其他扩展通信
与其他扩展通信的方式有两种:定向通信 && 广播通信(全局通信)
定向通信
如果一个扩展想要调用另一个扩展的功能时,可以通过
Editor.Message.send(extensionName:string,messasge:string,...args:any[])
向某个扩展发送消息(前提是已经注册了该消息)。
在CocosCreator中,每一个扩展的 contributions.messages 中定义的消息,默认都是可以对外的,也就是说默认可以接收(绑定)所有消息名相同的消息。
由于上面的菜单插件案例中已经注册了open-panel消息,而且定义了 openOther 函数,这里只需要修改一下openOther函数的实现(让它发送在面板插件中注册的打开面板的消息)。
/**
* @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('赛利亚:你好啊?');
},
openOther() {
//Editor.Panel.open('first-panel');
Editor.Message.send('first-panel', 'other-panel');
}
};
/**
* @en Method Triggered on Extension Startup
* @zh 扩展启动时触发的方法
*/
export function load() { }
/**
* @en Method triggered when uninstalling the extension
* @zh 卸载扩展时触发的方法
*/
export function unload() { }
Editor.Message.send的第一个参数是插件名,第二个参数是触发消息的名称,【可选】参数
保存->编译->刷新,然后再次点击 Develop -> HelloWorld -> open other 菜单项


报错了,根据堆栈检查一下代码
发现在first panel插件中注册的消息名称是open-panel,修改一下菜单插件中打开面板的实现
Editor.Message.send('first-panel', 'open-panel');
保存->编译->刷新,然后再次点击 Develop -> HelloWorld -> open other 菜单项

可以看到 first-panel 的默认面板被打开了
广播通信
当一个扩展想要向整个系统所有扩展通知某个事件完成的时候,可以通过API
Editor.Message.broadcast(message:string, ...args:any[])
接下来以以上两个插件为例,我们在面板插件中广播消息,在菜单插件中监听消息并打印收到消息的log(当然发送方也可以监听自己广播的消息,但通常来说没有必要)。
- 先注册监听
打开菜单插件的package.json注册一个first-panel:open的消息,并绑定一个onFirstPanelOpen的方法用来打印消息
打开main.ts实现方法onFirstPanelOpen{ "$schema": "./@types/schema/package/index.json", "package_version": 2, "name": "blank-template-001", "version": "1.0.0", "author": "Cocos Creator", "editor": ">=3.8.5", "scripts": { "preinstall": "node ./scripts/preinstall.js", "build": "tsc", "watch": "tsc -w" }, "description": "i18n:blank-template-001.description", "main": "./dist/main.js", "devDependencies": { "@cocos/creator-types": "^3.8.5", "@types/node": "^18.17.1", "typescript": "^4.3.4" }, "contributions": { "menu": [ { "path": "Develop/HelloWorld", "label": "test", "message": "log" }, { "path": "Develop/HelloWorld", "label": "open other", "message": "open-other" } ], "messages": { "log": { "methods": ["log"] }, "open-other": { "methods": ["openOther"] }, "first-panel:open": { "methods": ["onFirstPanelOpen"] } } } }/** * @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('赛利亚:你好啊?'); }, openOther() { //Editor.Panel.open('first-panel'); Editor.Message.send('first-panel', 'open-panel'); }, openFirstPanel() { console.log('first-panel knows is open'); } }; /** * @en Method Triggered on Extension Startup * @zh 扩展启动时触发的方法 */ export function load() { } /** * @en Method triggered when uninstalling the extension * @zh 卸载扩展时触发的方法 */ export function unload() { }
接下来打开面板插件的面板入口源码index.ts
在ready方法中加入广播消息的实现

ready 函数会在 面板启动时调用,此时会对 first-panel:open 消息进行广播。
保存->分别编译并刷新两个扩展,再次点击 Develop -> HelloWorld -> open other 菜单项.

可以看到,不仅默认面板被打开,还在控制台打印出了广播信息。
浙公网安备 33010602011771号