2.x 项目升级 3.x 避坑指南与基础 API 差异总结!

9d8eb230f9331f2f8efd29f7b9c7459a.jpeg

有读者在将 Cocos Creator 2.x 项目升级到 3.x 时,遇到不少问题,感觉很痛苦!

还好晓衡去年,也有过类似的经历。将自己在 Cocos Store 上的《球球要回家》从 Cocos Creator 2.2.2 先后升级到 2.4.10 再到 3.6.2。

本篇文就来跟大家分享一下,我在过程中踩到的一些坑以及 2.x 与 3.x 中引擎最基本的一些接口的变化。

不论你是升级老项目,还是想尝试在 Creator 3.x 上新开项目,相信本文都能对你有所帮助!

01 升级流程

1. 升级引擎到 2.4.x

如果你是 2.4.x 以下的老项目,建议先将项目升级到 2.4.x 最新引擎版本。

如果有出现警告什么的,可以暂时不管他,引擎会提示你哪些方法、属性废弃了,用什么接口去替换。只需要将真正被废弃的接口改掉,保证项目正常运行就好。

根据我这一两年参与CocosStore资源上架审核测试工作来看 95% 的项目,可以不用任何改动升级到 2.4.x。

2. 脚本升级

Cocos Creator 3.x 仅支持使用 TypeScript 作为组件脚本。

因此,如果你之前用 Javacript 编写的组件脚本,还需要将它们翻译为 TypeScript。这一步是个体力活动:

扫描二维码关注公众号,回复: 16530936 查看本文章
  • 一是翻译脚本从JS到TS

  • 二是将脚本重新挂载节点

我的做法是,比如:看到有个脚本为:GameScene.js,先在它旁边生成一个 GameSceneTS.ts 照着 JS 代码逻辑,按 TS 语法重写一遍代码。

058018244685cf23d35533999961e184.png

虽然这是个体力活,但是在 VSCode 中写 TS 代码还是很享受的,智能提示非常的方便。

如果发现代码提示,并没像我说的那么友好!那请注意,你可以通过引擎主菜单开发者VSCode 工作流更新或导入creator.d.ts提示文件,如图:

b5baee68ce3dfc7d3d9651e636ae3fa9.png

TS 脚本翻译完后,就要开始在编辑器上进行替换了。

但是,如何找到之前使用的 JS 脚本,在哪些地方使用过呢?看下图:

912661559b3d43b2d3be06c4280610c3.png

在资源管理器中,鼠标右键选中脚本文件,在菜单中点击找查使用可以找到资源使用过的场景预制体

不过问题又来了,场景那么多节点,组件脚本在哪里呢?这个怎么找?

3162156a09c7ad2e5d4d304fd0586127.png

在这里分享一个小技巧,在层级管理器的搜索栏中输入:t:组件名字 就出来了!96c229775afe834a69099d93d288f925.png

然后你就可以,将新的 TS 脚本挂到节点上,并照之前 JS 组件属性值,配置 TS 组件参数了。

8f8943b684faade73db31b1a6c802826.png

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 项目

a0901f17f778cf5d3bf0fff7c4cc5191.png

浏览到准备升级的 2.x 工程目录,会弹出下面这样一个面板。

0cda1cb2312bede2aa196fa64454b73e.png

注意:这里有一个坑点!我最初在导入球球要回家 2.4.10 工程后发现,场景中的 Button 按钮点不动。

为了排除是因为脚本引起的问题,我使用 2.4.10 重新建了一个 Hello World 工程,添加上Button按钮,再导入 3.6.2 依然有这个问题,

试了多次无解决,我再停下来看导入面板上的说明,打开一个 Github 仓库,是这个导入工具的插件版本。

997626c9b52e59ec0255be28539b35d2.png

看 README 中的更新说明,正好解决了按钮不能点击的问题,以及其他 BUG 的修复

a24a6d6fe360d7b88bb199011a5e6586.png

