spine使用BoundingBox實現遊戲中的碰撞檢測

首先允許我用句髒話發泄一下寫這篇文章的心情,當時爲了實現這個功能,查了許多資料,也問了不少所謂的大佬(有好多竟然還不知道spine的這個用法。。。),結果還是模棱兩可,垃圾、垃圾、垃圾!

因爲當時搞這個東西是真的耗費了我不少時間,也可能是我太菜了o(╥﹏╥)o,分享出來方便大家以後少走彎路,話不多說。

需求:

在項目中需要用實現角色的技能,技能的傷害判定一般是由碰撞觸發的,而在這個技能的生命週期中,碰撞框Collider並不一定是固定形狀的,而且由程序手動添加的碰撞組件(BoxCollider、CircleCollider、polygonCollider)並不一定跟技能動畫幀每幀都很切合,所以在spine中有一個邊界框的屬性定義,在動畫師製作技能動畫的時候,可以隨心所欲的勾連與技能動畫碰撞範圍相切合的邊界框形狀,有點類似於polygonCollider,可以勾連任意形狀,所以一個技能的生命週期中,碰撞範圍可以隨意改變。

實現:creator、帶有邊界框的技能動畫(spine)

在場景中新建一節點作爲技能節點,命名爲skillNode,手動添加渲染組件:SpineSkeleton,將技能動畫的.json文件拖入到SpineSkeleton的SkeletonData屬性上,選定一個動作執行,然後新建一個腳本代碼實現,

重點:在腳本的onLoad函數中動態爲技能節點添加polygonCollider組件(也可以在創建skillNode時手動添加,在腳本中獲取該組件)

然後再update函數中更新polygonCollider組件的多邊形頂點數組Points,代碼如下:

onLoad(){

       this.node.addComponent(cc.cc.PolygonCollider);//代碼添加PolygonCollider組件

       this.skillSpine=this.node.getComponent(sp.Skeleton);//獲得spine組件

       this.isSkillingBox=null;//

}

//每幀更新polygonCollider組件的頂點數組

public update(dt: number): void {

            let slots = (<any>this).skillSpine._skeleton.slots;

            for (let i = 0; i < slots.length; i++) {

                let attachmentVertices = slots[i].attachmentVertices;

                if (attachmentVertices.length > 0) {

                    (<any>this).isSkillingBox = attachmentVertices;

                    if ((<any>this).isSkillingBox) {

                        let polCol = this.node.getComponent(cc.PolygonCollider);

                        polCol.offset.x = slots[i].bone.worldX;

                        polCol.offset.y = slots[i].bone.worldY;

                        let collider = this.node.getComponent(cc.PolygonCollider);

                        while (collider.points.length > (<any>this).isSkillingBox.length / 2) collider.points.pop();

                        for (let i = 0; i < (<any>this).isSkillingBox.length / 2; ++i) {

                            if (collider.points[i]) {

                                collider.points[i].x = (<any>this).isSkillingBox[i * 2];

                                collider.points[i].y = (<any>this).isSkillingBox[i * 2 + 1];

                            } else {

                                collider.points[i] = cc.v2((<any>this).isSkillingBox[i * 2], (<any>this).isSkillingBox[i * 2 + 1]);

                            }

                        }

                    }

                    break;

                }

        }

    }

需要注意的是要提前設定好碰撞分組,這樣就可以實現用spine的邊界框來實現碰撞了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章