最近,我将自己在 Cocos Store 上的一个 2D 项目《球球要回家》从
Creator 2.2.2
升级到
Creator 3.6.2
,编程语言也从 JavaScript 全面升级至 TypeScript 并适配微信小游戏,目前在微信审核中!
本篇文章就来跟大家分享一下,我在升级过程中踩到的一些坑,以及 2.x 与 3.x 中引擎最基本的一些接口的变化。
不论你是升级老项目,还是想尝试在 Creator 3.x 上新开项目,相信本文都能对你有所帮助!
一、2.x项目升级流程
1. 升级引擎到 2.4.x
如果你是 2.4.x 以下的老项目,建议先将项目升级到 2.4.x 最新引擎版本。
如果有出现警告什么的,可以暂时不管他,引擎会提示你那些方法、属性废弃了,用什么接口去替换。只需要将真正被废弃的接口改掉,保证项目正常运行就好。
根据我这一两年参与CocosStore资源上架审核测试工作来看 95% 的项目,可以不用任何改动升级到 2.4.x。
2. 脚本升级
Creator 3.x 仅支持使用 TypeScript 做为组件脚本。
因此,如果你之前是用 Javacript 编写的组件脚本,还需要将它们翻译为 TypeScript。这一步是个体力活动,一是翻译脚本,二是将脚本重新挂载节点。
我的做法是,比如:看到有个脚本为:
GameScene.js
,先在它旁边生成一个
GameSceneTS.ts
照着 js 代码逻辑,按 ts 语法重写一遍代码。
虽然这是个体力活,但是在 VSCode 中写 ts 代码还是很享受的,智能提示非常的方便。
如果发现代码提示,并没像我说的那么友好!那请注意,你可以通过引擎
主菜单
→
开发者
→
VSCode 工作流
更新或导入
creator.d.ts
提示文件,如图:
ts 脚本翻译完后,就要开始在编辑器上进行替换了。
但是,如何找到之前使用的 js 脚本,在那些地方使用过呢?看下图:
在资源管理器中,鼠标右键选中脚本文件,在菜单中点击
找查使用
可以找到资源使用过的
场景
和
预制体
。
不过问题又来了,场景那么多节点,组件脚本在那里呢?这个怎么找?
在这里分享一个小技巧,在层级管理器的搜索栏中输入:
t:组件名字
就出来了!
然后你就可以,将新的 ts 脚本挂到节点上,并照之前 js 组件属性值,配置 ts 组件参数了。
ts 组件属性设置完后,将 js 版的组件移除,进行测试。这样操作,可以最大程度保证项目与之前逻辑一致,不容易出问题。
将所有组件替换完毕后,将 js 脚本从资源管理器上移除,再将 ts 脚本名后缀的 xxxTS 拿掉。
《球球要回家》从 2.2.2 升级到 2.4.10 过程中,除了将代码脚本从 js 迁移到 ts 外,我还将所有的 cc.Action 动作改写为了 cc.Tween,为后续升级 3.x 做好充分准备。
3. 升级 Creator 3.x 工程
重点来了,我们的目标是将 2.2.2 项目顺利升级到 3.6.2 上。
新建一个 Creator 3.x 工程,从编辑器主菜单上
文件
→
导入 Cocos Creator 2.x 项目
浏览到准备升级的 2.x 工程目录,会弹出下面这样一个面板。
注意:这里有一个坑点!我最初在导入
球球要回家
2.4.10 工程后发现,场景中的 Button 按钮点不动。
为了排除是因为脚本引起的问题,我使用 2.4.10 重新建了一个
Hello World
工程,添加上Button按钮,再导入 3.6.2 依然有这个问题,
试了多次无解决,我再停下来看导入面板上的说明,打开一个 Github 仓库,是这个导入工具的插件版本。
看 README 中的更新说明,正好解决了按钮不能点击的问题,以及其他 BUG 的修复
果断下载插件安装上,再次尝试使用 Hellow World 工程导入 3.x 引擎 Button 点击问题解决!
4. 升级 3.x 脚本代码
使用插件版本导入工具,导入完毕,我感觉有点心跳加速,小心翼翼地打开几个游戏场景和预制体!惊呆了!
UI完美再现……OK
组件脚本节点绑定在……OK
组件属性、节点引用、组件方法调用一切OK!
难道这就成功呢吗?
我按捺住激动的心,尝试着运行一下,跑起来了!
可是!点击下按钮,仅仅弹动一下,但就没有然后了。
我赶紧打开脚本看看,发现是这样一个光景:
所有代码中的函数体,都被注释起来了!
这时我才意识到,正真的 3.x 升级工作现在才开始!
二、2.x 升级 3.x 组件代码调整
1. 模块引入
在 Creator 3.x 中废弃了
cc.Node
、
cc.Sprite
这种形式的 API 调用。取而代之的是,先在脚本顶部做
import
模块,代码如下:
//从 cc 模块中解构出 Node、Sprite 变量
import { Node, Sprite } from 'cc'
其实在使用 VSCode 编写代码时,并不需要我们手动一个个敲
import
引入的模块,看下面:
脚本中首次使用引擎模块时,它会自动 import 的,如果你有出现上面招数不灵,可以尝试通过 3.x 引擎主菜单
开发者
→
Export.d.ts
安装 VSCode 提示文件。
2. Node 属性的变化
Creator 3.x 中 Node 的属性变的极其的简洁了,只剩下
position
、
rotation
、
scale
保留。
那其它的属性到去了呢?我们在 3.x 场景中添加一个2D精灵,你可以看到:
-
opacity 属性移到
cc.UIOpacity
组件 -
color 属性移到
cc.Sprite
组件 -
size、anchor point 属性移到
cc.UITransform
组件
因此之前的 node.opacity、node.scale、node.color、node.width,这些接口都不能使用了,取而代之的是下面这些样的接口方法:
设置节点透明度
//Creator 2.x
this.node.opacity = 200;
//Creator 3.x
this.node.getComponent(UIOpacity).opacity = 200;
设置节点颜色
//Creator 2.x
this.node.color = cc.Color.RED;
//Creator 3.x
this.node.getComponent(Sprite).color = Color.RED;
设置节点 size
//Creator 2.x
this.node.setContentSize(100, 100);
//Creator 3.x
let transform = this.node.getComponent(UITransform);
//使用方法设置节点大小
transform.setContentSize(100, 100)
//也可以使用contentSize属性
transform.contentSize = Size(100, 100);
//还可以使用width、height属性
transform.width = 100;
transform.height = 100;
虽然 3.x 中 Node 的 position、scale、rotation 属性还在,但代码接口也有所变化,我们来看下他们的区别。
设置节点位置
//Creator 2.x
this.node.position = v2(100, 100)
this.node.x = 100; //3.x中不可用
this.node.y = 100; //3.x中不可用
//Creator 3.x 中不能使用x、y、z分量设置节点位置
//需要使用 position 属性或 setPosition 方法
this.node.position = v3(100, 100, 100);
//注意需要同时设置 xyz 三个分量
this.node.setPosition(100, 100, 100);
设置节点缩放
//Creator 2.x
this.node.scale = 1.5;
//Creator 3.x
//注意 scale 不在是一个 number 而是 Vec3
this.node.scale = v3(1.5, 1.5, 1.5);
//注意 需要同时设置 xyz 三个分量
this.node.setScale(1,1,1);
设置节点在二维上的旋转
//Creator 2.x rotation 属性在 2.3.x 之后是使用 angle 属性
this.node.angle = 1.5;
//Creator 3.x
//节点的 rotation 属性其实是一个 Quat 类型
//2D节点在属性检查器中的 rotation
//对应的是节点的 angle 属性
this.node.angle = 10
//也可以使用 eulerAngles 来设置,注意它是设置的Z轴的旋转
this.node.eulerAngels = v3(0, 0, 10);
节点坐标转换
还有,在 2D 中常用的节点坐标转换 convertToNodeSpaceAR、convertToWorldSpaceAR、getBoundingBox 这些接口移到了 UITransform 组件对象上了,看代码:
//Creator 2.x
let p = this.node.convertToNodeSpaceAR(eventTouch.location);
//Creator 3.x
let transform = this.node.getComponent(UITransform);
let location = eventTouch.location;
//注意 3.x 中convertToNodeSpaceAR的参数为 Vec3 类型
//但 location 为 Vec2 类型
let p = transform.convertToNodeSpaceAR(v3(location.x, location.y));
Tween 动画
在 Creator 2.x 中 Tween 动画主要是控制节点的位移、旋转、缩放、透明度、颜色等属性。移植到 Creator 3.x 后要注意的是:
-
有些属性已经不在 Node 对象上了,需要获取相关组件来控制
-
位移、旋转、缩放属性使用 Vec3 类型而非 Vec2,不然会出现一些意想不到的问题。
像下面这个场景,关卡按钮出现时,做了一个缩放动画。
代码是这样写的:
...
let node = item.node;
tween(node)
.to(0.1, { sacle: v2(1.1, 1.1) }) //放大
.to(0.1, { sacle: v2(1, 1)}) //还原
.start();
运行效果也都正常,但是!按钮无法响应点击事件… 通过各种排查才发现,是写的 Tween 动画造成的,于是改成下面这样:
...
let node = item.node;
tween(node)
.to(0.1, { sacle: v3(1.1, 1.1) }) //放大
.to(0.1, { sacle: v3(1, 1)}) //还原
.start();
将 v2 改成 v3 立马就正常了,就这样一个小小的问题,搞了半天。
节点层级
在 2.x 中
Node.zIndex
是用来控制节点显示层级,数值越大在最底层。
而在 3.x 中
Node.zIndex
接口已被废弃,需要使用
Node.setSiblingIndex()
方法,与 2.x 是相反的,数值最小的在最底层。
winSize
2.x 中还有一个高频接口
cc.winSize
在 3.x 中也不存在了,对应的API为
view.getContentSize()
获取窗口设计分辨率大小。
import { view } form 'cc'
view.getVisibleSize()
编辑器加载资源
项目中,有时我们会用到编辑器内资源加载,什么意思呢?
就是说希望在编辑器状态就能看一些界面效果,而不用跑H5预览运行。而且使用到的图片资源,并不是在编辑器中手动拖放的,而是用代码加载。
图中,通过
GameBoard
组件的
Level
属性切换关卡编号,可看直接看到场景变化。不会的同学可能会问,这是怎么做到的呢?
-
为组件脚本添加
executeInEditMode
装饰器
import { _decorator } from 'cc';
const {ccclass, executeInEditMode} = _decorator;
@ccclass('GameBoard')
@executeInEditMode //添加编辑器模式执行
export default class GameBoard extends Component {
onLoad() {
//代码将在编辑器状态执行
}
start() {
//代码将在编辑器状态执行
}
update() {
//代码将在编辑器状态执行
}
}
注意,在编辑器中执行代码可能会出现一些副作用,比如对象未初化、update被频繁调起。2.x 这时你可以使用
CC_EDITOR
变量做检查,代码如下:
//Creator 2.x 使用 CC_EDIDTO 全局变量检查
update() {
if (CC_EDITOR) {
return;
}
...
}
3.x中已经不存在全局
CC_EDITOR
,而是在
cc/env
模块下代码如下:
//Creator 3.x 使用 EDITOR 变量检查
import { EDITOR } from 'cc/env';
...
update() {
if (EDITOR) {
return;
}
...
}
-
编辑器中加载资源
//Creator 2.4.x 加载图集中的图片
//注意'path'为resouces目录文件路径
cc.resources.load(path, SpriteAtlas, (err, res) => {
let sprite = this.getComponent(Sprite);
sprite.spriteFrame = res.getSpriteFrame(this.imageName);
});
在 3.x 中
Bundle
目录下的资源,不能在编辑器状态下被加载,因此需要将文件移出
resouces
目录,并使用
assetManager.loadAny
这个万能加载API,代码如下:
//Creator 3.x 加载图集中的图片
assetManager.loadAny({uuid:'xxx', type: SpriteAtlas}, (err, res) => {
let sprite = this.getComponent(Sprite);
sprite.spriteFrame = res.getSpriteFrame(this.imageName);
})
在我的测试中使用 assetManager.loadAny({
{uuid:…}})这种接口形式加载成功。如果获得资源UUID,看下图:
三、小结
从 Creator 2.x 移植 3.x 的整体过程,大概就下面三步:
-
将代码移植 ts 并升级到 2.4.x,如果项目已经是 2.4.x ts 那恭喜你,可以跳过这一步;
-
在 3.x 编辑器中使用 2.x 项目导入功能(注意要使用插件哦)将 2.x 升级到 3.x,这一步主要解决了 UI 重做的问题;
-
修改 3.x 中不兼容 2.x 的相关接口,基本上是一对一翻译,注意 3.x 首先它是 3D 引擎,大量接口已经变成 Vec3。
希望上面 2.x 升级 3.x 内容对你有所帮助,也感谢在双11期间支持《球球要回家》的老铁们,这将是 Cocos Store 上第二个同时支持 Creator 2.x 、3.x 的游戏源码资源。所有之前支持过的用户,都可以免费下载!
体验链接:
http://gameview.creator-star.cn/zxh/ball-game-ccc3.6.2/index.html
下载地址:
https://store.cocos.com/app/detail/2648
往期精彩