快速開始
跟著Cocos Creator用戶手冊完成step by step教程即可快速熟悉Cocos Creator
的應(yīng)用钥勋。
可以通過右上角切換用戶手冊版本:
IDE界面介紹
IDE管理
通過首頁下載Cocos Dashboard,可以管理不同版本的Cocos Creator Editor
辆苔。
語言設(shè)置
通過下述配置可以修改界面語言:
-
層級管理器:所有在場景編輯器中看到的內(nèi)容都可以在層級管理器中找到對應(yīng)的節(jié)點條目笔诵。
場景中仍有一些不可見的私有節(jié)點,不會在此顯示姑子。
在編輯場景時這兩個面板的內(nèi)容會同步顯示,一般我們也會同時使用這兩個面板來搭建場景测僵。
- 創(chuàng)建UI 組件需要在帶有
Canvas
的父節(jié)點下才能顯示街佑,編輯器在發(fā)現(xiàn)沒有 Canvas 節(jié)點時會自動創(chuàng)建一個谢翎。
- 創(chuàng)建UI 組件需要在帶有
-
場景編輯器:在場景編輯器中搭建場景,即可獲得所見即所得的場景預(yù)覽沐旨。
-
點擊主窗口左上角工具欄第四個按鈕纬傲,或在編輯場景時按下 T 快捷鍵享扔,即可切換使用 矩形變換工具。需要注意的是,矩形變換工具只適用于 UI 節(jié)點鞍帝。
通過點擊工具欄上的 2D/3D 按鈕切換到 2D 編輯視圖下進(jìn)行 UI 編輯操作
-
資源管理器:
動畫編輯器:用于編輯并存儲動畫數(shù)據(jù)。
場景視角操作
在 3D 視圖下窑多,可以通過以下操作來移動和定位 場景編輯器 的視圖:
鼠標(biāo)左鍵 + Alt:以視圖中心點為中心旋轉(zhuǎn)豆励。
鼠標(biāo)中鍵:平移視圖。
空格鍵 + 鼠標(biāo)/觸摸板拖拽:平移視圖统诺。
鼠標(biāo)滾輪:以視圖中心點為中心縮放視圖歪脏。
鼠標(biāo)右鍵 + WASD:攝像機漫游。
F 快捷鍵:攝像機聚焦到當(dāng)前選中節(jié)點粮呢。
渲染
列表渲染詳見
資源類型
目前婿失,Creator 支持 FBX 和 glTF 兩種格式的模型文件。
FBX(.fbx):支持 FBX 2020 及更早的文件格式啄寡。
glTF(.gltf 豪硅、.glb):支持 glTF 2.0 及更早的文件格式。
動畫
骨骼動畫
對于mixamo官網(wǎng)來說挺物,處理骨骼動畫需滿足:
- 僅支持特定格式的資源文件:
fbx
懒浮、obj
、zip
(fbx/obj模型 + 紋理打包的zip包) - 要求資源文件內(nèi)沒有骨骼信息姻乓,若有嵌溢,需要通過3D設(shè)計軟件
e.g. blender
提前清除再導(dǎo)入mixamo
。
從mixamo
下載TPose
后蹋岩,下載所需的不同without skin
骨骼動畫赖草,分別導(dǎo)入blender
中重命名骨骼動畫(便于識別),然后刪除場景中的所有要素
最后導(dǎo)入TPose
剪个,進(jìn)行下列步驟綁定骨骼動畫:
在下方面板中[1]選擇[2]動畫攝影表秧骑,[3]選擇動作編輯器,[4]可以切換動畫Animation Clip
扣囊,[5]為每個動畫創(chuàng)建不同的時間線乎折。
從[4]可以看到,當(dāng)前添加了兩條時間線侵歇,可以通過關(guān)鍵幀上下鍵切換不同的動畫骂澄,空格鍵播放動畫。
導(dǎo)出fbx
:
[1]綁定紋理惕虑,[3]將blender
坐標(biāo)系轉(zhuǎn)換為瀏覽器web
坐標(biāo)系坟冲。
參考文檔
程序控制動畫
幀事件
import { Animation, Component, _decorator } from 'cc';
const { ccclass, property } = _decorator;
@ccclass("MyScript")
class MyScript extends Component { // 需要將該組件綁定到骨骼動畫節(jié)點上
public start() {
const skeletalAnimation = this.node.getComponent(SkeletalAnimation);
if (skeletalAnimation && skeletalAnimation .defaultClip) {
const { defaultClip } = skeletalAnimation ;
defaultClip.events = [ // 添加幀事件
{
frame: 0.5, // 第 0.5 秒時觸發(fā)事件
func: 'onTriggered', // 事件觸發(fā)時調(diào)用的函數(shù)名稱
params: [ 0 ], // 向 `func` 傳遞的參數(shù)
}
];
skeletalAnimation.clips = skeletalAnimation.clips;
}
}
public onTriggered(arg: number) { // 骨骼動畫執(zhí)行到第0.5s觸發(fā)該函數(shù)
console.log('I am triggered!', arg);
}
}
自定義動畫磨镶,可以在動畫編輯器面板通過右鍵添加幀事件:
其中:
-
func
:表示事件觸發(fā)時回調(diào)的函數(shù)名稱。- 事件觸發(fā)時健提,動畫系統(tǒng)會搜索 動畫根節(jié)點中的所有組件琳猫,若組件中有實現(xiàn)動畫事件
func
中指定的函數(shù),便會對其進(jìn)行調(diào)用私痹,并傳入params
中的參數(shù)脐嫂。
- 事件觸發(fā)時健提,動畫系統(tǒng)會搜索 動畫根節(jié)點中的所有組件琳猫,若組件中有實現(xiàn)動畫事件
Notes:
-
動畫根節(jié)點中的所有組件
- 骨骼動畫的話,動畫根節(jié)點是骨骼動畫綁定的
Character
- 骨骼動畫的話,動畫根節(jié)點是骨骼動畫綁定的
需要使用
skeletalAnimation.clips = skeletalAnimation.clips;
觸發(fā)幀事件紊遵。
動畫事件回調(diào)
目前支持的回調(diào)事件包括:
PLAY
:開始播放時觸發(fā)STOP
:停止播放時觸發(fā)PAUSE
:暫停播放時觸發(fā)RESUME
:恢復(fù)播放時觸發(fā)LASTFRAME
:假如動畫循環(huán)次數(shù)大于 1账千,當(dāng)動畫播放到最后一幀時觸發(fā)。FINISHED
:動畫播放完成時觸發(fā)
import { _decorator, Component, Node, SkeletalAnimation, Animation, SkeletalAnimationState } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('SkeletonAnimationEvent')
export class SkeletonAnimationEvent extends Component {
start() {
const skeletalAnimation = this.node.getComponent(SkeletalAnimation); // 獲取動畫組件
skeletalAnimation.on(Animation.EventType.FINISHED, this.onAnimationFinished, this); // 綁定事件監(jiān)聽
}
onAnimationFinished(type:Animation.EventType, state:SkeletalAnimationState){
}
}
通信
父子
事件冒泡
// 子節(jié)點的組件腳本中
this.node.dispatchEvent( new MyEvent('foobar', true, 'detail info') );
// 父節(jié)點的組件腳本中
this.node.on('foobar', (event: MyEvent) => {
event.propagationStopped = true;
});
Notes:
- 如果我們希望在某一級節(jié)點截獲事件后就不再傳遞事件癞蚕,可以通過調(diào)用
event.propagationStopped = true
函數(shù)來完成蕊爵。
注入對象實例
調(diào)用實例節(jié)點方法
if(this.playerCtrl){
// 禁止接收用戶操作人物移動指令
this.playerCtrl.setInputActive(false);
// 重置人物位置
this.playerCtrl.node.setPosition(Vec3.ZERO);
}
調(diào)用實例組件方法
const item = instantiate(this.itemPrefab); // 實例化
const data = this.items[i];
this.node.addChild(item);
item.getComponent('ItemTemplate').init(data) // 查找對應(yīng)組件,調(diào)用方法
其中ItemTemplate
組件定義:
import { _decorator, Component, Label, Sprite } from "cc";
import { Item } from "./ItemManager";
const { ccclass, property } = _decorator;
@ccclass("ItemTemplate")
export class ItemTemplate extends Component {
@property
public id = 0;
@property(Sprite)
public icon: Sprite | null = null;
@property(Label)
public itemName: Label | null = null;
@property(Label)
public itemPrice: Label | null = null;
init(data: Item) {
this.id = data.id;
this.itemName.string = data.itemName;
this.itemPrice.string = data.itemPrice;
}
}
事件線程
Cocos Creator 引擎提供了
EventTarget
類桦山,用以實現(xiàn)自定義事件的監(jiān)聽和發(fā)射
import { _decorator, Component, EventTarget } from 'cc';
const { ccclass } = _decorator;
const eventTarget = new EventTarget();
@ccclass("Example")
export class Example extends Component {
onEnable () {
// 監(jiān)聽事件可以通過 eventTarget.on() 接口來實現(xiàn)
eventTarget.on('foobar', this._sayHello, this);
}
onDisable () {
// 當(dāng)我們不再關(guān)心某個事件時攒射,我們可以使用 off 接口關(guān)閉對應(yīng)的監(jiān)聽事件。
eventTarget.off('foobar', this._sayHello, this);
}
_sayHello () {
console.log('Hello World');
}
}
// 發(fā)射事件可以通過 eventTarget.emit() 接口來實現(xiàn)恒水,參數(shù)最多只支持 5 個事件參數(shù)
eventTarget.emit(type, ...args);
適配
多分辨率適配
可以通過以下幾個部分完成多分辨率適配解決方案:
Canvas
(畫布) 組件隨時獲得設(shè)備屏幕的實際分辨率并對場景中所有渲染元素進(jìn)行適當(dāng)?shù)目s放会放。-
Widget
(對齊掛件)能夠根據(jù)需要將元素對齊目標(biāo)節(jié)點(默認(rèn)是父節(jié)點)的不同參考位置,可實現(xiàn)彈性布局钉凌。
-
Label
(文字) 組件內(nèi)置了提供各種動態(tài)文字排版模式的功能咧最,當(dāng)文字的約束框由于 Widget 對齊要求發(fā)生變化時,文字會根據(jù)需要呈現(xiàn)完美的排版效果御雕。-
共有
NONE
矢沿、CLAMP
、SHRINK
酸纲、RESIZE_HEIGHT
四種模式:NONE
模式會自動根據(jù)文字尺寸捣鲸、行高等固定約束框尺寸,不支持自定義尺寸闽坡。-
在 后三種模式 下才能通過編輯器左上角的 矩形變換工具(也可以是按鍵盤按鍵 T)或者修改 屬性檢查器 中的 Size 大小或者添加 Widget 組件 來調(diào)整約束框的大小栽惶。
CLAMP
:截斷,超出的部分會被隱藏疾嗅。-
SHRINK
:自動縮小模式下外厂,如果文字按照原定尺寸渲染會超出約束框時,會自動縮小文字尺寸以顯示全部文字代承。
自動縮小模式不會放大文字來適應(yīng)約束框汁蝶。
-
RESIZE_HEIGHT
:- 自動適應(yīng)高度模式會保證文字的約束框貼合文字的高度,不管文字有多少行论悴。這個模式非常適合顯示內(nèi)容量不固定的大段文字穿仪。
- 自動適應(yīng)高度模式會保證文字的約束框貼合文字的高度,不管文字有多少行论悴。這個模式非常適合顯示內(nèi)容量不固定的大段文字穿仪。
-
-
Layout
(自動布局) 可以掛載在任何節(jié)點上席爽,將節(jié)點變成一個有自動布局功能的容器,實現(xiàn)flex啊片、grid布局。
-
在
Cocos Creator v3.8
版本中玖像,通過
設(shè)定設(shè)計尺寸紫谷,需打包為web-mobile
。
Cocos Creator 提供了兩種 Web 平臺的頁面模板捐寥,可以通過 發(fā)布平臺 的下拉菜單選擇 Web Mobile 或 Web Desktop笤昨,它們的區(qū)別主要在于:
- Web Mobile 會默認(rèn)將游戲視圖撐滿整個瀏覽器窗口。
- Web Desktop 允許在發(fā)布時指定一個游戲視圖的分辨率握恳,而且之后游戲視圖也不會隨著瀏覽器窗口大小變化而變化瞒窒。
九宮格格式的圖像
如果圖像資源是用九宮格的形式生產(chǎn)的,那么不管 Sprite 如何放大乡洼,都不會產(chǎn)生模糊或變形崇裁。
切分圖像
在[1]資源管理器中導(dǎo)入圖片,如[2]
點擊圖片資源[2]束昵,查看屬性檢查器[3]
在屬性檢查器[3]中修改圖片資源類型為
sprite-frame
[5]點擊[6]應(yīng)用修改
-
點擊
Edit
編輯拔稳,打開Sprite
編輯器:
應(yīng)用圖像
在層級管理器[1]中的
Cavans
節(jié)點[2]下創(chuàng)建Sprite
節(jié)點[3]拖拽資源管理器[4]中的圖片資源[5]到屬性檢查器[6],將 Sprite 的
Type
屬性設(shè)為Sliced
[7]锹雏。
三方庫支持
[Cocos Creator外部代碼支持]https://docs.cocos.com/creator/3.8/manual/zh/scripting/external-scripts.html
[Cocos Creator外部代碼支持示例]https://docs.cocos.com/creator/3.8/manual/zh/scripting/modules/example.html
調(diào)試
在 偏好設(shè)置 面板中指定了 <u>默認(rèn)腳本編輯器</u>巴比,便可以在 資源管理器 中雙擊腳本文件打開代碼編輯器快速編輯代碼。
-
Cocos Creator 在頂部菜單欄的 開發(fā)者 -> VS Code 工作流 中集成了 添加編譯任務(wù) 和 添加 Chrome Debug 配置 功能礁遵,分別點擊可給
vs code
添加調(diào)試任務(wù)task
-
添加編譯任務(wù):用于在 VS Code 中觸發(fā) Creator 的腳本編譯
添加后轻绞,可通過
vs code
任務(wù)觸發(fā)Creator編譯,無需重新激活Creator
佣耐;若不添加政勃,
vs code
修改腳本后,需要激活Creator
進(jìn)行編譯
-
添加 Chrome Debug 配置:用于調(diào)試網(wǎng)頁版游戲
啟動專門的Chrome調(diào)試預(yù)覽效果
可直接在
vs code
中調(diào)試代碼晰赞,指定Chrome工具調(diào)試
-
使用 VS Code 調(diào)試網(wǎng)頁版游戲
- 在 VS Code 中點擊左側(cè)欄的 調(diào)試 按鈕打開調(diào)試面板稼病,并在最上方的調(diào)試配置中選擇
Cocos Creator Launch Chrome against
localhost
,然后點擊左側(cè)綠色的開始按鈕進(jìn)行調(diào)試
- 在 VS Code 中點擊左側(cè)欄的 調(diào)試 按鈕打開調(diào)試面板稼病,并在最上方的調(diào)試配置中選擇
2. 更新腳本后掖鱼,在VS Code 里按下快捷鍵 Cmd/Ctrl + P然走,激活 快速打開 輸入框,然后輸入`task CocosCreator compile`戏挡,選擇 `CocosCreator compile`芍瑞,即可在Chrome中查看最新腳本運行。
性能優(yōu)化
靜態(tài)資源
在 屬性檢查器 里設(shè)置資源雖然很直觀褐墅,但資源只能在場景里預(yù)先設(shè)好拆檬,沒辦法動態(tài)切換洪己。
動態(tài)加載
動態(tài)加載應(yīng)用包內(nèi)的本地資源
通常我們會把項目中需要動態(tài)加載的資源放在
resources
目錄下,配合resources.load
等接口動態(tài)加載竟贯。
-
所有需要通過腳本動態(tài)加載的資源答捕,都必須放置在
resources
文件夾或它的子文件夾下。-
resources
文件夾需要在 assets 根目錄 下手動創(chuàng)建屑那。
-
-
配合
resources.load
等接口動態(tài)加載- 只要傳入相對 resources 的路徑即可拱镐,并且路徑的結(jié)尾處 不能 包含文件擴展名。
// 加載 Prefab resources.load("test_assets/prefab", Prefab, (err, prefab) => { const newNode = instantiate(prefab); this.node.addChild(newNode); }); // 加載 AnimationClip resources.load("test_assets/anim", AnimationClip, (err, clip) => {s this.node.getComponent(Animation).addClip(clip, "anim"); });
resources.loadDir
可以加載相同路徑下的多個資源
// 加載 test_assets 目錄下所有資源
resources.loadDir("test_assets", function (err, assets) {
// ...
});
// 加載 test_assets 目錄下所有 SpriteFrame持际,并且獲取它們的路徑
resources.loadDir("test_assets", SpriteFrame, function (err, assets) {
// ...
});
動態(tài)加載遠(yuǎn)程資源
直接調(diào)用
assetManager.loadRemote
方法
// 遠(yuǎn)程 url 帶圖片后綴名
let remoteUrl = "http://unknown.org/someres.png";
assetManager.loadRemote<ImageAsset>(remoteUrl, function (err, imageAsset) {
const spriteFrame = new SpriteFrame();
const texture = new Texture2D();
texture.image = imageAsset;
spriteFrame.texture = texture;
// ...
});
// 遠(yuǎn)程 url 不帶圖片后綴名沃琅,此時必須指定遠(yuǎn)程圖片文件的類型
remoteUrl = "http://unknown.org/emoji?id=124982374";
assetManager.loadRemote<ImageAsset>(remoteUrl, {ext: '.png'}, function (err, imageAsset) {
const spriteFrame = new SpriteFrame();
const texture = new Texture2D();
texture.image = imageAsset;
spriteFrame.texture = texture;
// ...
});
動態(tài)加載本地設(shè)備存儲資源
直接調(diào)用
assetManager.loadRemote
方法
// 用絕對路徑加載設(shè)備存儲內(nèi)的資源,比如相冊
const absolutePath = "/dara/data/some/path/to/image.png";
assetManager.loadRemote<ImageAsset>(absolutePath, function (err, imageAsset) {
const spriteFrame = new SpriteFrame();
const texture = new Texture2D();
texture.image = imageAsset;
spriteFrame.texture = texture;
// ...
});
Notes:
assetManager.loadRemote
這種加載方式只支持圖片蜘欲、聲音益眉、文本等原生資源類型,不支持 SpriteFrame姥份、SpriteAtlas郭脂、TiledMap 等資源的直接加載和解析。Web 端的遠(yuǎn)程加載受到瀏覽器的 <u>CORS 跨域策略限制</u>殿衰,如果對方服務(wù)器禁止跨域訪問朱庆,那么會加載失敗,而且由于 WebGL 安全策略的限制闷祥,即便對方服務(wù)器允許 http 請求成功之后也無法渲染娱颊。
預(yù)加載
場景預(yù)加載
director.preloadScene("table", function () {
console.log('Next scene preloaded');
});
// 在某個時機調(diào)用loadScene
// 就算預(yù)加載還沒完成,直接調(diào)用 director.loadScene凯砍,預(yù)加載完成后場景就會啟動
director.loadScene("table");
動態(tài)資源預(yù)加載
resources.preload('test_assets/image/spriteFrame', SpriteFrame);
/**
* 開發(fā)者可以使用預(yù)加載相關(guān)接口提前加載資源箱硕,
* 不需要等到預(yù)加載結(jié)束即可使用正常加載接口進(jìn)行加載,
* 正常加載接口會直接復(fù)用預(yù)加載過程中已經(jīng)下載好的內(nèi)容悟衩,縮短加載時間剧罩。
*/
resources.load('test_assets/image/spriteFrame', SpriteFrame, (err, spriteFrame) => {
this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});
分包預(yù)加載
Asset Bundle 中提供了 preload
和 preloadDir
接口用于預(yù)加載 Asset Bundle 中的資源,具體的使用方式和 assetManager
一致座泳。
分包
Asset Bundle 作為資源模塊化工具惠昔,允許開發(fā)者按照項目需求將貼圖、腳本挑势、場景等資源劃分在多個 Asset Bundle 中镇防,然后在游戲運行過程中,按照需求去加載不同的 Asset Bundle潮饱,以減少啟動時需要加載的資源數(shù)量来氧,從而減少首次下載和加載游戲時所需的時間。
Asset Bundle 可以按需求放置在不同地方,比如可以放在遠(yuǎn)程服務(wù)器啦扬、本地中狂、或者小游戲平臺的分包中。
-
自定義 Asset Bundle 是以 文件夾 為單位進(jìn)行配置的扑毡。當(dāng)我們在 資源管理器 中選中一個文件夾時胃榕,屬性檢查器 中就會出現(xiàn)一個 配置為 Bundle 的選項,勾選開啟Bundle分包:
- 定義配置僚楞,點擊面板右上方的 綠色打鉤按鈕勤晚,該文件夾就被配置為 Asset Bundle 的打包預(yù)設(shè)集合了,在放置需要的資源后泉褐,然后在 構(gòu)建發(fā)布 面板選擇對應(yīng)的平臺進(jìn)行構(gòu)建即可得到對應(yīng)的 Asset Bundle。
-
assetManager.loadBundle
API傳入 Asset Bundle 配置面板中的 Bundle 名稱 或者 Asset Bundle 的 url來加載 Asset Bundle
assetManager.loadBundle('01_graphics', (err, bundle) => {
bundle.load(`prefab`, Prefab, function (err, prefab) {
let newNode = instantiate(prefab);
director.getScene().addChild(newNode);
});
// 加載 textures 目錄下的所有資源
bundle.loadDir("textures", function (err, assets) {
// ...
});
// 加載 textures 目錄下的所有 Texture 資源
bundle.loadDir("textures", Texture2D, function (err, assets) {
// ...
});
});
// 當(dāng)復(fù)用其他項目的 Asset Bundle 時
assetManager.loadBundle('https://othergame.com/remote/01_graphics', (err, bundle) => {
bundle.load('xxx');
});
Notes:
在通過 API 加載 Asset Bundle 時鸟蜡,引擎并沒有加載 Asset Bundle 中的所有資源膜赃,而是加載 Asset Bundle 的 資源清單,以及包含的 所有腳本揉忘。
當(dāng) Asset Bundle 加載完成后跳座,會觸發(fā)回調(diào)并返回錯誤信息和
AssetManager.Bundle
類的實例,這個實例就是 Asset Bundle API 的主要入口泣矛,開發(fā)者可以使用它去加載 Asset Bundle 中的各類資源疲眷。
- 釋放 Asset Bundle 中的資源
在資源加載完成后,所有的資源都會被臨時緩存到
assetManager
中您朽,以避免重復(fù)加載狂丝。當(dāng)然,緩存中的資源也會占用內(nèi)存哗总,有些資源如果不再需要用到几颜,需要進(jìn)行釋放
// 方式一、使用常規(guī)的 assetManager.releaseAsset 方法進(jìn)行釋放讯屈。
bundle.load(`image/spriteFrame`, SpriteFrame, function (err, spriteFrame) {
assetManager.releaseAsset(spriteFrame);
});
// 方式二蛋哭、使用 Asset Bundle 提供的 release 方法,釋放在 Asset Bundle 中的單個資源涮母。
bundle.load(`image/spriteFrame`, SpriteFrame, function (err, spriteFrame) {
bundle.release(`image`, SpriteFrame);
});
// 方式三谆趾、使用 Asset Bundle 提供的 releaseAll 方法,釋放所有屬于該 bundle 的資源
bundle.load(`image/spriteFrame`, SpriteFrame, function (err, spriteFrame) {
bundle.releaseAll();
});
- 移除 Asset Bundle
let bundle = assetManager.getBundle('bundle1');
// 釋放在 Asset Bundle 中的單個資源
bundle.release(`image`, SpriteFrame);
assetManager.removeBundle(bundle);
let bundle = assetManager.getBundle('bundle1');
// 釋放所有屬于 Asset Bundle 的資源
bundle.releaseAll();
assetManager.removeBundle(bundle);
資源釋放
資源引用類型:
-
當(dāng)開發(fā)者在編輯器中編輯資源時(例如場景叛本、預(yù)制件沪蓬、材質(zhì)等),需要在這些資源的屬性中配置一些其他的資源炮赦,例如在材質(zhì)中設(shè)置貼圖怜跑,在場景的 Sprite 組件上設(shè)置 SpriteFrame。那么這些引用關(guān)系會被記錄在資源的序列化數(shù)據(jù)中,引擎可以通過這些數(shù)據(jù)分析出依賴資源列表性芬,像這樣的引用關(guān)系就是靜態(tài)引用峡眶。
- Asset Manager 提供了一套基于引用計數(shù)的資源釋放機制,會自動統(tǒng)計資源之間的靜態(tài)引用植锉。
-
當(dāng)開發(fā)者在編輯器中沒有對資源做任何設(shè)置辫樱,而是通過代碼動態(tài)加載資源并設(shè)置到場景的組件上,則資源的引用關(guān)系不會記錄在序列化數(shù)據(jù)中俊庇,引擎無法統(tǒng)計到這部分的引用關(guān)系狮暑,這些引用關(guān)系就是動態(tài)引用。
- 如果動態(tài)加載出來的資源需要長期引用辉饱、持有搬男,或者復(fù)用時,建議使用
addRef
接口手動增加引用計數(shù)彭沼。
- 如果動態(tài)加載出來的資源需要長期引用辉饱、持有搬男,或者復(fù)用時,建議使用
資源釋放類型:
-
自動釋放
自動釋放的優(yōu)勢在于不用顯式地調(diào)用釋放接口缔逛,開發(fā)者只需要維護(hù)好資源的引用計數(shù),Creator 會根據(jù)引用計數(shù)自動進(jìn)行釋放姓惑。
其中褐奴,靜態(tài)引用的資源開發(fā)者不用維護(hù)引用計數(shù),Creator會自動統(tǒng)計于毙。動態(tài)資源引用需要開發(fā)者手動維護(hù)引用計數(shù)敦冬。
-
手動釋放
顯式調(diào)用
release
系列接口可以確保資源本身一定會被釋放。
資源本身不會進(jìn)行釋放檢查唯沮,只有其依賴資源會進(jìn)行釋放檢查
物理系統(tǒng)
物體需要具備完全物理特性的前提條件物體同時具備 剛體 和 碰撞體脖旱,并調(diào)整好其質(zhì)心位置和碰撞體的形狀。
碰撞體
碰撞組件屬性 IsTrigger 決定了組件為觸發(fā)器還是碰撞器烂翰。
-
將 IsTrigger 設(shè)置為
true
時夯缺,組件為觸發(fā)器。觸發(fā)器只用于碰撞檢測和觸發(fā)事件甘耿,會被物理引擎忽略踊兜。
觸發(fā)器不會與其它觸發(fā)器或者碰撞器做更精細(xì)的檢測。
-
默認(rèn)設(shè)置
false
佳恬,組件為碰撞器捏境,可以結(jié)合剛體產(chǎn)生碰撞效果。- 碰撞器與碰撞器會做更精細(xì)的檢測毁葱,并會產(chǎn)生碰撞數(shù)據(jù)垫言,如碰撞點、法線等倾剿。
剛體
碰撞體間定義碰撞發(fā)生的可能性是通過剛體的 Group 屬性筷频,而非 Node 的 Layer 屬性蚌成。
剛體類型
-
STATIC靜態(tài)剛體:
靜態(tài)剛體在大多數(shù)情況下用于一些始終停留在一個地方,不會輕易移動的游戲物體凛捏,例如:建筑物担忧。
靜態(tài)剛體與其他物體發(fā)生碰撞時,不會產(chǎn)生物理行為坯癣,因此瓶盛,也不會移動。
-
DYNAMIC動力學(xué)剛體:
剛體碰撞完全由物理引擎模擬示罗,可以通過 力的作用 運動物體(需要保證質(zhì)量大于 0)
-
僅有動力學(xué)剛體的相互碰撞才有真實世界的效果
- 其中有一個是非動力學(xué)剛體惩猫,相互碰撞沒有真實世界的效果。
-
KINEMATIC運動學(xué)剛體:
它與靜態(tài)剛體類似蚜点,只是靜態(tài)剛體與其他物體發(fā)生碰撞時轧房,不會產(chǎn)生物理行為,而運動學(xué)剛體會對其他對象施加摩擦力绍绘,并在接觸時喚醒其他剛體锯厢。
通常用于表達(dá)電梯這類平臺運動的物體
物理材質(zhì)
物理材質(zhì)是一種資源,它記錄了物體的物理屬性脯倒,這些信息用來計算碰撞物體受到的摩擦力和彈力等。
物理事件
-
觸發(fā)事件
用于檢測兩個物體是否進(jìn)入或離開彼此的觸發(fā)區(qū)域捺氢。
-
這種事件通常用于不需要物理碰撞效果的情況藻丢,例如進(jìn)入一個區(qū)域來觸發(fā)某個效果或行為。
沒有物理反應(yīng):不會導(dǎo)致物理碰撞效果摄乒,如反彈或力的作用
主要用于區(qū)域檢測:常用于檢測進(jìn)入悠反、停留和離開某個區(qū)域的情況
接收到觸發(fā)事件的前提是兩者都必須帶有碰撞組件,并且至少有一個是觸發(fā)器類型馍佑。
-
碰撞事件
用于檢測兩個物體之間的物理碰撞斋否。
-
這種情況通常用于需要物理反應(yīng)的情況,例如角色與障礙物的碰撞拭荤。
有物理反應(yīng):碰撞事件通常會導(dǎo)致物理反應(yīng)茵臭,例如反彈、推力等舅世。
用于物理交互:常用于檢測和處理實際的物理碰撞旦委。
接收到碰撞事件的前提是兩者都必須帶有碰撞組件、都不是觸發(fā)器類型雏亚、至少有一個是非靜態(tài)剛體并且使用的是非 builtin 的物理引擎缨硝。
真實世界碰撞效果
protected shoot(velocity: number) {
// 獲取炮彈
const bulletNode = this.generateBullet(),
bulletRigidBody = bulletNode.getComponent(RigidBody);
// 方向和速度(默認(rèn)前方為 -z 方向,需要反過來)
const direction = bulletNode.forward.negative();
direction.multiplyScalar(velocity);
// 給剛體設(shè)置速度
bulletRigidBody.setLinearVelocity(direction);
}
Notes:
產(chǎn)生真實世界的物理碰撞效果罢低,不應(yīng)該依賴使用
position
的變更產(chǎn)生碰撞查辩,這樣無法產(chǎn)生物理碰撞的動力學(xué)效果。應(yīng)該通過設(shè)置剛體的速度,讓其運動宜岛,與其他剛體產(chǎn)生碰撞长踊,從而產(chǎn)生真實世界的碰撞效果。
射線檢測
射線檢測是對一條射線和非動力學(xué)剛體碰撞組件進(jìn)行相交性判斷
檢測對象需要滿足:
檢測的對象是物理碰撞器谬返,在場景面板上與之對應(yīng)的是碰撞器組件之斯,例如 BoxCollider。
檢測的對象僅支持
STATIC
遣铝、KINEMATIC
剛體類型佑刷,不支持****DYNAMIC
****剛體類型。
// bullet物理引擎測試結(jié)果:
const worldRay = new geometry.Ray(0, -1, 0, 0, 1, 0); // 世界坐標(biāo)下的射線
// 以下參數(shù)可選
const mask = 0xffffffff;
const maxDistance = 10000000;
const queryTrigger = true;
const rayCollision = PhysicsSystem.instance.raycast(worldRay, mask, maxDistance, queryTrigger);
if(rayCollision){
const results = PhysicsSystem.instance.raycastResults;
for (let i = 0; i < results.length; i++) {
const result = results[i];
const collider = result.collider;
const distance = result.distance;
const hitPoint = result.hitPoint;
const hitNormal = result.hitNormal;
}
}
Notes:
射線起點需要是世界坐標(biāo)
node.getWorldPosition(new Vec3())
-
射線穿過平面的邊界時酿炸,浮點運算的精度問題瘫絮,可能會被記錄為多次碰撞。
在某些(如
Bullet
)物理后端中填硕,由于計算精度的原因麦萤,應(yīng)該避免使用比例很高的尺寸,這里建議低于1000扁眯。如某個盒碰撞器壮莹,其 Size 屬性的 Y 值為 40 而 Z 值為 0.01,此時他們的 Y姻檀、Z 的比例超過了 1000命满,此時可能會出現(xiàn)浮點數(shù)計算不準(zhǔn)確的問題。切換物理引擎試試绣版,如
cannonjs
沒有此問題胶台。
粒子系統(tǒng)
-
添加3D粒子系統(tǒng)
- 在[1]層級管理器中右鍵[2]創(chuàng)建特效 —> 粒子系統(tǒng)[3]
-
添加粒子材質(zhì)
- 在[1]資源管理器中[2]右鍵 —> [3]創(chuàng)建 —> 材質(zhì)[4]
- 處理貼圖
使用Photoshop
等DCC設(shè)計工具去除素材的顏色,僅保留明度的信息:
打開圖片: 打開你想要處理的圖片杂抽。
-
去色:
- 依次點擊 圖像 > 調(diào)整 > 去色 或按快捷鍵 Shift+Ctrl+U诈唬,這樣會去除圖像中的所有顏色,僅保留灰度信息缩麸。
-
調(diào)整對比度(可選):
- 為了增強圖像效果铸磅,你可以調(diào)整對比度。依次點擊 圖像 > 調(diào)整 > 亮度/對比度匙睹,進(jìn)行適當(dāng)調(diào)整愚屁。
-
保存圖像:
- 選擇 文件 > 存儲為,保存為你需要的格式(如 PNG 或 JPEG)痕檬。
-
配置粒子貼圖
在資源管理器中選中創(chuàng)建的粒子材質(zhì)霎槐,通過屬性檢查器[1]配置材質(zhì)屬性;
粒子屬性
Effect
設(shè)定為particles/builtin-particle
;展開[4]配置表梦谜,將貼圖資源拖拽到
Main Texture
丘跌,將材質(zhì)貼圖袭景;
Good to know:
-
Effect:用來定義材質(zhì)具體的渲染操作和邏輯的腳本。
它通常由一個或多個著色器(Shader)程序組成
這些程序在 GPU 上運行闭树,負(fù)責(zé)執(zhí)行頂點和像素的處理耸棒。
-
Techniques:定義渲染技術(shù)和流程,每個技術(shù)包含多個渲染階段(Pass)报辱。
-
add
与殃、add-smooth
和premultiply-blend
是常見的混合模式,用于控制不同材質(zhì)的混合方式碍现。
-
Passes:定義具體的渲染階段幅疼,包括頂點著色器和片段著色器。
-
粒子渲染貼圖
在層級管理器中選中添加的粒子系統(tǒng)昼接,在屬性檢查器[1]配置渲染貼圖爽篷;
展開[2]粒子渲染器配置表,將粒子材質(zhì)拖拽到
Cpu Material
[4]慢睡;
文件模板
自定義html構(gòu)建模板
在
cocos creator
編輯器中添加構(gòu)建模版逐工;在代碼編輯器中修改
index.ejs
模板;-
build-templates/web-desktop
目錄下的資源會自動打包到build
目錄中- 在
build-templates/web-desktop
放置ico
圖標(biāo)可以用于修改favicon.ico
- 在
腳本模板
在.creator/asset-template/typescript/CustomComponent
添加腳本模板:
import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;
/**
*
* <%UnderscoreCaseClassName%>
* <%CamelCaseClassName%>
* <%Author%>
* <%DateTime%>
* <%FileBasename%>
* <%FileBasenameNoExtension%>
* <%URL%>
* <%ManualUrl%>
*
*/
@ccclass('Robot<%CamelCaseClassName%>')
export class Robot<%CamelCaseClassName%> extends Component {
start() {
}
update(deltaTime: number) {
}
}
打包
構(gòu)建支持平臺
平臺 | 平臺構(gòu)建插件名 | 支持的特殊文件類型 |
---|---|---|
華為 AGC | huawei-agc | 暫不支持 |
支付寶小游戲 | alipay-mini-game | game.json |
字節(jié)跳動小游戲 | bytedance-mini-game | game.ejs漂辐、game.json泪喊、project.config.json |
OPPO 小游戲 | oppo-mini-game | manifest.json |
華為快游戲 | huawei-quick-game | 暫不支持 |
Cocos Play | cocos-play | game.config.json |
vivo 小游戲 | vivo-mini-game | project.config.json |
小米快游戲 | xiaomi-quick-game | manifest.json |
百度小游戲 | baidu-mini-game | game.json髓涯、project.swan.json |
微信小游戲 | wechatgame | game.ejs复凳、game.json辙浑、project.config.json |
Web Desktop | web-desktop | index.ejs |
Web Mobile | web-mobile | index.ejs |
原生平臺 | native | 暫不支持 |
打包
在[1]項目菜單中選擇[2]構(gòu)建發(fā)布
自定義插屏
場景初始化加載預(yù)覽圖片
通過[1]開啟/關(guān)閉插屏效果改执。
-
點擊[2]可以開啟自定義插屏面板赦邻。
社區(qū)
- 資源商店:查找相關(guān)商品惶洲,下載源碼查看學(xué)習(xí)
- Cocos中文社區(qū):問答社區(qū)
引擎對比
基本情況 | Three.js | Unity3D | Cocos Creator |
---|---|---|---|
定位 | 輕量級3D庫 | 游戲開發(fā)引擎 | 輕量級游戲開發(fā)引擎 |
二次開發(fā)語言 | Javascript開發(fā) | 需安裝Unity編輯器恬吕,C#語言開發(fā) | 需安裝Cocos Creator編輯器,Typescript開發(fā) |
模型來源 | 三方提供渐裂,手動維護(hù) | 三方提供柒凉,手動維護(hù) | 三方提供膝捞,手動維護(hù) |
輔助器 | 提供了各種輔助工具蔬咬,如射線輔助線计盒、坐標(biāo)輔助線 | 提供了部分輔助工具,如射線輔助線 | 沒有輔助工具北启,需要自己通過現(xiàn)有資源模擬 |
小技巧
通過常駐節(jié)點進(jìn)行場景資源管理和參數(shù)傳遞
引擎同時只會運行一個場景咕村,當(dāng)切換場景時懈涛,默認(rèn)會將場景內(nèi)所有節(jié)點和其他實例銷毀批钠。如果我們需要用一個組件控制所有場景的加載埋心,或在場景之間傳遞參數(shù)數(shù)據(jù)拷呆,就需要將該組件所在節(jié)點標(biāo)記為「常駐節(jié)點」茬斧,使它在場景切換時不被自動銷毀项秉,常駐內(nèi)存娄蔼。
// 添加一個節(jié)點的常駐屬性:
director.addPersistRootNode(myNode);
// 要取消一個節(jié)點的常駐屬性:
director.removePersistRootNode(myNode);
Notes:
目標(biāo)節(jié)點必須為位于層級的根節(jié)點,否則設(shè)置無效艘虎。
removePersistRootNode
并不會立即銷毀指定節(jié)點野建,只是將節(jié)點還原為可在場景切換時銷毀的節(jié)點。
Blender使用mixamo處理骨骼動畫
在
github
中直接通過zip包下載源碼-
在[編輯]菜單中選擇[偏好設(shè)置]
在[偏好設(shè)置]面板中選擇[插件]唯鸭。
在[2]選擇
zip
安裝包進(jìn)行安裝目溉,安裝完成后缭付,可在[3][4]的檢索的基礎(chǔ)上看到mixamo
列表項陷猫。-
勾選[5]開啟
mixamo
插件绣檬。
- 在
mixamo
開啟插件設(shè)置
[blender安裝插件:內(nèi)容詳見](https://blog.51cto.com/u_15525868/5468758)
預(yù)覽看不到地形的貼圖
僅僅需要在cocos編輯器中保存一下即可。
概念
引擎:
內(nèi)置完整的工具集,而非生態(tài)擴展
特定領(lǐng)域,而非通用
專門性
運行時:
可以是通用的(如語言運行時)或特定功能的(如游戲引擎運行時)
包括解釋器护糖,解釋和執(zhí)行代碼
Node vs. Component
Node:
Node是 Cocos Creator 中場景的基本構(gòu)建塊嫡良,所有的場景寝受、UI 元素很澄、精靈甩苛、動畫等都是通過節(jié)點來組織和管理的讯蒲。
節(jié)點本身不包含具體的功能或行為墨林,它們只是承載其他組件的容器赞哗。
類似threejs中的Three.mesh
Component:
Component 是附加在節(jié)點上的腳本或功能模塊肪笋,用于定義節(jié)點的具體行為和功能藤乙。
組件不能獨立存在坛梁,它們必須附加到一個節(jié)點上划咐,節(jié)點可以附加多個組件褐缠。
組件決定了節(jié)點的行為和功能。
類似threejs中的Three.geomotry胡桨、Three.material
Prefab(預(yù)制)資源
Prefab(預(yù)制)資源昧谊,作為我們動態(tài)生成節(jié)點時使用的模板揽浙。
cc類
將裝飾器
ccclass
應(yīng)用在類上時馅巷,此類稱為 cc 類稍刀。
- 未聲明
ccclass
的組件類账月,也無法作為組件添加到節(jié)點上局齿。
ccclass
裝飾器的參數(shù)name
指定了 cc 類的名稱抓歼,cc 類名是 獨一無二 的谣妻,這意味著即便在不同目錄下的同名類也是不允許的。
- 類名不應(yīng)該以
cc.
减江、internal.
作為前綴辈灼,這是 Cocos Creator 的保留類名前綴。
組件類裝飾器
ccclass
裝飾器 修飾榕莺,且繼承Component
的子類钉鸯,此類稱為 cc 組件類唠雕。
executeInEditMode
:動態(tài)加載的預(yù)制體
import {
_decorator,
Component
} from "cc";
const { ccclass, property, executeInEditMode } = _decorator;
@ccclass("GameManager")
@executeInEditMode
export class GameManager extends Component {
}
默認(rèn)在層級管理器和場景管理器中看不到動態(tài)加載的預(yù)制體或者動態(tài)創(chuàng)建的節(jié)點 new Node()岩睁,可以通過[@executeInEditMode裝飾器](https://docs.cocos.com/creator/3.8/api/en/function/_decorator.executeInEditMode)
使繼承自組件的ccclass在編輯模式下執(zhí)行。
Notes:
- 使用
@executeInEditMode
執(zhí)行過的ccclass無法還原成未執(zhí)行狀態(tài)刘莹。
executionOrder
:生命周期回調(diào)的執(zhí)行優(yōu)先級
小于 0 的腳本將優(yōu)先執(zhí)行点弯,大于 0 的腳本將最后執(zhí)行。排序方式如下:
對于同一節(jié)點上的不同組件雌团,數(shù)值小的先執(zhí)行锦援,數(shù)值相同的按組件添加先后順序執(zhí)行
對于不同節(jié)點上的同一組件灵寺,按節(jié)點樹排列決定執(zhí)行的先后順序
可以通過組件類裝飾器executionOrder
用來指定腳本生命周期回調(diào)的執(zhí)行優(yōu)先級。
const { ccclass, executionOrder } = _decorator;
@ccclass('Example')
@executionOrder(3)
export class Example extends Component {
}
屬性裝飾器
在編輯器 屬性檢查器 中展示的屬性叮称,屬性名開頭不應(yīng)該帶
_
瓤檐,否則會識別為 private 屬性祭示,private 屬性不會在編輯器組件屬性面板上顯示质涛。
基礎(chǔ)屬性類型
CCInteger
汇陆、CCFloat
、CCBoolean
月趟、CCString
是Cocos Creator
基礎(chǔ)屬性類型標(biāo)識
- 當(dāng)聲明 JavaScript 內(nèi)置構(gòu)造函數(shù)
Number
孝宗、String
因妇、Boolean
用作類型時將給出警告,并且將分別視為 cc 類型中的CCFloat
址芯、CCString
谷炸、CCBoolean
group
分組
當(dāng)腳本中定義的屬性過多且雜時,可通過
group
對屬性進(jìn)行分組描孟、排序匿醒,方便管理。同時還支持對組內(nèi)屬性進(jìn)行分類蜜另。
group
寫法包括以下兩種:
@property({ group: { name } })
@property({ group: { id, name, displayOrder, style } })