关于Spine动画中SkeletonGraphic无法使用外部图片换肤的研究
最近在研究Spine,项目中有一个需求,希望我们程序能够通过代码实现外部图片直接替换spine动画中的插槽图片进行换肤。
先附上链接
https://www.jianshu.com/p/893cc1dd2838
我参考了该链接的方法,其实现原理是替换对应插槽的附件attachment来实现外部图片换肤的。于是我照着这个方法进行换肤,在使用SkeletonAnimation时是可以实现外部图片换肤的,但是,当我使用SkeletonGraphic时,发现对应插槽的图片没有成功替换,会出现对应插槽贴图消失或贴图错位的情况
上面的截图是我测试使用的spine动画,此时是SkeletonGarphic格式,原本在方框的中间是一个金币,当我使用换肤代码后,整张图集都在方框内了
于是我只能查看spine的源代码,看一看是SkeletonGraphic的渲染过程中哪一步出了问题。
通过查看源代码,我发现SkeletonGraphic和SkeletonAnimation的渲染机制的相似点和不同点,相同点是两者在渲染时都需要调用SpineMesh中生成渲染指令的方法,不同的是他们生成指令的方法不一样,换肤方法对两者产生后果不一样也是出自这里。
SkeletonGraphic在渲染时调用了SpineMesh的MeshGenerator.GenerateSingleSubmeshInstruction方法,该方法会传入一个material参数,该material是指令中第一个Item的material,在SkeletonGraphic后续的渲染中,其所有的slot都使用该指令进行渲染操作,也就是说SkeletonGraphic在渲染时所有slot公用一个material,因此在使用网上的替换attachment方法时,对SkeletonGraphic不适用
那为什么对SkeletonAnimation就适用呢?
原因就是SkeletonAnimation在渲染时调用的是SpineMesh的另一个生成指令方法,叫
MeshGenerator.GenerateSkeletonRendererInstruction,该方法也生成渲染指令,但是,该方法灵活很多,它会对每个插槽分别生成一个指令,而不是生成统一的指令,最重要的是下面这段代码
Material material;
if (isCustomSlotMaterialsPopulated) {
if (!customSlotMaterials.TryGetValue(slot, out material))
material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
} else {
material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
}
每个slot使用的都是对应attachment的material,而不是同一的material
因此,SkeletonAnimation可以使用网上的修改某个插槽的attachment来实现外部图片换肤的功能,
因为每个插槽调用的是各自的attachment的material,互不干扰,我修改了该插槽的附件的材料,那么该插槽
就会调用新的material,使用新的贴图进行渲染了
上一篇: Vue中路由的重定向