上周六我们的深圳第三期线下技术分享会圆满结束,现场大家也是热情高涨,气氛火热。这周我们收到最多的留言有两种:
第一种留言是:
现场 PPT 能公布吗?
—— 实话实说,现场 PPT 是讲师用于活动现场使用的,无法分享呢。
第二种留言是:
新晋美女讲师(严媛媛)讲得也太棒了,求详解!
—— 这不就来了嘛!
本篇将由媛媛为大家带来分享会讲稿详解:《编辑器插件&自定义构建流程》,带大家认识编辑器插件。因为各种原因不能到达现场的小伙伴,不要再错过了哦~
此外,本周五(10 月 23 日)19:30 放空老师将携编辑器大佬斯杰空降 B 站直播间喔,带来 Cocos Creator 3D 1.2 功能详解演示,以及引擎插件内容等等,欢迎大家前来围观喔,大佬们将在线答疑解惑!
以下为《编辑器插件 & 自定义构建流程》,欢迎结合文档配套食用喔!
Cocos Creator 3D 1.2 开始,编辑器正式对外开放了编辑器插件的功能。但其实在编辑器内部各个功能模块一早便是由编辑器插件的模式进行的,所以 1.2 之前也是支持编辑器插件的,只是一直内部使用,没有编写文档,如果对外需要进行一定程度上的归档整理甚至是部分优化重构。
在介绍如何开始编写一个编辑器插件之前,想先分享关于整个编辑器插件在编辑器里所处的位置以及基本的通讯结构。一些编辑器插件的老司机应该比较清楚, 编辑器是基于 Electron 开发的,而 Electron 本身又是基于 Chromium 和 Node.Js。也就是说编写插件时,这些 Electron 自带 api 和所有 node 接口你都可以随意调用。编辑器本身也在这个基础上封装了一层,提供了一些常用功能的接口,比如说 IPC 消息,配置系统,菜单,弹窗等等,这些方法都放在了全局变量 Editor 里,只要你熟悉这些方法,你甚至可以直接在编辑器控制台就调用这些方法来执行一些操作。虽然在编写一个功能的时候使用的 API 可能有很多选择,但是我们建议优先使用 Editor 封装的接口,这样才会和编辑器的表现更加一致。并且一旦编辑器升级了 Electron 版本,也会对这个接口的实现做升级,如果自己调用就只能自行升级了。想要了解编辑器使用的各个模块的版本号,直接在控制台输入 process.versions 即可,大家可以通过版本号去自行查找网上对应版本的模块文档。编辑器启动的流程实际上就是先实例化这些层封装好的 Editor 接口,再按照内部插件的启动顺序来依次启动插件,再接着按照插件管理器记录的各个用户插件的启动情况来依次启动插件,如果有同名插件将会被覆盖。平时打开编辑器应该都能看到一些 [Package] xxx@version enable 这类的 log 信息,其实就是插件启动后打印的 log。而插件启动便是根据插件包内 package.json 里指定的一些配置参数来注册对应功能,比如菜单、Ipc 消息、配置等等,启动之后就主要看插件本身写了什么样的逻辑了。图上红色虚线框起来的区域,就是插件作者需要去编写的部分,如果只是纯逻辑基本只需要在 main 字段启动脚本的对应生命周期里面编写即可,如果配置了面板,则在打开对应面板时,会加载面板入口的脚本,并执行内部的生命周期,界面显示部分和正常编写网页的处理是一致的。这里打开的每个窗口和浏览器窗口是类似的,每个窗口页一个独立的渲染进程,都可以单独打开当前窗口的 devtools。整个编辑器打开后,只有主进程和几个特殊 worker 进程是常驻的,其他面板的渲染进程都会随着窗口的打开关闭而产生对应的初始化与销毁动作,由于渲染进程随时可能被销毁,所以数据通常都是存储在主进程的,面板打开后通过向自己插件主进程发送 IPC 消息来获取数据。
绿色虚线区域是编辑器封装的接口模块,这部分的接口使用就需要大家去多看看文档了,上面提到的发送 IPC 消息的具体接口就是封装在 Editor.Message 对象内的。底下蓝色部分则是编辑器使用的框架本身带有的 API 接口,这部分接口直接网上看对应文档即可。你可能不需要精通 node 、Electron、HTML 标签,但需要知道编写某个功能的时候知道要往哪些方向查询,毕竟我们的目标是利用现有的 API 去做我们真正想要的功能,知道知识在哪里有时候比记住全部知识要重要。目前编辑器也给大家提供了一些快捷的创建编辑器插件模板的方式。有两种方式,创建普通插件包和构建插件包。如果你是想要快速上手,只需要在扩展那边新建一个插件包即可,这个插件包模板是用 js 编写的,可以很方便快速修改。如果想要编写构建插件,建议创建构建插件模块模板,因为这个项目里放置了一些接口定义,用的 ts 编写起来会更加顺手,tsc 监听编译也不会麻烦。这个版本的接口定义还比较简陋,后续我们会统一成一个插件模板,提供完整的接口定义。除了这种方式,也可以去直接下载网上的 zip 包来导入。接下来我们来讲解一下,拿到一个插件包模板后,需要如何的修改里面的内容。一个插件包,最少需要一个入口文件 package.json ,这有点类似 npm 包,一样是以包名作为唯一标识符,里面可以填写一些插件本身的介绍信息等等,这些信息将会显示在插件管理器上。main 字段允许传入一个脚本的相对路径,插件启动时就会执行 main 字段指向的 js 文件,并根据流程触发或执行对应的方法。如果你想要监听这个插件启动,禁用来做一些数据处理,可以参考文档在这里添加脚本入口,需要注意的是 main 脚本是主进程内执行的,如果修改需要重启插件才会生效。panels 就是这个插件想要配置的面板定义,每个插件允许指定多个面板窗口,每个面板配置里也会有一个 main 字段来指定入口脚本,内部同样有一套生命周期钩子。这里的 main 脚本就是在渲染进程里执行的,修改完重新打开窗口或者刷新窗口就会生效。contributions 目前是编辑器一些重要模块的扩展配置入口,这个字段和 vscode 插件是一样,除了以上提到的这些以外,其他功能的扩展都是放在这个字段下面的。这里的配置都是编辑器内置插件自行解析的,所以编写方式需要参考对应文档。这个字段也是为了将来插件生态庞大之时,一些插件定义自己扩展入口的一个规范。接下来就来看看编辑器目前支持了哪些重要模块的扩展:消息系统可以说是非常重要的一个模块了,前面有提到编辑器内各个窗口都是独立的进程,信息的交互都需要靠 IPC 来实现。消息有两种,一种是广播消息一种是定向消息,每个插件都可以对外公开 ipc 消息供各个插件使用,同样也可以去接受所有插件的广播消息。这些消息的公开与否和自身插件方法的绑定,就是在这里定义的,配置了公开的消息可以在消息列表里面看到方便开发者使用。配置系统是用来定义编辑器一些本地设置、项目设置这类数据。大家在打开游戏项目后,也会看到项目目录下会有一个 profiles 的文件夹,里面就是存储一些当前项目的本地配置。而项目设置的数据则是存储在 settings 内,默认跟随 git 的。当想要添加一些新的配置时,需要从这里添加定义,在定义好的基础上可以配合偏好设置、项目设置扩展方式来给数据添加界面 UI,除了添加定义,还能直接在这里添加配置被修改后的消息通知。这些字段允许插件开发者用一些简单的配置定义,来添加属于自己插件的偏好设置。有了这个功能意味着普通插件根本不需要接触任何 html 的内容就能给自己想开放的配置添加界面交互,并且偏好设置也会管理好所有数据同步交互的部分。项目设置也和偏好设置同理,不过这两个配置需要做好定义的区分。自定义构建的配置,在这里只留了一个路径入口定义。具体的配置,会在后面讲解到,主要是考虑到构建涉及的平台众多,用了入口脚本的方式方便一些配置的复用。这些配置,我这里只是做一个简单的介绍,带大家大概的了解有哪些扩展可用,具体还是需要自行参考文档。在知道了编辑器提供了哪些扩展后,大家就可以更加针对性的去看自己感兴趣和需要的部分。除了这些概念以外,还想向大家介绍一个我们内部开发插件时常用的一些辅助工具,其实就是编辑器主菜单 开发者里的这些选项。第一个要说的也是最重要就是这个开发者工具了,可以看到这里有是有多个选择的。第一个其实就是非常常见的国际通用快捷键,主要用来调试渲染进程代码。按下快捷键就会打开当前聚焦窗口的开发者工具。开发者工具能做什么事情,就不需要我来赘述了吧,前面有提到过的封装了各种接口的全局 Editor,有兴趣的盆友就算你不看文档,在这里打印看看不也能了解个大概。最下面这三个开发者工具,是用来调试一些特殊进程的,这三个进程是专门为对应功能开启的独立进程,差异点主要在于全局变量环境的差异,三个进程都有引擎接口可以调用。如果将来大家在编写的插件脚本运行在这些进程,也可以直接利用熟悉的引擎接口来写逻辑。再有就是刚刚提到消息扩展时有提到过的消息列表,可以看到这里其实有对 asset-db 详细的接口描述。当然了,只有在 package.json 里配置了公开的接口才能在这里看到。公开的接口意味着是插件开发者允许外部调用的,不公开的接口其实也有地方看到,就是下面这个消息调试工具,按下录制按钮就会讲有发送出去的消息都记录下来。
有些插件开发老司机们早期就是利用这个工具自行找到很多编辑器内部还没有公开的消息,来达到自己编写插件的目的。虽然我这里提到了这个工具,不过不公开的消息还是建议大家慎用的,除非你对这个提供消息的模块有一定程度上的了解。但是大家别用它来干什么坏事啊,不然说不准哪个版本这个工具就移除掉了。再有就是必须要提到的 UI 组件,这个我们平时开发也一直在用的,这个你不需要看文档,直接打开窗口,都有对应的代码示例。前面有提到过的偏好设置、项目设置的填写自动渲染配置,包括后续自定义构建参数的渲染配置,都是需要参考 UI 组件支持的属性来编写的。有了这些文档工具的助力,编写插件就不再是一个摸不着边的事儿。当然了,1.2 是编辑器插件面向大众的第一版,在基础建设上还不够完善,这个版本的编辑器插件主要为了给想要跃跃欲试的开发者们尝鲜,给确实有强烈业务需求的开发者们准备的。功能是可用的,但由于时间精力关系,确实没有那么完美,大家如果有去体验可以把遇到的问题尽快反馈给我们,这样 3.0 就能看到一个更加完善的编辑器插件体系。很多功能我们也很想做更多、做完美,比如之后也有计划添加类似 vscode 那种全局搜索的功能,事实上我们在确定整个插件系统注册规则时,就预留了这个处理方式,最常见的就是搜索某个消息后回车执行,这也是为什么 package.jSon 里的消息需要做定义的原因,就是为了能将所有的消息更方便的收集起来。大家可以畅想一下一个这样的编辑器,当你配置完各个平台的构建任务后,每次测试只需要搜索某个命令,回车就可以帮你省略了界面操作,忘记了某个配置在哪个面板也没事,直接搜索就出来了。再有就是提供官方的插件脚手架,目前我们给的模板确实还属于比较粗糙的阶段。理想情况下,最好是全部可用接口的 .d.ts 都能给到,并且提供大家一套现成可用的插件代码编译加密流程,让大家更加方便放心的去开发和共享插件。在即将到来的 3.0 我们也会把模板做成类似组 test case 那样既作为插件案例也作为对应测试例进入到我们的测试流程里,来保障功能的可用性。同时也会提供更多模块的扩展支持,比如自定义资源的全套工作流、场景 Gzimo 扩展等等,同时插件商城也正在准备接入当中。这些我们都有计划,还请大家相信我们,保持耐心。如果什么功能扩展确实非常紧急,可以在论坛告知我们,我们会根据实际的诉求情况去调整这些模块扩展的版本计划。以上这些就是插件系统想要介绍到的内容,本身我自己是负责构建这块内容,本来应该构建的篇幅放得更多,但是构建插件它本身也是一个编辑器插件,所以了解这些内容对于编写构建插件也是很有帮助的。讲了这么多插件系统提供的功能,接下来看看构建插件模块支持了哪些功能。主要是以下几点,一个是允许添加新的构建参数,并且会在对应的构建配置界面上显示方便修改,二是允许添加不同构建时期的回调函数来添加自定义的构建逻辑,同时构建进程自身也是在引擎环境下,意味着大家可以使用熟悉的引擎接口来编写一部分逻辑,构建进程也提供了 Build 这个封装了一些常用构建接口的全局变量。刚刚前面有提到过的构建在 package.json 里面的配置就是简单地添加 builder 字段写上入口配置脚本路径,所以重点在于这个配置入口脚本的编写。这个 js 需要导出一份以平台名作为 key 的配置对象,针对每个平台可以去添加对应的构建配置参数,这个 options 就是用来指定对应参数的默认值、显示文本,以及界面渲染规则的,这里的 render 字段就可以参考前面提到的 UI 组件面板来编写。添加的参数,在界面上修改后将会自动添加到构建 options 上,在后续的钩子函数里就能够访问到这些数据。hooks 就是填写这些钩子函数脚本入口的字段,之所以把这个字段设计成路径字符串,是因为 hooks 是和构建一起运行在单独的构建进程内,而当前这份入口脚本的解析则是在主进程。hooks 脚本写起来其实就是暴露了一些函数脚本的 js 模块,构建会在构建的不同阶段去调用这里的函数,并传递必要的构建参数进去。参数主要是 options 和 result,options 不用多说就能知道,就是平台构建界面填写的构建参数,里面也会包含前面注册进来的自定义构建参数。result 则是构建结果对象,也封装了一些常用的查询方法,方便查找一些构建后的信息,比如 settings,构建目录等。除了这些参数以外,还可以直接使用引擎的接口来处理,构建进程也有封装一个 Build 全局对象,里面包含了一些构建阶段常用方法,比如说简单的脚本编译,资源信息查询,uuid 压缩和解压缩的方法。大家可以自行在控制台打印查看。编写这些钩子函数,除了这些内容外,最重要的是需要知道钩子函数在整个构建流程所处的阶段。目前构建在三个大区域的前后提供了对应区域 before 和 after 的钩子,分别是整个构建阶段,构建实际文件阶段,压缩 settings 阶段。不同阶段的构建参数会有差异,比如构建就不会有 result 参数,构建资源阶段就不会有 settings 数据了。以上内容都是对整个插件注册流程的整体介绍,每个小系统深入下去都是一大块知识点,在一次分享内是不可能介绍清楚的。许多小伙伴也许也跃跃欲试,但是不知道这样的接口究竟能和怎样的实际需求案例结合起来。这里也给大家准备了一个可以思考实现的方向:webpack 有个插件叫做 webpack-bundle-analyzer ,可以用来分析包内脚本的资源占比以及依赖关系。类比过来,我们同样可以来设计一个用来分析编辑器构建后项目包的分析工具。可以因地制宜地,利用目前提供的一些消息接口,来实现分析 res 包后,直接点击对应资源就能在资源管理器里面闪烁高亮,同时也可以设计一个 settings 数据可视化的面板。编辑器插件目前确实还处于一个比较早期的阶段,但也正因为如此,它的未来才充满了无限可能。所有市面上成熟的开源插件设计都是目前编辑器插件可以去参考的点,只要你愿意,编辑器插件可以是任何形式,你甚至可以写一个编辑器插件来专门汇总所有的游戏文档链接,甚至是自己的作品集等等。在这里也想和大家分享一下知名技术演讲《A career in programming》中关于「为什么只有少数科学家才能在科学发展的进程中做出巨大的贡献,而其他很多科学家却在这个过程中逐渐被遗忘?」的观点,其中有一点就是:开放的思想和推销自己成果的能力(「我建议你在阅读一份期刊的时候想一想,为什么我能读到这些文章?」)。每一份宝贵的插件开发经验,都会成为编辑器插件系统生态繁荣的推动助力,希望能在论坛或者其他地方看到越来越多关于编辑器插件开发资料分享。https://docs.cocos.com/creator3d/manual/zh/editor/extension/readme.htmlhttps://docs.cocos.com/creator3d/manual/zh/editor/publish/custom-build-plugin.html
以上就是媛媛关于插件方面的分享,有任何使用问题,也欢迎到论坛上向我们反馈分享喔。最后,本周五(10 月 23 日)晚 19:30,Cocos 引擎组放空老师将携斯杰在 B 站开展直播,带来关于 Cocos Creator 3D 1.2 新功能演示、插件介绍等内容,欢迎各位开发者准时围观,也欢迎大家提前准备关于 Cocos 引擎想要问的问题,引擎组会在直播间里为大家解答噢!期待您的参与!
戳【阅读原文】或扫码提前收藏直播间,10 月 23 日晚 19:30,B 站直播间,不见不散哟!