Cocos 3.x 扩展开发教程

855 阅读7分钟

本文接上篇:

但为了让本文也可以单独阅读,仍保留必要信息。

一、Cocos扩展介绍

Cocos扩展可以让Cocos Creator用户定制和扩展编辑器的功能。这些扩展以包(package)的形式进行加载。

Cocos Creator 的扩展包沿用了 Node.js 社区的包设计方式,通过 package.json 描述文件来定义扩展包的内容和注册信息。

需要注意的是,Cocos Creator 2.x 系列和 Cocos Creator 3.x 系列的扩展不兼容,位置也不同,所以开发教程也不同。本文讲的是 Cocos Creator 3.x 系列扩展开发教程,Cocos Creator 2.x 系列见上一篇。

官方开发教程在:扩展编辑器 · Cocos Creator

Cocos扩展的商店页面是 store.cocos.com/app ,可以在Cocos Creator IDE中直接打开。

1.png

2.png 注:上图的SmartAd试玩打包工具就是本文要讲的案例。

二、教程案例介绍

1. 案例背景

本案例介绍的扩展名叫**SmartAd试玩打包工具**,是一个Cocos打包试玩广告的扩展。

试玩广告是一种新兴广告类型,在近几年开始兴起。与传统广告格式(如图片和视频)不同,试玩广告对用户具有高度互动性,在广告展示时,可以与用户进行交互,使广告变得更丰富有趣。

这些广告能在 30 秒内吸引观众的注意力、展示游戏玩法并转化用户。即使在竞争激烈的市场中,它们也能提供低用户获取成本(CPI)、高转化率 (CVR) 和点击率 (CTR)。

试玩广告本质上是一个HTML网页,通过JS等技术响应用户操作,与用户产生互动。由于带宽和加载速度的原因,试玩广告一般对文件大小都有严格要求,大多数投放渠道的要求是不超过5M,且要求单文件,即所有资源都要在一个HTML中加载展示。

Cocos因为引擎的特性,非常适合用来制作试玩广告,但Cocos导出的工程是一个多文件目录,需要用专门的工具进行单文件打包,并接入各渠道的SDK,这是一个耗时耗力的过程。SmartAd平台开发了一个工具,可以一键完成Cocos工程导出试玩广告,为了更方便用户使用,因此需要开发一个Cocos Creator扩展,方便用户的使用。

关于试玩广告,如果你想了解更多可以阅读这篇文章:应用、游戏和品牌的新营销方式-试玩广告-帮助中心-SmartAd试玩广告制作平台

2. 扩展流程

本扩展的流程是:

3.jpg

3. 涉及到的知识点

  • 扩展基本结构
  • 多语言
  • 扩展菜单添加
  • 扩展面板UI编写
  • UIKit的使用
  • 扩展数据交互
  • 文件上传
  • 扩展打包上架

三、创建基本结构

在菜单上选择 扩展->创建扩展:

4.png

即可打开扩展模板面板:

4.1.png

这里我们选择 HTML面板,扩展名叫smartad_demo,创建位置选全局:

4.2.png

操作完成后,即可在扩展管理器(也可以在菜单中通过 扩展 -> 扩展管理器 打开)中看到我们创建的扩展:

4.3.png

上面的操作,会在用户目录生成一个目录,结构如下:

5.png

这几个文件作用如下:

1. @types

扩展环境,不用关注,也用不到

2. dist

因为src中是用ts编写的,在发布时需要编译为js文件,ts编译为js后,就存在这个目录中。

3. i18n

多语言文件

4. src

扩展源码,是ts语言,这里面比较关键的有两个文件,分别是:

(1)src/main.ts

src/main.ts 是扩展入口文件,在package.json中定义: `//@ts-ignore

import packageJSON from '../package.json';

/**

  • @en

  • @zh 为扩展的主进程的注册方法

*/

export const methods: { [key: string]: (...any: any) => any } = {

openPanel() {

Editor.Panel.open(packageJSON.name);

},

};

/**

  • @en Hooks triggered after extension loading is complete

  • @zh 扩展加载完成后触发的钩子

*/

export const load = function() { };

/**

  • @en Hooks triggered after extension uninstallation is complete

  • @zh 扩展卸载完成后触发的钩子

*/

export const unload = function() { };` 值分别表示:

  • methods:为扩展的主进程的注册方法,这里只注册了openPanel方法
  • load:扩展打开时调用
  • unload:扩展关闭调用

(2)src/panels/default/index.js

这个是面板入口文件,也在package.json中定义: `import { readFileSync } from 'fs-extra';

import { join } from 'path';

/**

  • @zh 如果希望兼容 3.3 之前的版本可以使用下方的代码

  • @en You can add the code below if you want compatibility with versions prior to 3.3

*/

// Editor.Panel.define = Editor.Panel.define || function(options: any) { return options }

module.exports = Editor.Panel.define({

listeners: {

show() { console.log('show'); },

hide() { console.log('hide'); },

},

template: readFileSync(join(__dirname, '../../../static/template/default/index.html'), 'utf-8'),

style: readFileSync(join(__dirname, '../../../static/style/default/index.css'), 'utf-8'),

$: {

app: '#app',

},

methods: {

hello() {

if (this.$.app) {

this.$.app.innerHTML = 'hello';

console.log('[cocos-panel-html.default]: hello');

}

},

},

ready() {

if (this.$.app) {

this.$.app.innerHTML = 'Hello Cocos.';

}

},

beforeClose() { },

close() { },

});`

