[muzzik 教程]:3.x 插件开发指南

# 前言

此贴作为成都 Star Meetings 活动的扩展贴,方便大家更好的阅读理解

1.为什么要开发插件?

  • 任何重复机械式的劳动都是无意义的,一切机械劳动皆可自动化,而插件能帮助我们实现自动化

2.插件能给我们带来什么?

  • 时间,解决了自动化的问题,最大的好处当然是节省了我们额外的手动操作时间,正所谓寸金难买寸光阴,节约时间便是插件最大的价值

  • 收益,插件在给我们自己带来好处的同时,也可以发布到cocos商店,给他人带来便利的过程中,也可以给自己带来额外的收益

  • 生态,unity的生态就不用说了吧,各种插件涵盖了方方面面,这都是插件开发者的功劳,我们的每个插件,都可以给 cocos 的生态添砖加瓦

  • 技术,插件开发包括但不限于HTML,CSS,NodeJs,Vue,可以帮我们拓展技术范围,增加个人竞争力

# 目录

  • 入门

    • 创建插件
    • package.json 简述
    • 插件多语言
    • 怎么通过消息启动插件面板
    • 插件面板的内容编写
    • 消息系统
    • 场景脚本
    • 配置系统
    • 插件编译
    • 发布插件
  • 进阶

    • 理解主进程和渲染进程
    • 使用 element-plus
    • html 和 css 调试技巧
    • 扩展 inspector
    • 插件公共代码库
    • 插件编译器
  • 深入

    • 使用 creator 制作插件 UI
    • 调试主进程代码
    • 代码加密的方式

# 入门

# 创建插件


我们可以从顶部菜单栏中打开 扩展/创建扩展 打开插件创建面板

# 创建插件 - 插件放在哪儿?


我们可以从顶部菜单栏中打开 扩展/扩展管理器 从找到我们的插件,点击 Open Folder 即可打开我们的插件根目录文件夹

# 创建插件 - 插件初始化

由于我们的插件可能一开始会依赖部分 npm 模块,所以需要初始化

  1. cd 插件根目录
  2. npm i

# package.json 简述

package.json 是一个在插件根目录内的文件,里面包含了很多信息,相当于插件的身份证,这里我们只说了最重要的三个配置

  • main 关系到插件能否正常启动
  • panels关系到面板能否正常展示
  • contributions 插件大部分的配置都在这里面

参考链接

# 插件多语言

在开发中我们经常使用多语言,插件多语言怎么使用的呢?其实是靠一个放在插件根目录的 i18n 文件夹来实现,文件里面存放的文件名是语言代号,内容则是一个导出的对象
image
image

参考链接

# 插件多语言 - 使用方式

  • 脚本中使用:let str = Editor.I18n.t(‘first-panel.open_panel’);
    注: 常用于动态展示的内容

  • HTML中使用:<ui-label value=“i18n:first-panel.open_panel”>
    注:常用于面板中

  • JSON 中使用中使用:“description”: “i18n:first-panel.description”,
    注:package.json 中使用

参考链接

# 怎么通过消息启动插件面板

首先我们要启动插件面板需要先注册一个菜单项,在 package.json 的 contributions.menu 里面,写入一个含有 path、label、message 属性的数据

这些内容代表了什么?

  • 菜单路径:path + label = 扩展/demo_part1/默认面板
  • 菜单点击触发的消息:message

# 怎么通过消息启动插件面板 - 怎么监听消息

image

我们可以在 package.json 文件中的 contributions.messages 中写入我们监听的消息名以及触发的方法数组
我们所有的事件都是在 messages 里面注册,这里的 open-panel 就是我们注册的事件,open_panel 是触发的方法名,由于没有指定面板名,所以触发的是 main 内的方法,接下来我们看看 open_panel 方法做了什么

参考链接

# 怎么通过消息启动插件面板 - 看看回调做了什么

在 open_panel 内我们调用了 Editor.Panel.open,这就是打开面板的方法

  • Editor.Panel.open:打开面板,参数为扩展名 | 扩展名.面板名

到这里点击菜单后我们的插件面板就打开了

# 插件面板的内容编写

