Yeah, we have this in a list of things to investigate for Spine-Unity.
Per attachment override is actually currently "easier", but you need to do some kinda-silly things so SkeletonRenderer has what it needs.
RegionAttachment
, MeshAttachment
and SkinnedMeshAttachment
have a System.Object rendererObject
field: https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-unity/Assets/spine-unity/SkeletonRenderer.cs#L229
That's supposed to be a generic reference in Spine-C# but in Spine-Unity, it's specifically a reference to a Spine.AtlasRegion
. And it goes down slightly deep in references:
regionAttachment.rendererObject.page.rendererObject;
the first .rendererObject
is the AtlasRegion. You need to cast it to get to its members.
.page is an AtlasPage.
the second .rendererObject is a UnityEngine.Material.
So concievably, if you could create a dummy AtlasRegion and AtlasPage, and do a deep-copy only of the data it needs, you can have each attachment have its own material, and SkeletonRenderer will treat it correctly as a material change. (I'm sure you're familiar with that system already)
You'll find this in practice in another form in SpriteAttacher.cs
//create faux-region to play nice with SkeletonRenderer
atlasRegion = new AtlasRegion();
AtlasPage page = new AtlasPage();
page.rendererObject = mat;
atlasRegion.page = page;
SpriteAttacher is actually an example of how you don't actually need to do a deep copy at all since none of the atlas data is used for actual rendering except for the material reference, since all the rendering-relevant data like UV offsets is already on the Attachment object itself.
For a per-skeleton override, I made that short script which basically just went down the list of sharedMaterials in MeshRenderer and replaced them as needed. I forgot the Unity magic method I used, but it was performed after LateUpdate but before actual rendering happened. I also can't find that script, but it's in the forums somewhere.