查看原文
其他

开发属于你的第一款 Cocos Creator 3D 插件

许彦峰 COCOS 2022-06-10

Cocos Creator 3D 插件系列教程是由大家熟悉的 Cocos 「插件小王子」许彦峰策划良久的新课程。作者从个人角度,阐述了其对新插件体系从零入门的全新理解,部分教程附带简洁明了的代码说明。

查看本文前,先温习一下 Cocos Creator 3D 插件教程(一)的内容吧!


添加面板


有时我们的插件需要 UI 面板,进行一些简单的人机交互,使插件的使用更加简单、方便。
那么在 Cocos Creator 3D 插件中,如何添加 UI 面板呢?

1.配置插件 UI 面板

如下所示,修改package.json文件,插件的所有面板,都是在panels字段定义:
{
     // ...
   "panels": {
    "default": {
      "title""UI面板",
      "type""dockable",
      "main""./panel.js"
    }
  }
}
  • type:定义了插件面板类型,dockable 类型就是可悬浮停靠,Cocos Creator 3D 编辑器内置的面板就是这种类型。
  • main:UI面板的逻辑入口。

2.给 UI 面板添加打开入口

在第一步中,已经定义了一个 UI 面板,我们需要提供一个打开面板的入口,还记得之前的插件菜单么?
  • package.json增加一个打开面板菜单:
{
  // ...
  "main""./main.js",
    "contributions": {
        "menu": [
      // ...
      {
        "path""插件",
        "label""打开面板",
        "message""openPanel"
      }
    ],
    "messages":{
      // ...
      "openPanel": {
        "methods": [
          "openPanel"
        ]
      }
    }
    }
}
  • main.js中实现openPanel消息,通过调用Editor.Panel.open("插件名字.面板名字")接口来打开面板:
exports.methods={
        // ...
      openPanel () {
        Editor.Panel.open('hello-world');
    }
}
Editor.Panel.open('hello-world'),默认会打开配置的"default"面板。
如果要打开配置的其他面板,比如配置了"game"面板,需要Editor.Panel.open("hello-world.game")来打开"game"面板。

3. 编辑器中测试下

回到编辑器中,和之前一样,我们需要在扩展面板重启启用下插件(必要情况下,可能得重启下编辑器)。
我们点击菜单栏的插件/打开面板
编辑器就会打开一个新的面板

我们也可以将该 UI 面板拖拽到编辑器主窗口中:

请注意拖拽部位,拖拽的不是窗口的标题栏,而是窗口内的 tap 栏,也就是"UI 面板"的部位
现在我们插件的 UI 面板中还没有任何 UI 元素,接下来,就让我们给界面添加一些按钮、文本吧

添加 UI