首先是面板的一些基础属性,我们在 package.json 内的 contributions.panels 中定义

image

  • title:面板标题

  • type:dockable(可停靠) | simple(不可停靠)

  • main:面板入口脚本文件夹,文件名默认为 index.js

  • size:面板大小信息

# 插件面板的内容编写 - 面板展示内容控制

也就是在 index.js 文件中我们导出的对象,template 则为 html 内容,style 则为 css 内容

AW~_PVSGTYYDB(C82467XI4

这块涉及的内容比较深,大家下来可以自行了解

参考链接

# 消息系统

前面我们说了怎么监听一个消息,下面我们来看看怎么发送消息

发送消息一共有三个接口,发送,请求和广播

参考链接

# 消息系统 - 怎么查看默认定义的消息?

菜单 开发者/消息列表

# 消息系统 - 怎么调试消息?

消息管理器中的消息并不是编辑器全部存在的消息,那么怎么知道我们的操作触发了什么消息呢?那就是使用消息调试工具,菜单 开发者/消息调试工具

  1. 开始操作前点击播放按钮(扫把旁边的按钮)
  2. 操作结束后点击暂停按钮

这样我们就能看到这个操作触发的所有消息,包括消息的参数内容

# 场景脚本

场景脚本是什么?我们什么时候用到它?

简单的说场景脚本就是和编辑器内脚本运行的环境处于同一进程的脚本

我们在需要调用引擎接口的时候需要用到它,比如加载资源,获取节点等等…

参考链接

# 场景脚本 - 场景脚本在package.json中的定义

image

# 场景脚本 - 场景脚本结构

image

  • load:加载回调
  • unload:卸载回调
  • methods:场景脚本事件函数存放位置

# 场景脚本 - 和场景脚本通信

我们可以通过消息系统默认定义的消息进行通信

  • name:扩展名
  • method:触发的事件函数名
  • args:事件参数

参考链接

# 配置系统

配置系统是什么?
简单来说配置系统就是文件读写工具, 用于编辑器环境下的文件读写

我们可以无需任何前提条件在脚本内使用,但是大家注意,我们没有写文件之前首次获取的值一定是 undefined,那我们怎么配置默认值呢?

参考链接

# 插件编译

使用 ts 写插件自然需要将其编译为 js 才能使用,那么我们怎么编译 ts 脚本呢?市场上有很多第三方编译器,这里我们只说怎么通过 tsc(typescript 语言自带编译器)来进行编译

我们可以在命令行输入以下命令进行脚本编译

  • tsc -b [tsconfig所在目录]:单次编译
  • tsc -w [tsconfig所在目录]:监听编译(在 ts 文件保存后且有改动就会自动编译)

我们也可以配置脚本命令,在 vscode 内可以通过 ctrl + shift + p 来搜索并执行

# 发布插件

  1. 请仔细阅读发布 插件规范
  2. 确认无误后登陆 cocos开发者中心
  3. 点击商店 -> 卖家中心 -> 发布新资源
  4. 填写好后静待两三天审核时间,如有问题官方人员会联系你

参考链接

# 进阶

# 理解主进程和渲染进程

有可能大家接触插件开发的时候听说过主进程和渲染进程,但是并不了解,那么它们是什么呢?

  • 主进程:package.json 中 main 属性的脚本运行进程(插件入口脚本

  • 渲染进程:package.json 中 contributions.panels 中 main 属性的脚本运行进程(插件面板入口脚本

# 理解主进程和渲染进程 - 不同进程如何交互

  • 通过消息系统:最简单的方式
  • 通过 websocket:一般没人这样做

# 理解主进程和渲染进程 - 进程间使用误区

  • 进程间数据不是共享的,而是单独的
    注:这里经常犯的错就是认为自己使用的是同一份数据,其实是两份单独的数据,不同进程间的数据互不干扰

  • 不要把昂贵的计算逻辑放在主进程
    注:放在主进程会造成 creator 编辑器界面卡顿,最好放在插件渲染进程或者单独开个子进程

# 使用 element-plus

什么是 element-plus?element-plus 是一个 web 前端常用的 ui 组件库,creator 编辑器虽然也提供了一些插件 ui 组件,但是可能并不满足我们的需求,这时候就可以用 element-plus

参考链接

# html 和 css 调试技巧

插件开发时需要经常修改 html 与 css,又不想每次都要重新加载插件怎么办?

我们可以打开插件面板后点击插件面板,再按下 ctrl + shift + i 打开开发者工具,就可以在里面直接编辑 html 与 css 了,效果都是实时生效的,我们可以修改到预期效果再将其搬到插件源码内

image

# 扩展 inspector

inspector 是什么?简答的说就是属性检查器面板内组件展示的内容

怎么定义 inspector? 只需要在 package.json 中的 contributions 中声明即可

参考链接

# 扩展 inspector - 与组件数据的交互方式

inspector 自定义了我们的组件属性面板展示,那么怎么与组件数据交互呢?有两种方式

  • 场景脚本
    注:场景脚本可以通过 getScene 拿到场景根节点并以此找到我们的组件进行数据访问修改

  • 消息系统
    注:编辑器使用的方式,推荐使用此种方式,大家不知道消息内容可以通过消息调试器获得

为什么推荐使用消息来修改组件数据呢?因为编辑器会依赖这些消息,比如撤销操作

# 插件公共代码库

在插件开发过程中,我们可能会遇到几份插件都使用同一份代码的情况,这时候我们想要只保留一份公共代码,该怎么操作呢?

答案是 在插件根目录 tsconfig.include 中添加我们的公共代码库路径

但是这样会使用有个问题,插件编译后路径结构与之前不一致了

前:

  • @libs 目录
  • 插件目录
    • dist 目录
      • src 目录
    • src 目录

后:

  • @libs 目录
  • 插件目录
    • dist 目录
      • @libs 目录
      • 插件目录
        • src
    • src 目录

怎么解决呢?这里我写了小工具,插件编译器

# 插件编译器

npm 主页:https://www.npmjs.com/package/@muzzik/cc-plugin-cli

功能简介:

  • 自动修改 package,json 中因为引用公共代码库导致的路径不一致问题
  • 自动拷贝依赖的 npm 包到输出目录
  • 输出 zip

注意不要把输出目录设置为开发目录,否则会删除你的开发代码,代码开源,欢迎贡献代码

# 深入

# 使用 creator 制作插件 UI

看起来很复杂,实现起来很简单,大家别忘了,插件面板也是一个 web 界面,而 web 界面是可以嵌入的,而 creator 也可以输出 web 包,那么事情就很简单了

我们可以通过 iframe 标签嵌入指定网址链接,就可以实现插件面板展示 creator 界面

  • 调试时:嵌入预览网址
  • 发布时:本地开个 http-server,指向编译后的 web 包路径即可

image

# 调试主进程代码

开发中有可能遇到主进程报错,但是却无法调试的情况,那么我们怎么调试主进程呢?

  1. 设置 cocos dashboard 启动选项,path后为项目根目录
    _49PI2UM6W{RR5$)U(CDO0

  2. 打开 chrome://inspect/#devices 配置
    image

  3. 点击 Discover network targets 右侧的 configure 添加 localhost:5858

  4. 打开对应的项目,target 下会出现一个新的项,点击蓝色的 inspect,这时候我们就进入了主进程开发者工具,可以使用 ctrl + p 搜索自己插件的 main.js 进行调试

# 代码加密的方式

  • 逻辑放在服务器
    注:主要代码放在服务器,插件面板只负责展示,就算代码被偷也无所谓

  • 使用其他语言
    注:使用C、C++编译为 wasm,基本杜绝破解核心代码

  • 混淆
    注:只防君子不防小人

17赞

厉害呀,这么快就赶出文章了~

正在美化插件中,:pray:

mark 1 下

请问插件可以做到编写一个菜单的按钮,然后点击这个按钮,可以帮我执行一些命令行指令吗?比如我需要点击下这个按钮,然后帮我把插件文件夹里的某些文件复制到工程的其他目录下

当然可以,点击按钮触发事件,在回调里面使用 fs 模块进行文件操作就行了

如果你想要具体的代码,你可以问别人要

mark…