---
# System prepended metadata

title: Cocos Creator 3D
tags: [Creator3D]

---

# Cocos Creator 3D

### 生命周期函數

按以下順序調用

|  Function  | 調用時機                                     |
|:----------:| -------------------------------------------- |
|   onLoad   | 腳本初始化時調用                             |
|  onEnable  | 組件的 enabled 屬性從 false 變為 true 時調用 |
|   start    | 組件第一次激活時調用                         |
|   update   | 每一幀渲染前更新物體調用                     |
| lateUpdate | 在所有組件的 update 都執行完之後調用         |
| onDisable  | 組件的 enabled 屬性從 true 變為 false 時調用 |
| onDestroy  | 組件或者所在節點銷毀時調用                   |


### 3D向量計算
:::success

pseudo code
```
Vec3(0, 0, 0) + Vec3(0, 0, 1) * 10
```
cocos
```
let startPos:Vec3 = new Vec3(0, 0, 0);
let moveDir:Vec3 = new Vec3(0, 0, 1);
let endPos:Vec3 = new Vec3();

Vec3.multiplyScalar(endPos, moveDir, 10);
Vec3.add(endPos, startPos, endPos)

// 方法二 out = A + B x scale
Vec3.scaleAndAdd(endPos, startPos, moveDir, 10);
```

:::


