动画融合
一个骨骼上存在多个动画时,我们可以使用sp.setAnimation()进行动画播放
但是,直接使用sp.setAnimation()进行播放时,会出现动画切换僵硬的问题,这种痕迹很影响游戏的体验,所以基于spine在Cocos中的API我们可以对两段动画进行融合
什么是动画融合
如图可以看到Idle和Walking之间存在重叠的部分,红线为切换动作时刻,红绿线之间为动作切换时间,这之间动画播放为Idle与Walking的混合,这两两个动画之间会产生一个平滑的过度
融合代码实现(简,无权重)
首先使用一个动画播放管道播放一个动画
this.spine_node.setAnimation(0, 'Idle', true);
这里我获取了Idle的动画时间
getAnimationTimeByName()是我继承sp.Skeleton自定义的方法,在项目中挂载spine的地方都会使用这个继承类
const time = this.spine_node.getAnimationTimeByName('Idle');
/**
* 获取动画时间
* @param name 动画名
* @returns 返回动画时长 s
*/
public getAnimationTimeByName(name: string) {
const state = this.getState();
if (state == undefined) throw `[ERROR SPINE ANIMATION] 无法获取获取动画状态>`;
const { animations } = state.data.skeletonData;
let result = 0;
for (const key in animations) {
if (Object.prototype.hasOwnProperty.call(animations, key)) {
const element = animations[key];
if (element.name == name) {
result = element.duration;
}
}
}
return result;
}
依然使用播放Idle动画的管道,在这个管道后面添加Walking动画,并且延迟两个Idle动画时间后播放(时间可以自定义,他的单位是秒)
this.spine_node.addAnimation(0, 'Walking', true, time * 2);
最后要做的就是进行混合,这一步就是产生红绿线之间的那部分
time指的就是红绿线之间的时间,在此案例中表示的意思就是,在Idle播放第一段时间结束后混合Walking动画,产生一个平滑过渡
this.spine_node.setMix('Idle', 'Walking', time);
完整代码
this.spine_node.clearTracks();
this.spine_node.setAnimation(0, 'Idle', true);
const time = this.spine_node.getAnimationTimeByName('Idle');
this.spine_node.addAnimation(0, 'Walking', true, time * 2);
this.spine_node.setMix('Idle', 'Walking', time);