3.7.0 如果将spine的缓存模式设置为SHARED_CACHE,就会报offset is out of bounds的错误

新建的空项目,只放了2个spine

测试的 spine 方便发下不?

这个公司有规定,不方便发 :joy:
我觉得可能只要是同一个动画,选择 SHARED_CACHE后,再选择不同的动画名播放,应该都会报错

1赞

你这有没有spine资源的下载网站,我去找几个试下 :joy:

image
我是直接用的这两个简单的 spine 测试,没有复现

没有 :sweat_smile:

你这spine方便发我份,我这试下吗

spine.zip (2.4 MB)

你这个没问题,看来只是我们公司动效做的有问题 :rofl:

应该是初始化申请的顶点buffer 小于 某个动作的需要的顶点buffer
需要两个相同的骨骼测试,一个播放完A动作,另一个在播放A动作,buffer就超了

:joy:,好像这个顶点buffer很容易出问题

@215194780

解决了吗?龙骨有遇到一样的问题

我遇到过,这是美术在做spine时加入了遮罩,用这个缓存模式就会报错 。

1赞

感谢!!!

确实是这个问题,为什么spine有遮罩就会有问题? @215194780

确实,spine 的 json 文件中 clipping 在shared cache 中会有问题

function cacheTraverse (comp: Skeleton): void {
    const model = comp.updateRenderData();
    if (!model) return;

    const vc = model.vCount as number;
    const ic = model.iCount as number;
    const rd = comp.renderData;
    if (!rd || vc < 1 || ic < 1) return;
    if (rd.vertexCount !== vc || rd.indexCount !== ic) {
        if (rd.vertexCount < vc || rd.indexCount < ic) {
            rd.resize(Math.ceil(vc * ADJUST_SIZE_RATE), Math.ceil(ic * ADJUST_SIZE_RATE));
        }
        rd.indices = new Uint16Array(ic);
    }

    ......

    const iUint16Buf = rd.indices!;
    iUint16Buf.set(model.iData as TypedArray);
    
    ......
}

从引擎代码来看,只有 rd.indexCount 和 ic 不匹配的时候,才会执行重新分配,但是 rd.resize 和 indices 新 new 出来的 Uint16Array 长度不匹配,rd.indexCount == rd.indices.length * ADJUST_SIZE_RATE

所以下次执行到这里的时候,如果新的 model.iCount 和 rd.indexCount 相等,就不会进行 resize 这些操作了,但是这时候 rd.indices.length 是比 model.iCount 要少的,所以才会有这个报错吧

所以就是,添加 ADJUST_SIZE_RATE 本来是想要减少重新分配发生的次数,但却导致了这个问题吧?


这是我这里发生的时候相关数据,model.iCount == rd.indexCount == 60 但是 rd.indices.length == 54

EDIT:
抱歉,ADJUST_SIZE_RATE 引入的提交比较近,和 3.7 的这个应该没有关系 :sweat_smile:
https://github.com/cocos/cocos-engine/pull/18936/files 3.8.8 有修复

感谢,这两天优化内存给Spine设置共享缓存,就出了这个问题,按你的提示解决了问题!