上一篇我們介紹了 Cocos Creator 2.x 專案升級 3.x 的大流程。
但最後一步,還需要手動將之前 2.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 模組。
但你需要先在 3.x 引擎主選單 開發者
→Export.d.ts
安裝 VSCode 提示檔案,看下圖:
2. Node 基礎屬性變化
Creator 3.x 中 Node 的屬性變的極其的簡潔了,只剩下 position
、rotation
、scale
這三個屬性被保留。
而且它們都變成了 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 精靈,你可以看到,節點的顏色與透明,已經分離到別的元件上了。
- 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;
設定節點大小
//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 後要注意的是:
- 有些屬性已經不在 Node 物件上了,需要獲取相關元件來控制
- 位移、旋轉、縮放屬性使用 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預覽。
而且使用到的圖片資源,並不是在編輯器中手動拖放的,而是用程式碼載入。
上圖中,透過 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,看下圖:
以上是都是我在升級 2.x 專案到 3.x 時遇到的 API 介面差異情況,在此做個記錄,也希望能對你有所幫助。
更多精彩請關注Creator星球遊戲開發社群