发现一个spine的BUG

如果Spine设置为Cache模式,然后在预制体中默认播放某一个动画。那在代码中使用setAnimation手动播放一个动画,cache模式会无限制的添加帧直到超过上限MaxCacheTime。

具体表现为,如果这是个循环播放的动画,动画播放完存在的帧数后就会卡住。

简单跟踪了一下堆栈,发现是因为skeleton-cache.js方法中updateToFrame方法

updateToFrame (toFrameIdx) {
    if (!this._inited) return;

    this.begin();

    if (!this._needToUpdate(toFrameIdx)) return;

    let skeletonInfo = this._skeletonInfo;
    let skeleton = skeletonInfo.skeleton;
    let clipper = skeletonInfo.clipper;
    let state = skeletonInfo.state;

    do {
        // Solid update frame rate 1/60.
        skeleton.update(FrameTime);
        state.update(FrameTime);
        state.apply(skeleton);
        skeleton.updateWorldTransform();
        this._frameIdx++;
        this._updateFrame(skeleton, clipper, this._frameIdx);
        this.totalTime += FrameTime;
    } while (this._needToUpdate(toFrameIdx));

    this.end();
},

end中的结束判断

end () {
    if (!this._needToUpdate()) {
        // clear cur animation cache
        this._skeletonInfo.curAnimationCache = null;
        this.frames.length = this._frameIdx + 1;
        this.isCompleted = true;
        this.unbind(this._skeletonInfo.listener);
    }
},

_needToUpdate永远是true,导致引擎不会将这个spine动画标记为完成。

_needToUpdate (toFrameIdx) {
    return !this.isCompleted && 
            this.totalTime < MaxCacheTime && 
            (toFrameIdx == undefined || this._frameIdx < toFrameIdx);
},

感觉应该是在预制体中设置播放的动画,没有进行过缓存的初始化,导致这个动画找不到结束的索引id,导致无限制的进行扩展,直到突破上限。(当然,以上的只是推测,问题是这么个情况,但代码逻辑上可能不是我说的那样)

另外,我使用了3.8的引擎,里面的spine也会有同样的问题。

以上问题只会出现在我已经将东西拖到了预制体中直接用的情况。
使用代码,手动进行prefab的cc.instantiate是不会出问题的。

应该是使用方法不对,和是否为缓存无关。
因为播放的代码是放在了节点的start中,这个时候节点内部的spine还没有完成初始化,因此这个时候没法进行播放。改为延时一帧去播放就可以了