### UI
- [alignOnce](https://docs.cocos.com/creator3d/manual/zh/ui-system/components/engine/widget-align.html#%E8%BF%90%E8%A1%8C%E6%97%B6%E6%AF%8F%E5%B8%A7%E6%9B%B4%E6%96%B0%E5%AF%B9%E9%BD%90%E5%92%8C%E4%BC%98%E5%8C%96%E7%AD%96%E7%95%A5) - Widget效能
- [对节点位置、尺寸的限制](https://docs.cocos.com/creator3d/manual/zh/ui-system/components/editor/widget.html#%E5%AF%B9%E8%8A%82%E7%82%B9%E4%BD%8D%E7%BD%AE%E3%80%81%E5%B0%BA%E5%AF%B8%E7%9A%84%E9%99%90%E5%88%B6)- runtime 修改 Widget 的限制
- [文本缓存类型（Cache Mode）](https://docs.cocos.com/creator3d/manual/zh/ui-system/components/editor/label.html#%E6%96%87%E6%9C%AC%E7%BC%93%E5%AD%98%E7%B1%BB%E5%9E%8B%EF%BC%88cache-mode%EF%BC%89) - 經常修改的 Label 選用 `CHAR` 可能較佳

### Script
- 使用 [babel](https://babeljs.io/) 而非 [tsc](https://www.typescriptlang.org/) 编译 TypeScript 脚本。
- 不吃 `tsconfig.json`
- `@property({ type: AnimationComponent })` 在大多情況下直接寫成 `@property(AnimationComponent)` 即可.

### 物理
#### 分組與掩碼 (Group and Mask)

只要符合 
>GroupA & MaskB > 0
>GroupB & MaskA > 0
>
A 與 B 才會檢測碰撞

範例

Cube：
>Layer = 4
>Group = 272 `// (1 << 4) + (1 << 8)`
>Mask = 256 `Plane 的 Layer`

Plane：
>Layer = 8
>Group = 272 `// (1 << 4) + (1 << 8)`
>Mask = 16 `Cube 的 Layer`

在這個情況下，Cube與Plane可以互相碰撞，但是無法與其他物體的 Collider 碰撞

---
### 解決 rigidbody 接觸 kinematic rigidbody 會穿過去
問題
:::info
rigidbody A -> isKinematic = false
rigidbody B -> isKinematic = true

A 完全靜止時, B 接觸到 A 會直接穿過去
:::

解法
:::success
避免讓 A 進入休眠 (回收再強制設成休眠)
```
allowSleep = false
```
:::

---
### VS 和 VS Code 隱藏 meta 檔
:::success
打開 **.gitignore**
在 Cocos Creator 3D Project 區塊新增
```
*.meta
```
:::

---


### 集合 Module
當我們需要引用特定 module 時
```typescript=
import aModule from "aModule"
```

但如果我們需要引用到多個 module 時
```typescript=
import aModule from "aModule"
import bModule from "bModule"
import cModule from "cModule"
import dModule from "dModule"
import eModule from "eModule"
import fModule from "fModule"
...
```
一來看起來不夠整潔，二來很麻煩(你必須要指定每個 module path)
這時候可以透過集合 module(若這些 module 隸屬於同一體系，類似同一個 namespace 的概念)
來讓外部取用方便些

```typescript=
// myModule.ts
import aModule from "aModule"
import bModule from "bModule"
import cModule from "cModule"
import dModule from "dModule"
import eModule from "eModule"
import fModule from "fModule"
...
export default {
    aModule,
    bModule,
    cModule,
    dModule,
    eModule,
    fModule,
    ...
}
```
這時引入 myModule 就可以直接使用那些零碎的 module
```typescript=
import myModule from "myModule"

myModule.aModule
myModule.bModule 
etc..
```
或者是
```typescript=
// myModule.ts
import aModule from "aModule"
import bModule from "bModule"
import cModule from "cModule"
import dModule from "dModule"
import eModule from "eModule"
import fModule from "fModule"
...
export { aModule, bModule, cModule, ... }
```
```typescript=
import { aModule, bModule, etc.. } from "myModule"
```
---
### Path Mapping
上面的集合 Module 還是有一個不方便的地方，就是路徑問題，
要引用 Module 還得知道他的存放位置，若結構深一點看起來也很醜
```typescript=
import myModule from "./first/second/third/.../myModule"
```
為了解決這個問題，可以透過 tsconfig 設定路徑 map
```typescript=
{
  /* Base configuration. Do not edit this field. */
  "extends": "./temp/tsconfig.cocos.json" ,

  /* Add your custom configuration here. */
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "myModule": ["assets/first/second/third/.../myModule"],
    }
  }
}
```
設定完就可以直接透過名稱取用
```typescript=
import myModule from "myModule"
```
也可以指定資料夾位置
```typescript=
{
  /* Base configuration. Do not edit this field. */
  "extends": "./temp/tsconfig.cocos.json" ,

  /* Add your custom configuration here. */
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "myModules/*": ["assets/first/second/third/.../myModules/*"],
    }
  }
}
```
```typescript=
import aModule from "myModules/aModule"
```

PS.以上寫法在純TypeScript專案正常，但cocos專案會噴錯

---
### import error

假設如下code

aModule內容:
```typescript=
import { bModule } from "myModules"; //PS: import方式需對應測試方式

export class aModule {
    public static enabled:boolean = bModule.EnableLog;
    public static warning:boolean = bModule.EnableLog;
}
```

bModule內容:
```typescript=
export class bModule
{
    public static EnableLog: boolean = false;
}
```

myModules錯誤的格式
:::danger
```typescript=
import { aModule } from "./aModule"
import { bModule } from "./bModule"

export { aModule, bModule }
```
:::
不論tsconfig怎麼設定paths都會噴錯 **Uncaught (in promise) Error:: Error loading xxx**

正確的內容:
::: success
```typescript=
export { aModule } from "./aModule"
export { bModule } from "./bModule"
```
:::

測試tsconfig的設定
**測試1:**
tsconfig設定用如下的編譯路徑:
```typescript=
"compilerOptions": {
      "baseUrl": ".",
      "paths": {
        "myModules": ["assets/Module/myModules"],
      }
    }
```
**執行結果正常**

**測試2**
tsconfig設定用如下的編譯路徑:
```typescript=
"compilerOptions": {
      "baseUrl": ".",
      "paths": {
        "@myModules/*": ["assets/Module/*"],
      }
    }
```
**執行結果正常**

**測試3**
tsconfig設定同時使用範例1和2的編譯路徑:
```typescript=
"compilerOptions": {
      "baseUrl": ".",
      "paths": {
        "myModules": ["assets/Module/myModules"],
        "@myModules/*": ["assets/Module/*"],
      }
    }
```

會出現如下錯誤:
:::danger
[Scene] Possible circular-reference in {asset(db://assets/Module/aModule.ts)}: 
when import Module from myModules.

[Build] Error: Error loading project:///assets/Module/myModules.js 
from project:///assets/Module/myModules.js
:::

PS. 一旦出現上述錯誤，直接修改code到正常版本，並執行也不會正常。
**需重新啟動Creator 3D**

---

參考連結：
[Path Mapping](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping)
[Path Aliases](https://medium.com/zero-equals-false/how-to-use-module-path-aliases-in-visual-studio-typescript-and-javascript-e7851df8eeaa)
[CC Manual](https://docs.cocos.com/creator3d/manual/zh/scripting/language-support.html#%E6%A8%A1%E5%9D%97%E8%A7%A3%E6%9E%90)

---

###### tags: `Creator3D`