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 菜单项
image
image
可以看到示例面板被打开.
在该示例中,通过 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 菜单项
image
image

报错了,根据堆栈检查一下代码
发现在first panel插件中注册的消息名称是open-panel,修改一下菜单插件中打开面板的实现

Editor.Message.send('first-panel', 'open-panel');

保存->编译->刷新,然后再次点击 Develop -> HelloWorld -> open other 菜单项
image

可以看到 first-panel 的默认面板被打开了

广播通信

当一个扩展想要向整个系统所有扩展通知某个事件完成的时候,可以通过API

Editor.Message.broadcast(message:string, ...args:any[])

接下来以以上两个插件为例,我们在面板插件中广播消息,在菜单插件中监听消息并打印收到消息的log(当然发送方也可以监听自己广播的消息,但通常来说没有必要)。

  • 先注册监听
    打开菜单插件的package.json注册一个first-panel:open的消息,并绑定一个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"]
    			}
    		}
    	}
    }
    
    
    打开main.ts实现方法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方法中加入广播消息的实现
image
ready 函数会在 面板启动时调用,此时会对 first-panel:open 消息进行广播。
保存->分别编译并刷新两个扩展,再次点击 Develop -> HelloWorld -> open other 菜单项.
image

可以看到,不仅默认面板被打开,还在控制台打印出了广播信息。

posted @ 2025-06-17 00:54  EricShx  阅读(32)  评论(0)    收藏  举报