Spine加载外部图片换装不穿帮的方案

有一个人物换装的需求,比如换鞋子、换上衣、裤子、外套,做一套骨架动画,里面很多节点。
我知道可以使用 spine.setSlotTexture 来替换纹理。但是很多形状不一样的纹理(拿鞋子来说,有长鞋、短鞋、胖鞋、瘦鞋),如果直接替换,动画很大几率是会穿帮的。
如果不想穿帮,需要在插槽里面针对这个图片进行网格调整,这样骨架的json数据就无法通用。

针对这个换装需求,请教各位大佬,最佳实践是怎样的?

你是要把整个项目外包?

图片都会有锚点,感觉你不是游戏开发者。(没用过spine)

类似的游戏,你可以玩一下奇迹暖暖

锚点只是控制位置,应该不够的,要网格处理,但是网格数据是在骨架上

锚点可以解决高度问题或者宽度问题,只能解决其中一个,另一个就是自己适配。如果全都有变换,例如要给不同胖瘦的人穿衣服,可以生成不同的图片,否则那就是3D了

3D给材质贴图,是分割成碎图的方式。

楼主说的是否是spineregionAttachment而不是meshAttachment 后者是带网格形变的一般不会拿来做局部换装需求而是用setSkin整体换装

如果只是普通贴图就算是用外部图片换装也没事的 只要不带offset 和美术沟通一下就行 就说要求附件拖进插槽里不需要再调偏移 让图片的锚点定在一个位置(这个应该不难理解吧)

有一种方案是 将其他同骨架的Spine文件的插槽 设置到当前自身动画中 优点是可以使用Spine软件中用到的所有功能 缺点是 你将会拥有多个Spine文件

这个 3.8.4支持吗?还是需要修改引擎?是哪个api呢?

我说的是在网格的形变,如果要追求极致效果,是要用网格的,普通贴图可能满足不了

我们美术给部分插槽加了mesh,这些插槽在用外部图片换装时会出问题 :sob:

加了mesh网格形变的外部图片换装包出问题 这是一定的 除非另外储存好相关的数据在换装的时候再还原

没用网格但是每个图片的offset不一样 不也得写个映射储存数据吗

我特意让美术出一样大小的图片,offset是一样的吧

offset要看美术有没有动图片的位置的 就是美术在spine里把图片拖入到插槽后 每个图片还有没有调整坐标

好的谢谢,我找美术问一下。

/**

 * 替换当前皮肤的所有插槽

 * @param ani 当前spine对象

 * @param skinName  需要替换的皮肤动画

 * @param Slots 需要清理的骨骼

 */

changeSkinSlot(ani: sp.Skeleton, skinName: string, slots: { [key: string]: string[] }, target: sp.Skeleton = null) {

    let skeletonData: sp.spine.SkeletonData = null;

    let skin: sp.spine.Skin = null;

    if (target) {

        skeletonData = target.skeletonData.getRuntimeData();

        skin = skeletonData.findSkin(skinName);

    } else {

        skeletonData = ani.skeletonData.getRuntimeData();

        skin = skeletonData.findSkin(skinName);

    }

    if(skin==null){return  console.log("skin 为空",skinName)}

    if(skin.attachments){

        skin.attachments.forEach((value , index)=>{

            let name = '';

            let attachment = null;

            console.log(value)

            if(value.attachment){

                let skinAttachment = value

                name = skinAttachment.name;

                attachment = skinAttachment.attachment;

            }

            else{

                name = Object.keys(value)[0];

                attachment = value[name];

            }

            let slot: sp.spine.Slot = ani.findSlot(name) || ani.findSlot(attachment.name);

            slot && slot.setAttachment(attachment);

        })

        ani.invalidAnimationCache();

    }

}

直接上代码吧 大致原理就是将武器制作为一款皮肤 查找目标皮肤上的插槽 然后进行替换
这里有几个注意点 :

  1. 目标spine 与 我方spine的 骨架相同
  2. 插槽名称相同 因为需要进行查找相同的插槽然后进行插槽数据替换
  3. 因为每个皮肤用到的插槽数量不一致 所以你需要清除上次设置的所有皮肤插槽 避免出现多余的插槽数据
1赞

因为保密问题 我无法给你 展示实际效果 不过这个方式是可行的 我看到3.8.4中的代码TS里也没暴露出 attachments 中的 attachment属性 那么在手机端 你大概就需要 自己修改引擎 接口暴露出来使用

这里的技术难点就是 骨架的一致性 骨架不一致会导致 网格权重变形 会出现错误显示

image
插槽的名称最好与衣架名称一致 这样方便查找

题目你是一点不看 注意审题啊少年