动画融合
一个骨骼上存在多个动画时,我们可以使用
sp.setAnimation()
进行动画播放
但是,直接使用sp.setAnimation()
进行播放时,会出现动画切换僵硬的问题
如图所示,Idle
在切换Wlaking
过程中出现了明显的切换痕迹
这种痕迹很影响游戏的体验,所以基于spine在Cocos中的API我们可以对两段动画进行融合
如下效果
特别说明一下,这里设置了在两个Idle
时间后执行Wakling
动画
我们可以看到,在Idle
过渡到Walking
时,中间没有切换动画的痕迹
什么是动画融合
如图可以看到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);