Creator 2.x 升級 3.x 基礎 API 差異總結

張曉衡發表於2023-01-11

上一篇我們介紹了 Cocos Creator 2.x 專案升級 3.x 的大流程。

但最後一步,還需要手動將之前 2.x 寫的函式註釋一處處的放開。

並將 2.x 的程式碼寫法改成 3.x 的,下面我們就來看一下有那些差異。

1. 模組引入

在 Creator 3.x 中廢棄了 cc.Nodecc.Sprite 這種全域性形式的 API 呼叫。

取而代之的是,先要在指令碼頂部 import 模組,程式碼如下:

//從 cc 模組中解構出 Node、Sprite 變數
import { Node, Sprite } from 'cc'

好在 VSCode 編輯器,它會自動幫助我們新增 import 模組。
file

但你需要先在 3.x 引擎主選單 開發者Export.d.ts 安裝 VSCode 提示檔案,看下圖:

file

2. Node 基礎屬性變化

Creator 3.x 中 Node 的屬性變的極其的簡潔了,只剩下 positionrotationscale 這三個屬性被保留。

file

而且它們都變成了 Vec3 型別,看下面使用方法。

設定節點位置

//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);

3. 節點顏色與透明

我們在 3.x 場景中新增一個 2D 精靈,你可以看到,節點的顏色與透明,已經分離到別的元件上了。

file

  1. opacity 屬性移到 cc.UIOpacity 元件
  2. color 屬性移到 cc.Sprite 元件
  3. size、anchor point 屬性移到 cc.UITransform 元件

file

因此之前的 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;

設定節點大小

//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 屬性還在,但程式碼介面也有所變化,我們來看下他們的區別。

節點座標轉換

還有,在 2D 中常用的節點座標轉換

  • Node.convertToNodeSpaceAR
  • Node.convertToWorldSpaceAR
  • Node.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));

節點層級

在 2.x 中 Node.zIndex 是用來控制節點顯示層級,數值越大在最底層。

而在 3.x 中 Node.zIndex 介面已被廢棄,需要使用 Node.setSiblingIndex() 方法,與 2.x 是相反的,數值最小的在最底層。

4. Tween 動畫

在 Creator 2.x 中 Tween 動畫主要是控制節點的位移、旋轉、縮放、透明度、顏色等屬性。

移植到 Creator 3.x 後要注意的是:

  1. 有些屬性已經不在 Node 物件上了,需要獲取相關元件來控制
  2. 位移、旋轉、縮放屬性使用 Vec3 型別而非 Vec2,不然會出現一些意想不到的問題。

例如:

...
let node = item.node;
tween(node)
  .to(0.1, { scale: v2(1.1, 1.1) }) //放大
  .to(0.1, { scale: v2(1, 1)})      //還原,這裡會出錯!
  .start();

上面執行效果也都正常,但是會導致一些互動事件失效,比如:按鈕無法響應點選事件。需要改成下面這樣:

...
let node = item.node;
tween(node)
  .to(0.1, { scale: v3(1.1, 1.1) }) //放大
  .to(0.1, { scale: v3(1, 1)})      //還原
  .start();

需要將 scale 屬性的值從 Vec2 改成 Vect3 就正常了。

5. 編輯器載入資源

專案中,有時我們會用到編輯器內資源載入,什麼意思呢?

就是說希望在編輯器狀態,就能看一些介面效果,而不用跑H5預覽。

而且使用到的圖片資源,並不是在編輯器中手動拖放的,而是用程式碼載入。

file

上圖中,透過 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;
  }
  ...
}

** 2. 編輯器中載入資源 **

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

以上是都是我在升級 2.x 專案到 3.x 時遇到的 API 介面差異情況,在此做個記錄,也希望能對你有所幫助。

更多精彩請關注Creator星球遊戲開發社群

相關文章