调用引擎 API 和项目脚本

在插件中可以声明一个特殊的脚本文件(场景脚本),该脚本和项目中的脚本 (assets 目录下的脚本)具有相同的环境,也就是说在这个脚本里可以调用引擎 API 和其他项目脚本,实现:

  • 遍历场景中的节点,获取或改动数据
  • 调用项目中的其他脚本完成工作

注册场景脚本

首先在 package.json 里添加 scene-script 字段,该字段的值是一个脚本文件的路径,相对于扩展包目录:

  1. {
  2. "name": "my-plugin-name",
  3. "scene-script": "scene-walker.js"
  4. }

该路径将指向 packages/foobar/scene-walker.js,接下来我们看看如何编写场景脚本。

编写场景脚本

scene-walker.js 需要用这样的形式定义:

  1. module.exports = {
  2. 'get-canvas-children': function (event) {
  3. var canvas = cc.find('Canvas');
  4. Editor.log('children length : ' + canvas.children.length);
  5. if (event.reply) {
  6. event.reply(null, canvas.children.length);
  7. }
  8. }
  9. };

可以看到场景脚本由一个或多个 IPC 消息监听方法组成,收到相应的 IPC 消息后,我们在函数体内可以使用包括全部引擎 API 和用户组件脚本里声明的方法和属性。

从扩展包中向场景脚本发送消息

接下来在扩展包程序的主进程和渲染进程中,都可以使用下面的接口来向 scene-walker.js 发送消息(假设扩展包名是 foobar):

  1. Editor.Scene.callSceneScript('foobar', 'get-canvas-children', function (err, length) {
  2. console.log(`get-canvas-children callback : length - ${length}`);
  3. });

这样就可以在扩展包中获取到场景里的 Canvas 根节点有多少子节点,当然还可以用来对场景节点进行更多的查询和操作。

在发送消息时 callSceneScript 接受的参数输入和其他 IPC 消息发送接口一致,也可以指定更多传参和 timeout 超时时限。详情请看 IPC 工作流程

注意: 由于通讯基于 Electron 的底层 IPC 实现,所以切记传输的数据不可以包含原生对象,否则可能导致进程崩溃或者内存暴涨。推荐只传输纯 JSON 对象。

在场景脚本中引用模块和插件脚本

除了通过 cc.find 在场景脚本中获取特定节点,并操作该节点和挂载的组件以外,我们还可以引用项目中的非组件模块,或者通过全局变量访问插件脚本。

引用模块

  1. //MyModule.js
  2. module.exports = {
  3. init: function () {
  4. //do initialization work
  5. }
  6. }
  7. //scene-walker.js
  8. module.exports = {
  9. 'init-module': function (event) {
  10. var myModule = cc.require('MyModule');
  11. myModule.init();
  12. }
  13. };

注意,要使用和项目脚本相同的模块引用机制,在场景脚本里必须使用 cc.require 的写法。

引用插件脚本

直接使用 window.globalVar 来访问插件脚本里声明的全局变量和方法即可。