果断下载插件安装上,再次尝试使用 Hellow World 工程导入 3.x 引擎 Button 点击问题解决!

4. 升级 3.x 脚本代码

使用插件版本导入工具,导入完毕,我感觉有点心跳加速,小心翼翼地打开几个游戏场景和预制体!惊呆了!

UI完美再现......OK
组件脚本节点绑定在......OK
组件属性、节点引用、组件方法调用一切OK!
难道这就成功了吗?

我按捺住激动的心,尝试着运行一下,跑起来了!

可是!点击下按钮,仅仅弹动一下,但就没有然后了。

我赶紧打开脚本看看,发现是这样一个光景:所有代码中的函数体,都被注释起来了!

319e2913919ac3d1af915fa6c6a1c757.png

这时我才意识到,正真的 3.x 升级工作现在才开始!

02 组件代码调整

1. 模块引入

在 Creator 3.x 中废弃了cc.Nodecc.Sprite 这种形式的 API 调用。取而代之的是,先在脚本顶部做import模块,代码如下:

//从 cc 模块中解构出 Node、Sprite 变量
import { Node, Sprite } from 'cc'

其实在使用 VSCode 编写代码时,并不需要我们手动一个个敲import引入的模块,看下面:

b0be1e6f88b36dd81d16b6bc90b1916a.gif

脚本中首次使用引擎模块时,它会自动 import 的,如果你有出现上面招数不灵,可以尝试通过 3.x 引擎主菜单开发者Export.d.ts安装 VSCode 提示文件。

c5a1cdccc59b21439e33c7cc7c3edec7.png

2. Node 属性的变化

Creator 3.x 中 Node 的属性变得极其的简洁了,只剩下positionrotationscale 保留。

b05531dba786cffece6ff26f380ea9d6.png

那其它的属性到去了呢?我们在 3.x 场景中添加一个2D精灵,你可以看到:

94bf4469c450fb7728fc128a1425c8a4.png
  1. opacity 属性移到cc.UIOpacity组件

  2. color 属性移到cc.Sprite组件

  3. size、anchor point 属性移到cc.UITransform组件

90dbb49ad260d69072ed33a71ccc23f1.png

因此之前的 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 后要注意的是:

  1. 有些属性已经不在 Node 对象上了,需要获取相关组件来控制

  2. 位移、旋转、缩放属性使用 Vec3 类型而非 Vec2,不然会出现一些意想不到的问题。

像下面这个场景,关卡按钮出现时,做了一个缩放动画。b7648d16fc89201db8bda67260bad834.gif

代码是这样写的:

...
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预览运行。而且使用到的图片资源,并不是在编辑器中手动拖放的,而是用代码加载。

830dbf8c0ed87cdefebb6a096ddf6c02.gif

图中,通过GameBoard组件的Level属性切换关卡编号,可看直接看到场景变化。不会的同学可能会问,这是怎么做到的呢?

  1. 为组件脚本添加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;
  }
  ...
}

  1. 编辑器中加载资源

//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,看下图:

1c8aea591197f013a3c17ce8813f2192.jpeg

03 小结

从 Creator 2.x 移植 3.x 的整体过程,大概就下面三步:

  1. 将代码移植 TS 并升级到 2.4.x,如果项目已经是 2.4.x TS 那恭喜你,可以跳过这一步;

  2. 在 3.x 编辑器中使用 2.x 项目导入功能(注意要使用插件哦)将 2.x 升级到 3.x,这一步主要解决了 UI 重做的问题;

  3. 修改 3.x 中不兼容 2.x 的相关接口,基本上是一对一翻译,注意 3.x 首先它是 3D 引擎,大量接口已经变成 Vec3。

希望上面 2.x 升级 3.x 内容对你有所帮助《球球要回家》

体验链接:
http://gameview.creator-star.cn/zxh/ball-game-ccc3.6.2/index.html

下载地址:
https://store.cocos.com/app/detail/2648


往期精彩

猜你喜欢

转载自blog.csdn.net/6346289/article/details/132179051