初探 Cocos Creator: 碰撞與物理系統

北桥苏發表於2024-03-20

前言

不知道你剛開始玩碰撞時,會不會遇到始終無法觸發碰撞事件?玩物理系統時,自由落體的剛體會穿過 “地面” 剛體等情況?沒錯我全都遇到過,那麼下面我就用紅藍色方塊,簡單實戰一下 Cocos Creator 的碰撞與物理系統。

場景建立

場景很簡單,一個白色背景,兩個紅藍色玩家,和一個綠色大草地。建立的方式也很簡單,全部採用 Sprite 單色。

節點建立

層級管理器 ->Canvas 右鍵 -> 建立節點 -> 建立渲染節點 ->Sprite(單色)。

顏色填充

在屬性檢查器,找到 Node 下的 Color,選擇色盤裡的一顏色即可。

分組

由於物理和碰撞中都要用到,這裡就提前給兩個玩家和綠草地建立分組並分配好。在屬性檢查器的 Node 中,找到 Group 點選編輯再新增,如下圖。

碰撞匹對

將三個分組進行碰撞的匹對,一定要勾選這個,不然後面測試碰撞無法觸發回撥,而是直接穿過另一個物體。

碰撞系統測試

碰撞元件新增

碰撞元件有三種,Box(盒狀)、Circle(圓形)、Polygon(多邊形),可以根據不同的物體形狀選擇對應元件型別,比如像賽車的就可以選盒狀,合成西瓜的那種就可以選圓形。在層級管理器中選中節點,進入屬性檢查器,新增元件,選擇碰撞元件,Box Collider。

引數介紹(Box)

Tag: 用於給在同一節點下,標識不同碰撞元件的

Offset: 碰撞的中心點位置,用於給碰撞範圍定位

Size: 預設是物品節點的大小,其實是物體碰撞的範圍大小

指令碼測試

建立指令碼,開啟碰撞監聽和碰撞範圍繪製 Debug,update 中新增紅色方塊向右移動,設定碰撞產生的回撥。最後拖入節點的屬性皮膚中,前提相關物品都新增了碰撞元件,並且也勾選了碰撞匹對。

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    onLoad() {
        
    }

    start() {
        // 碰撞系統(繪製和監聽開啟)
        var manager = cc.director.getCollisionManager();
        manager.enabled = true;
        manager.enabledDebugDraw = true;
        manager.enabledDrawBoundingBox = true;
    }

    update(dt) {
        this.node.x += dt * 50;
    }

    /**
     * 當碰撞產生的時候呼叫
     * param  {Collider} other 產生碰撞的另一個碰撞元件
     * param  {Collider} self  產生碰撞的自身的碰撞元件
    */
    onCollisionEnter(other, self) {
        console.log("red_collision_enter_1");
    }

    /**
     * 當碰撞產生後,碰撞結束前的情況下,每次計算碰撞結果後呼叫
     * @param  {Collider} other 產生碰撞的另一個碰撞元件
     * @param  {Collider} self  產生碰撞的自身的碰撞元件
     */
    onCollisionStay(other, self) {
        console.log("red_collision_stay_2");
    }

    /**
     * 當碰撞結束後呼叫
     * @param  {Collider} other 產生碰撞的另一個碰撞元件
     * @param  {Collider} self  產生碰撞的自身的碰撞元件
     */
    onCollisionExit(other, self) {
        console.log("red_collision_exit_3");
    }

}

物理系統測試

物理碰撞元件新增

選擇物理元件下的 Box(新增元件 -> 物理元件 ->Collider->Box),碰撞 + 剛體。引數就不介紹了,在編輯器裡懸浮文字就可以看到用法描述,不過 剛體(RigidBody)的 “Type” 需要注意一下。

指令碼測試

指令碼中開啟物理系統才可以看到自由落體效果,而碰撞監聽需要在屬性檢查器的剛體中 “Enabled Contact Listen” 開啟。

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    onLoad() {
        // 開啟物理系統
        cc.director.getPhysicsManager().enabled = true;
        // 物理物品繪製
        /*cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |
            cc.PhysicsManager.DrawBits.e_pairBit |
            cc.PhysicsManager.DrawBits.e_centerOfMassBit |
            cc.PhysicsManager.DrawBits.e_jointBit |
            cc.PhysicsManager.DrawBits.e_shapeBit;*/
    }

    start() {}

    update(dt) { }


    /**剛體的屬性Enabled Contact Listen必須開啟**/
    // 只在兩個碰撞體開始接觸時被呼叫一次
    onBeginContact(contact, selfCollider, otherCollider) {
        console.log("~collider start1111111111111111111111~");
    }

    // 只在兩個碰撞體結束接觸時被呼叫一次
    onEndContact(contact, selfCollider, otherCollider) {
        console.log("~collider end2222222222222222222222222~");
    }

    // 每次將要處理碰撞體接觸邏輯時被呼叫
    onPreSolve(contact, selfCollider, otherCollider) {
        console.log("~pre collider3333333333333333333333333~");
    }

    // 每次處理完碰撞體接觸邏輯時被呼叫
    onPostSolve(contact, selfCollider, otherCollider) {
        console.log("~solve44444444444444444444444444444444~");
    }

}

相關文章