一般 UI 都会有按钮、输入框,那么我们如何给面板添加一些元素呢?
我们再熟悉下package.json里面的panels
{
    // ...
    "panels": {
    "default": {
      "title""UI面板",
      "type""dockable",
      "main""./panel.js"
    }
}
  • main指向的panel.js,就是插件面板的入口逻辑,所有的面板逻辑也都需要写在这里。

1.编写插件面板逻辑,并添加一个按钮

我们在插件目录新建一个panel.js
并在panel.js中添加以下代码:
exports.template = `<button>按钮</button>`;

有没有很熟悉的感觉,没错,这就是 HTML,你可以在里面使用 html 的任何标签!

2.刷新插件面板 ,查看按钮效果

代码编写完毕,我们该如何刷新面板呢?
这里我们就不需要在扩展管理器重启插件,
只需要激活插件面板窗口,然后重新加载下就能看到刚才添加的按钮,如下图所示:
重新加载 时,请注意你当前激活的窗口。

3.美化 UI 界面

添加的按钮似乎有点丑,我们希望他更加个性化,这里就需要使用到了css
exports.template = `<button class="btn">按钮</button>`;
exports.style= `
.btn{
    width:100px;
    height:100px;
}`
;
熟悉 web 前端的小伙伴对这个应该不会陌生,我们还可以这么写,都是同样的效果:
exports.template = `
<button style="width: 100px;height: 100px;">
    按钮
</button>`
;
我们再刷新下界面,就会看到按钮已经发生了变化:
这里我就抛砖引玉,不再赘述输入框怎么添加了,对 web 前端不熟悉的小伙伴,咱就花点时间学习学习。

按钮添加点击事件


我们给插件面板添加了按钮,并且可以对按钮外观样式进行个性化设置。
那么我们该如何给按钮添加一个点击事件呢?

1.获取按钮元素

panel.js
exports.template = `
<button class="btn">
    按钮
</button>`
;

exports.style = `
.btn{
    width:100px;
    height:100px;
}`
;

exports.$ = {
    btn'.btn'// 获取按钮元素 
}
通过$我们可以很方便的拾取界面上的HTML元素,web 老司机一看就明白怎么回事了,这里我简单解释下,更多技术细节,参考 web 前端技术相关教程:
.可以拾取 class元素
exprots.$ = { btn'.btn'}
<button class="btn">按钮</button>

#可以拾取id元素
exprots.$ = { btn'#btn'}
<button id="btn">按钮</button>

2.给按钮绑定事件

panel.js
// ...
exports.ready = function () {
    this.$.btn.addEventListener('click', () => {
        console.log('点击按钮')
    })
}
这里必须在ready中获取HTML元素,直接使用html原生api,对按钮元素添加点击事件。

3. 点击按钮测试下

我们重新加载插件面板,刷新后,我们点击按钮,编辑器的控制台就会打印 log:


至此,我们就可以在插件面板中自由编写逻辑,写一些小插件工具。
有木有很激动?赶快试试吧!

编写插件代码


通过之前的学习,我们已经掌握了如何完整的编写一个插件面板。

我们先整理下panel.js代码:

exports.template = `
<button class="btn">
    按钮
</button>`
;

exports.style = `
.btn{
    width:100px;
    height:100px;
}`
;

exports.$ = {
    btn'.btn'
}

exports.ready = function () {
    this.$.btn.addEventListener('click', () => {
        console.log('点击按钮')
    })
}


随着插件逻辑慢慢复杂,似乎所有逻辑都堆在了这个panel.js,通过观察,我们发现templatestyle都是字符串,我们完全可以独立为htmlcss,这样也方便在 IDE 更加丝滑的编写。

优化后的插件项目结构,如下所示:

  • template变为了panel.html
<button class="btn">
    按钮
</button>
  • style变为了panel.css
.btn {
    width100px;
    height100px;
}
  • panel.jstemplaestyle改为通过读取文件获取
const Path = require('path');
const Fs = require('fs');
exports.template = Fs.readFileSync(Path.join(__dirname, 'panel.html'), 'utf-8');
exports.style = Fs.readFileSync(Path.join(__dirname, 'panel.css'), 'utf-8');

exports.$ = {
    btn'.btn'
}

exports.ready = function () {
    this.$.btn.addEventListener('click', () => {
        console.log('点击按钮')
    })
}
改造后的插件结构,更加有利于IDE的智能提示,同时也方便我们的代码管理。

CSS 再优化

上述的优化已经比较方便代码编写,但是如果界面元素比较多,样式也就非常多,css 编写会越来越麻烦,到最后起名字可能都成了难题。
web 技术发展非常快,新技术层出不穷,CSS 预处理语言也就由此诞生,其中less就是一个解决方案,详细的less教程大家可以自行搜索学习。
我个人使用的idewebstorm,对less支持的也非常好,这里我就分享下在webstorm中配置less
  • 电脑需要安装nodejs,然后全局安装less

    npm install -g less

  • 在 webstorm 中设置实时监听 less 文件,并转换为 css,详细设置自行搜索相关教程,这里不再赘述

经过以上改造,项目结构如下:

终于可以爽快的开撸代码了!!!
当然还有更多的 web 前沿技术等着大家在 Cocos Creator 3D 插件中解锁,期待大家的分享。

使用 UI 框架快速编写代码


在任何技术领域,编写 UI 界面,始终是一件比较繁琐的事情,不过 Cocos Creator 3D 插件也内置了大量内部 UI 组件,可以方便我们快速编写 UI。

使用插件内置 UI 组件

我们可以在菜单开发者/UI组件中,查看现有的内置组件:
面板中展示了很多已有的 UI 组件,我们都可以在插件面板中直接使用,无需引入,示例中也给出了使用代码,非常方便,具体的 UI 组件细节,可以在文档中查阅。
使用插件内置 UI 组件:

优点:

  • UI 风格和整个编辑器非常协调。
  • ui-asset, ui-nodeui-component 等组件,和编辑器器功能联动,算是插件UI特有的功能点。
  <ui-asset id="asset" droppable="cc.ImageAsset"></ui-asset>
  <ui-node></ui-node>
exports.$ = {asset:'#asset'}
exports.ready = function(){
    this.$.asset.value = "asset-uuid";
}

缺点:

  • 相关使用教程,除了文档,少之又少。
  • 如果编辑器 UI 风格发生调整,插件也会受影响。
当然,你也可以使用其他第三方 web-ui 框架,后续我会单独来一篇教程讲解如何引入,目前不在本教程范围内。

在插件面板使用 vue


到目前为止,我们已经知道,Creator 插件面板的编写,使用的是 web 前端技术。

在 web 领域Vue是最受欢迎的构建用户界面的框架之一。

creator2d 插件中我们是可以直接使用vue,但是 creator3d 插件并没有提供。

那么在 creator3d 插件里面,我们如何使用 Vue 呢?

1. 下载 vue

这里我们不使用npm的方式使用vue,我们直接下载vue的构建文件:

我下载的是vue.js,当然你也可以下载压缩版本vue.min.js

下载后,放到我们的插件项目里面:


2.插件里面使用 Vue

vue的本质还是一个 js library,所以,我们直接r equire 即可使用。

我们在panel.js中添加如下代码:

exports.ready = function () {
    // ...
    let Vue = require('./vue');
}

那么我们该如何将 Vue 绑定到 UI 上呢?web 老司机肯定对下面的代码非常熟悉:

panel.html

<div id="app">
    <button @click="onBtnClick">
        按钮
    </button>
</div>

panel.js


// ...
exports.$ = {
    app'#app'
}
exports.ready = function () {
    let Vue = require('./vue');
    new Vue({
        elthis.$.app, // 注意这里,没有不能使用#app,原因是ShadowDOM
        data () {
            return {}
        },
        created () {
            console.log('created');
        },
        methods: {
            onBtnClick () {
                console.log('点击按钮')
            }
        }
    });
}

以上代码,和之前教程给按钮绑定点击事件,效果一样。

重新加载下插件,点击按钮,同样的会在编辑器控制台打印点击按钮的log。

3.Vue 的数据绑定

数据绑定,让我们更专注逻辑开发,vue 会自动根据数据,同步视图。


这里总结了一些常用的小知识点,web 老司机可以直接忽略:


给元素绑定数据:
v-bind:可以简写为:<input v-bind:value="name"/><input :value="name"/>new Vue({
  // ...
    data(){
        return {name:'hello'};
    }
})

当然我们还可以给界面这样绑定文本数据:

<div>{{name}}</div>
  • 给元素绑定事件:v-on:可以简写为@
<button @click="onBtnClcik"></button><button v-on:click="onBtnClcik"></button>new Vue({
    // ...
    methods:{
        onBtnClcik(){
            // todo 
        }
    }
});
以上的小总结,足够让你编写一个功能复杂的小插件,vue还有更多简单易学的特性等待着你学习,更多 vue 的使用请参考 vue 官方文档。



调试插件


经过之前的学习,我们已经可以编写一个比较复杂的插件,编写逻辑的过程中,我们就需要调试,那么 Cocos Creator 3d 插件,应该如何调试呢?

1.万能的 console

console.log()是最简单直接的方式,编辑器会捕获 log,并且在编辑器的控制台进行打印显示。

显然这种方式只满足一些简单逻辑的调试,对于复杂的逻辑,我们必须依靠断点调试,才能准确定位问题。

2.进程?渲染进程,主进程?

在学习断点调试前,我们需要了解,插件的代码是分别运行在不同进程的。

package.json

{
    "main""./main.js",
    // ...
    "panels":{
        "default":{
            // ...
            "main":"./panel.js"
        }
    }
}
  • main.js是运行在主进程

  • panel.js是运行在渲染进程

为什么会是这样子?

主要原因是Creator编辑器采用Electron(https://www.electronjs.org/)开发的。

大家可以自行搜索相关资料,了解更多Electron技术细节。

3.如何调试插件面板

我们写的所有插件面板逻辑,都是运行在渲染进程,你可以认为就是一个很普通的网页,很自然我们就想到了调试网页利器devtools,那么在 Creator 3D 我们如何打开呢?

点击菜单栏的开发者/开关开发人员工具,就可以打开当前窗口的调试工具

注意:打开的当前激活窗口的调试工具


这里就不在详细介绍如何使用devtools了,这是开发 creator 游戏过程中,高频使用的工具。

4.发现更多编辑器 API

Devtools中,当我们在控制台编写代码按下.时,会自动提示该对象拥有的属性、方法:

所以,我们可以通过Console探索编辑器更多的 api 接口,有些 api 可能没有在文档写明,但的确是可以使用,不过在使用这些api的时候慎重,随着版本的更新,有可能就会消失。

以上就是插件开发过程中,常用的一些调试手段和小技巧,希望对你有所帮助!


好好学习,天天向上

感谢原文作者 许彦峰 的教学分享,也希望有更多的大佬带来关于编辑器插件开发分享!

本系列教程持续更新中,欢迎各位开发者点击【阅读原文】,查看作者第一手更新,与作者进行交流学习!


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存