在开发过程中,总少不了用到各类插件。Cocos Store 上提供了许多插件资源,但有时也需要我们自己动手去制作一些插件。本次,开发者 muzzik(马赛克)将分享 v3.x 插件开发流程与经验,一起来做插件吧!
Cocos Store 资源商店
首先,为什么要开发插件呢?
任何重复机械式的劳动都是无意义的,一切机械劳动皆可自动化,而插件能帮助我们实现自动化。
插件能给我们带来什么?
第一是时间。解决了自动化的问题,最大的好处当然是节省了我们额外的手动操作时间,正所谓寸金难买寸光阴,节约时间便是插件最大的价值。
其次是收益。我们可以把开发的插件发布到 Cocos 商店,给他人带来便利的过程中,也可以给自己带来额外的收益。
第三是生态。各类插件涵盖了开发的方方面面,将能帮助到更多开发者,我们的每个插件,都可以给 Cocos 的生态添砖加瓦。
第四是技术。插件开发所需要用到的技术包括但不限于 HTML、CSS、NodeJs、Vue,开发插件的同时,也可以帮我们拓展技术范围,增加个人竞争力。
本次,借这篇文章,我就从入门、进阶、深入三部分和大家分享一下开发 Cocos Creator 3.x 插件的流程,以及自己在实际开发中积累的经验,期待有更多的开发者加入到开发插件的行列中来!
PS. 限于篇幅,公众号仅展示正文部分,在论坛专贴中,我另附上了重点内容的参考与扩展链接,想做深入了解的小伙伴,可以直接前往论坛阅读:
https://forum.cocos.org/t/topic/144174
入门
1、创建插件
我们可以从顶部菜单栏中打开 扩展/创建扩展 打开插件创建面板。
插件放在哪儿?从顶部菜单栏中打开 扩展/扩展管理器 找到我们的插件,点击 Open Folder 即可打开我们的插件根目录文件夹。
由于我们的插件可能一开始会依赖部分 npm 模块,所以需要初始化:
-
cd 插件根目录。
-
npm i。
2、package.JSON 简述
package.json 是一个在插件根目录内的文件,里面包含了很多信息,相当于插件的身份证,其中最重要的三个配置是:
-
main:关系到插件能否正常启动。
-
panels:关系到面板能否正常展示。
-
contributions:插件大部分的配置都在这里面。
3、插件多语言
在开发中我们经常使用多语言,插件多语言怎么实现的呢?其实是靠一个放在插件根目录的 i18n 文件夹来实现,文件里面存放的文件名是语言代号,内容则是一个导出的对象。
插件多语言的基本使用方式是:
-
脚本中使用: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 中使用。
4、通过消息启动插件面板
首先我们要启动插件面板需要先注册一个菜单项,在 package.json 的 contributions.menu 里面,写入一个含有 path、label、message 属性的数据。
这些内容代表了什么?
-
菜单路径:path label = 扩展/demo_part1/默认面板。
-
菜单点击触发的消息:message。
监听消息
我们可以在 package.json 文件中的 contributions.messages 中写入我们监听的消息名以及触发的方法数组。
我们所有的事件都是在 messages 里面注册,这里的 open-panel 就是我们注册的事件,open_panel 是触发的方法名,由于没有指定面板名,所以触发的是 main 内的方法,接下来我们看看 open_panel 方法做了什么。
看看回调做了什么
在 open_panel 内我们调用了 Editor.Panel.open,这就是打开面板的方法。Editor.Panel.open 的参数为“扩展名 | 扩展名.面板名”。
到这里点击菜单后我们的插件面板就打开了。
5、插件面板的内容编写
首先是面板的一些基础属性,我们在 package.json 内的 contributions.panels 中定义:
-
title:面板标题。
-
type:dockable(可停靠) | simple(不可停靠)。
-
main:面板入口脚本文件夹,文件名默认为 index.js。
-
size:面板大小信息。
面板如何展示内容控制?在 index.js 文件中我们导出的对象,template 则为 html 内容,style 则为 css 内容。这块涉及的内容比较深,大家可以到论坛专贴查阅相关参考链接,做深入了解。
6、消息系统
前面我们说了怎么监听一个消息,下面我们来看看怎么发送消息。
发送消息一共有三个接口,发送、请求和广播,具体可参考官方文档。
查看默认定义的消息
打开菜单 开发者/消息列表 即可查看。
调试消息
消息管理器中的消息并不是编辑器全部存在的消息,那么怎么知道我们的操作触发了什么消息呢?就是使用消息调试工具,菜单 开发者/消息调试工具:
-
开始操作前点击播放按钮(扫把图标旁边的按钮)。
-
操作结束后点击暂停按钮。
这样我们就能看到这个操作触发的所有消息,包括消息的参数内容。
7、场景脚本
简单来说,场景脚本就是和编辑器内脚本运行的环境处于同一进程的脚本。我们在需要调用引擎接口的时候需要用到它,比如加载资源、获取节点等等。
场景脚本在 package.json 中的定义
场景脚本结构
-
load:加载回调。
-
unload:卸载回调。
-
methods:场景脚本事件函数存放位置。
和场景脚本通信
我们可以通过消息系统默认定义的消息进行通信:
-
name:扩展名。
-
method:触发的事件函数名。
-
args:事件参数。
8、配置系统
简单来说配置系统就是文件读写工具,用于编辑器环境下的文件读写。
我们可以无需任何前提条件在脚本内使用,但需要注意,我们没有写文件之前首次获取的值一定是 undefined。我们可以通过 package.json 来配置默认值。
9、插件编译
使用 ts 写插件自然需要将其编译为 js 才能使用。如何编译 ts 脚本呢?市场上有很多第三方编译器,这里我们选择通过 tsc(TypeScript 语言自带编译器)来进行编译。
我们可以在命令行输入以下命令进行脚本编译:
-
tsc -b [tsconfig 所在目录]:单次编译。
-
tsc -w [tsconfig 所在目录]:监听编译(在 ts 文件保存后且有改动就会自动编译)。
也可以配置脚本命令,在 vscode 内可以通过 ctrl shift p 来搜索并执行。
10、发布插件
插件开发完成后,我们就可以将其发布到 Cocos 商店了。发布前,建议大家先仔细阅读一下商店的插件类资源发布规范:
https://store.cocos.com/document/zh/cocos-store-template-extension.html
确认无误后登陆 Cocos 开发者中心:
https://auth.cocos.com/
点击商店 -> 卖家中心 -> 发布新资源。填写好后静待两三天审核时间,如有问题官方人员会联系你。
进阶
1、理解主进程和渲染进程
大家在接触插件开发的时候,可能有听说过主进程和渲染进程,但是并不太了解,那么它们是什么呢?
-
主进程:package.json 中 main 属性的脚本运行进程(插件入口脚本)。
-
渲染进程:package.json 中 contributions.panels 中 main 属性的脚本运行进程(插件面板入口脚本)。
不同进程如何交互
-
通过消息系统:最简单的方式。
-
通过 websocket:一般没人这样做。
进程间使用误区
-
进程间数据不是共享的,而是单独的。这里经常犯的错就是认为自己使用的是同一份数据,其实是两份单独的数据,不同进程间的数据互不干扰。
-
不要把昂贵的计算逻辑放在主进程。放在主进程会造成 Creator 编辑器界面卡顿,最好放在插件渲染进程或者单独开个子进程。
2、使用 element-plus
element-plus 是一个 web 前端常用的 UI 组件库,Cocos Creator 编辑器虽然也提供了一些插件 UI 组件,但是可能并不满足我们的需求,这时候就可以用 element-plus。
3、html 和 css 调试技巧
插件开发时需要经常修改 html 与 css,又不想每次都要重新加载插件怎么办?
我们可以打开插件面板后点击插件面板,再按下 ctrl shift i 打开开发者工具,就可以在里面直接编辑 html 与 css 了,效果都是实时生效的,我们可以修改到预期效果再将其搬到插件源码内。
4、扩展 inspector
inspector 简单地说就是属性检查器面板内组件展示的内容。怎么定义 inspector?只需要在 package.json 中的 contributions 中声明即可。
与组件数据交互
inspector 自定义了我们的组件属性面板展示,那么怎么与组件数据交互呢?有两种方式:
-
场景脚本。场景脚本可以通过 getScene 拿到场景根节点并以此找到我们的组件进行数据访问修改。
-
消息系统。编辑器使用的方式,推荐使用此种方式,大家不知道消息内容可以通过消息调试器获得。编辑器会依赖这些消息,比如撤销操作。
5、插件公共代码库
在插件开发过程中,我们可能会遇到几份插件都使用同一份代码的情况,这时候我们想要只保留一份公共代码,可以在插件根目录 tsconfig.include 中添加我们的公共代码库路径。
但是这样会使用有个问题,那就是插件编译后路径结构与之前不一致了。怎么解决呢?这里我写了一个小工具:插件编译器,可以自动修改 package.json 中因为引用公共代码库导致的路径不一致问题,自动拷贝依赖的 npm 包到输出目录,输出 zip。
插件编译器-下载与使用:
https://www.npmjs.com/package/@muzzik/cc-plugin-cli
深入
1、使用 Creator 制作插件 UI
看起来很复杂,实现起来其实并不难。插件面板也是一个 web 界面,而 web 界面是可以嵌入的,同时 Cocos Creator 也可以输出 web 包,那么事情就很简单了。
通过 iframe 标签嵌入指定网址链接,即可实现插件面板展示 Creator 界面:
-
调试时:嵌入预览网址。
-
发布时:本地开个 http-server,指向编译后的 web 包路径即可。
2、调试主进程代码
开发中有可能会遇到主进程报错,但是却无法调试的情况。那么我们该怎么调试主进程呢?
-
首先设置 Cocos Dashboard 启动选项,path 后为项目根目录:
-
然后打开 chrome://inspect/#devices 配置:
-
点击 Discover network targets 右侧的 configure 添加 localhost:5858。
-
最后打开对应的项目,target 下会出现一个新的项,点击蓝色的 inspect,这时候我们就进入了主进程开发者工具,可以使用 ctrl p 搜索自己插件的 main.js 进行调试:
3、代码加密的方式
-
逻辑放在服务器。主要代码放在服务器,插件面板只负责展示,就算代码被偷也无所谓。
-
使用其他语言。使用 C、C 编译为 wasm,基本杜绝破解核心代码。
-
混淆。此方法,只防君子不防小人。
以上就是本次分享的全部内容,希望对大家有所帮助!最后推荐几款我发布在 Cocos Store 上的插件和源码,感兴趣的小伙伴可自行下载取用。
SDF 纹理生成工具:
https://store.cocos.com/app/detail/3776
根据节点名生成节点引用代码插件:
https://store.cocos.com/app/detail/3998
编辑器菜单扩展(插件使用):
https://store.cocos.com/app/detail/2571