5. static

静态资源,如html,css等,当然也可以放js文件

6. package.json

package.json是扩展定义,文件内容如下: `{

"package_version": 2,

"version": "1.0.0",

"name": "smartad_demo",

"description": "i18n:smartad_demo.description",

"main": "./dist/main.js",

"dependencies": {

"fs-extra": "^10.0.0"

},

"devDependencies": {

"@types/node": "^16.0.1",

"@types/fs-extra": "^9.0.5",

"typescript": "^4.3.4"

},

"panels": {

"default": {

"title": "smartad_demo Default Panel",

"type": "dockable",

"main": "dist/panels/default",

"size": {

"min-width": 400,

"min-height": 300,

"width": 1024,

"height": 600

}

}

},

"contributions": {

"menu": [

{

"path": "i18n:menu.panel/smartad_demo",

"label": "i18n:smartad_demo.open_panel",

"message": "open-panel"

},

{

"path": "i18n:menu.develop/smartad_demo",

"label": "i18n:smartad_demo.send_to_panel",

"message": "send-to-panel"

}

],

"messages": {

"open-panel": {

"methods": [

"openPanel"

]

},

"send-to-panel": {

"methods": [

"default.hello"

]

}

}

},

"author": "Cocos Creator",

"editor": ">=3.4.2",

"scripts": {

"build": "tsc -b",

"watch": "tsc -w"

}

}`

四、多语言

1、方案

Cocos Creator编辑器扩展系统中内置了多语言方案,即目录下的 i18n 文件夹,你可以为每种语言添加一个相应的 JavaScript 文件,作为键值映射数据。数据文件名应该和语言的代号一致,如 en.js 对应英语映射数据。

如: `// en.js

"use strict";

module.exports = {

open_panel: "Default Panel",

send_to_panel: "Send message to Default Panel",

description: "Extension with a panel"

};

// zh.js

"use strict";

module.exports={

open_panel:"默认面板",

send_to_panel:"发送消息给面板",

description:"含有一个面板的扩展"

};`

2、在脚本中使用

在 TypeScript 或者 JavaScript 脚本中,可通过 Editor.I18n.t 接口获取当前语言对应的翻译后的文本: `// NOTE: my package name is "smartad_demo"

let str = Editor.I18n.t('smartad_demo.open_panel');`

3、在HTML模板中使用

在 HTML 模版里需要翻译的话可以使用 ui-label 元素进行翻译: <ui-label value="i18n: smartad_demo.open_panel"></ui-label>

4、在JSON文件中使用

例如在扩展包的 package.json 中注册菜单路径时,只要这个字段支持 i18n 格式的路径,该路径就可以用 i18n:${key} 的形式实现多语言翻译功能: `{

"menu": [

{

"path": "i18n:menu.panel/smartad_demo",

"label": "i18n:smartad_demo. smartad_demo",

"message": "open-panel"

},

{

"path": "i18n:menu.develop/smartad_demo",

"label": "i18n:smartad_demo.send_to_panel",

"message": "send-to-panel"

}

],

}`

五、扩展菜单添加

Cocos Creator 的主菜单是可以自由扩展的。扩展方法是在 package.json 文件中的 contributions 下面的menu 字段里,加入自己的菜单路径和菜单设置选项。

我们这里只需要一个,所以配置如下: `{

"contributions": {

"menu": [

{

"path": "i18n:menu.panel/smartad_demo",

"label": "i18n:smartad_demo.smartad_demo",

"message": "open-panel"

}

],

"messages": {

"open-panel": {

"methods": [

"openPanel"

]

}

}

},

}`

效果如图:

6.png

这里的 message 调用的是 main.ts中的openPanel方法。

六、扩展面板UI编写

1. 原型图

面板原型图如图:

7.jpg

2. 结构优化

为了让代码更具可读性,我们把面板分为html和css及js的方式,具体做法是在panel目录下创建index.html、index.css文件,并在index.js中引用。

目录如下:

8.png

3. 具体实现

index.css:

`#app {

padding:20px;

color: #fff;

}

a {

color:#fff;

margin: 5px;

}

h2 {

color: #fff;

text-align: center;

}

p {

font-size: 16px;

}

.btn_group {

text-align: center;

margin-top: 20px;

}

.button-item {

padding:10px 20px;

border-radius: 5px;

color: #fff;

}

#msg {

color: white;

padding: 10px;

margin-top: 20px;

font-size: 20px;

line-height: 24px;

border-radius: 5px;

word-break: break-all;

background: #000;

} `

4. 运行效果

效果如图所示

9.png

七、UIKit的使用

1. UIKit介绍

Cocos Creator 为开发者提供了非常丰富的界面元素,称为UIKit,帮助开发者快速地开发面板界面。

