调用引擎 API 和项目脚本

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

  • 遍历场景中的节点,获取或改动数据

  • 调用项目中的其他脚本完成工作

注册场景脚本

首先在 pacakge.jsoncontributions 属性中添加 scene 字段,该字段的值是一个脚本文件的路径,相对于扩展包目录:

  1. {
  2. "name": "engine",
  3. "contributions": {
  4. "scene": {
  5. "script": "./scene.js"
  6. }
  7. }
  8. }

编写场景脚本

定义 scene.js 的方法如下:

  1. const { join } = require('path');
  2. // 加载 ‘cc’ 需要设置搜索路径
  3. module.paths.push(join(Editor.App.path, 'node_modules'));
  4. // 模块加载的时候触发的函数
  5. exports.load = function() {};
  6. // 模块卸载的时候触发的函数
  7. exports.unload = function() {};
  8. // 模块内定义的方法
  9. exports.methods = {
  10. log() {
  11. const { director } = require('cc');
  12. director.getScene();
  13. return {};
  14. },
  15. };

注意:由于升级了脚本系统,原本使用和项目脚本相同的模块引用机制的 cc.require 方法被弃用。

发送消息到 scene.js

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

  1. interface ExecuteSceneScriptMethodOptions {
  2. // Name of extension
  3. name: string;
  4. method: string;
  5. args: any[];
  6. }
  7. const options: ExecuteSceneScriptMethodOptions = {
  8. name: 'foobar',
  9. method: 'log',
  10. args: []
  11. };
  12. // result: {}
  13. const result = await Editor.Message.request('scene', 'execute-scene-script', options);

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

注意:返回的对象 result 则是 log 方法里 return 的对象。

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