动画融合
一个骨骼上存在多个动画时,我们可以使用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');
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);
|