首先允許我用句髒話發泄一下寫這篇文章的心情,當時爲了實現這個功能,查了許多資料,也問了不少所謂的大佬(有好多竟然還不知道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的邊界框來實現碰撞了