目前常见的界面元素包括:

  • ui-button
  • ui-checkbox
  • ui-color
  • ui-input
  • ui-select
  • ui-slider
  • ui-text-area

全部元素见:掌握 UI Kit · Cocos Creator

2. UIKit的使用

我们这里只用 ui-button 做演示,在html中的取消和打包按钮分别如下: `取消

打包`

3. UIKit元素的获取

在面板上定义了uikit后,在js中通过$进行绑定:

`$: {

cancel_btn: '#cancel_btn',

pack_btn: '#pack_btn'

}`

使用时直接用 this.$cancel_btn即可。

八、扩展数据交互

按照第2步中的流程,接下来的操作就是用户点击“打包”按钮,开始检测构建文件,并压缩上传。

1. 事件监听

我们先来绑定按钮的点击事件,通过 addEventListener方法即可给元素添加事件: `ready() {

this..cancel_btn && this..cancel_btn.addEventListener('click', () => {

Editor.Panel.close('smartad');

});

this..pack_btn && this..pack_btn.addEventListener('click', () => {

});

this..help_link && this..help_link.addEventListener('click', () => {

smartAd.openDefaultBrowser('www.smartad.pro/help')

});

},`

如上面的代码,我们分别给“取消”、“打包”和帮助文字添加了点击事件。

2. 调用其他模块

为了让代码更好地组织和阅读,我们把主要的逻辑写在扩展的 static/src/smartAd.js 中,这里实现了扩展的所有流程。

在面板的js中我们可以通过下面的方式对smartAd.js进行引用:

const smartAd = require(join(__dirname, '../../../static/script/smartAd'));

在“打包”按钮中进行引用:

`const _self = this;

this..pack_btn && this..pack_btn.addEventListener('click', () => {

try {

console.log("begin");

// let token = this.$token.value;

smartAd.main(function msgCallback(msg: string) {

console.log("msgCallback", msg);

if (_self.$.msg){

_self.$.msg.innerHTML = msg;

}

});

} catch (e) {

console.log(e);

}

});`

九、文件上传

文件上传使用标准的HTTP POST请求就可以实现。

1. 构建form表单

我们这里先读取文件,放在header的boundary,构建一个form-data,示例如下: `function writeBinaryPostData(req, filepath) {

var fs = require('fs'),

data = fs.readFileSync(filepath);

var crlf = "\r\n",

boundaryKey = Math.random().toString(16),

boundary = --${boundaryKey},

delimeter = ${crlf}--${boundary},

headers = [

'Content-Disposition: form-data; name="zip"; filename="cocos_zip.zip"' + crlf

],

closeDelimeter = ${delimeter}--,

multipartBody;

multipartBody = Buffer.concat([

new Buffer(delimeter + crlf + headers.join('') + crlf),

data,

new Buffer(closeDelimeter)]

);

req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);

req.setHeader('Content-Length', multipartBody.length);

req.write(multipartBody);

return req;

}`

2. 发送POST请求

这里用的是node自带的https库,代码如下:

`function request_i(params, callback) {

let headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',

'Content-type': 'application/json'

}

const url_host = config.host.replace('https://', "").replace('http://', "");

const url_path = params.url;

const options = {

hostname: url_host,

port: 443,

path: url_path,

method: 'POST',

headers: headers,

};

let req = https.request(options, res => {

console.log(statusCode: ${res.statusCode});

res.on('data', d => {

console.log(data: ${d});

callback(d);

});

});

req.on('error', error => {

console.error("error:", error);

});

req = writeBinaryPostData(req,params.zip_file)

req.end();

}`

十、打包

1. 最终的代码

最终的目录结构如下:

10.png

2. 第三方库

因为我们用到了压缩,所以需要引入第三方压缩库archiver,在package.json中引入:

`{

"dependencies": {

"fs-extra": "^10.0.0",

"archiver": "^5.3.0"

},

"devDependencies": {

"@types/node": "^16.0.1",

"@types/fs-extra": "^9.0.5",

"typescript": "^4.3.4"

},

}`

然后通过 npm install 进行安装

3. 打包

通过npm run build进行构建,会把ts文件编译成js文件,放在dist目录中。

最后把如下目录(包含node_modules)压缩为ZIP格式,并命名为扩展名称,即可。

11.png

十一、上架

1. 注册Cocos开发者账号

访问 Cocos 开发者中心 注册账号并登录

2. 填写扩展信息

  • 进入 商店 栏目,点击右上方的发布新资源;
  • 然后进入资源类别页面,填写名称和类别 ,勾选已阅读协议;
  • 在 资源介绍 页面填写相关信息;
  • 在 定价 页面设置插件的售价,包括 CNY 和 USD 两种,如果免费请填写 0;
  • 在 上传资源 页面上传插件扩展包资源并填写相关信息;

3. 提交审核

填写完以上信息后,在 提交审核 页面点击 提交审核 按钮即可,一般3个工作日会有结果。

更详细的信息请参考:提交插件到商店 · Cocos Creator

十二、结束

好了,以上就是Cocos Creator 3.x 版扩展开发的相关内容,欢迎留言交流。