Pharan

per-attachment overrides: It's also pretty easy to edit the code to do that. And since this does no serialization, nothing should break.

The material override was working well for you, right?
if (material == a) material = b?
then do per-slot or per-attachment.

Actually, the other way around would work too since the material check would fail if you did the per-slot override too.

-- 12 Mar 2016 2:32 pm --

There's a big cleanup and change to SkeletonRenderer and the SubmeshRenderer system coming so any further changes will probably be there.
https://github.com/EsotericSoftware/spine-runtimes/tree/unity-skeletonrenderer
User avatar
Pharan

Pharan
Posts: 4431

ZimM

Added per-material overrides. Per-slot overrides are still in priority.
https://github.com/EsotericSoftware/spine-runtimes/pull/536
It's not a whole lot of code, so it should be easy to merge anyway.
User avatar
ZimM
Posts: 25

SavedByZero

CustomSlotMaterial seems to be what I'm looking for as well. It almost works; I'm replacing the shirt slot material for one instance of an animation with a pink shirt. I made the material from a single 256x256 pink shirt png, but when I add the CustomSlotMaterial for that one instance, it turns into a 256x256 pink square and just goes on top of his first shirt. What could I be doing wrong with regards to the shader? The Materials settings for the pink shirt are the same as for the materials of the base atlas. I found another shader you put up somewhere called Skeleton Fillable, but that doesn't change anything.
SavedByZero
Posts: 9

Pharan

The texture should be the exact same atlas, not a different texture.
This feature is for using different shaders per slot. Not for using different images.
User avatar
Pharan

Pharan
Posts: 4431

SavedByZero

Then how would I go about, say, sticking a moustache onto the head or a new shirt from a separate image onto the body, when the moustache or shirt comes from a separate image that isn't on the atlas? We very much need this functionality to make our animations as dynamic and interchangeable as possible. Is the only way really to dig into the guts of Spine-CSharp and modify the AtlasAsset.cs code?

P.S.: It looks to me like the shirt actually appears, but it's stretched out to size of the original atlas and rotated sideways (even though the texture properties claim it's the original size). Considering that AtlasAsset uses a Material to draw its pages, it seems like with some wrangling and code changes, this could work. It also seems like it can be a different atlas material without any such changes, as long as the sizes and offsets are the same.

P.P.S: Okay, this is weird. Setting the scale for the new tshirt material (which is supposed to be 256x256) HIGHER actually makes it SMALLER. The original atlas we used for this spine animation was 2048x1024, and the offset of the original shirt was 1034,648. This shirt from outside the atlas now fits perfectly if I scale its material's texture to (8,4) and set its offset to (-4,-0.5). This is obviously not a permanent solution and I know you said this isn't what it was intended to do, but it looks like the system can be twisted to make it so. I'd just like to know the pattern behind this madness. Pixels per unit for all the images was set to 1-1 as well.
SavedByZero
Posts: 9

Pharan

Spine creates a mesh and maps vertex UVs according to where the atlas regions are.
This is how UV mapping works, even with 3D models. If your 3D character had a texture map for all parts, and you replaced the texture just for the torso part, with a texture that was not laid out the same, you would get the same results. A torso mapped to an incorrect location in the texture. The same thing would also happen if you similarly changed the material of a Unity Sprite.

Please see Skins - Spine User Guide and Equips, Customization and Mix and Match for what you're probably trying to do.

In combination with that, see the functionality of the sample SpriteAttacher.cs script module. Spine-Unity SpriteAttacher - YouTube
User avatar
Pharan

Pharan
Posts: 4431

SavedByZero

Thanks. I will definitely look into that. I actually figured out my own method using slot separators; I separated the shirt mesh into its own mesh, added a child mesh to that, copied the properties of shirt A, created a simple material for my outside shirt (shirt B), added it to the child mesh, copied the properties of the original shirt mesh, and then changed the UV coordinates of the child mesh to 0,0;1,0;0,1;1,1, and it worked. Of course, I haven't stress tested it yet and the links you gave could easily be more efficient so I'll look at those now.
SavedByZero
Posts: 9

fmar123

Hey,

Sorry for necroing this thread, but it seemed more appropriate than to start a new one.

I am currently attempting to override a material at runtime ("atlas material"?). We've got it setup so that theres just one material per character but the process of overriding that material still has me scratching me head.

We're using material property blocks, and thats working fine, however, at times the characters in question has got to disable/enable certain shader effects for performance reasons, which is why material property blocks cant be the end all solution, at least in this case.

Initially the shaders were #pragma multi_compile or feature shaders to deal with that, but they don't exactly go hand in hand with Spine, which is shame - so the only option left is to split the shader features into seperate shaders & materials and swapping it out at runtime depending on the situation.

I've seen methods such as GetComponent<SkeletonAnimation>().CustomMaterialOverride.Add(originalMaterial, newMaterial); mentioned, as well as skeletonAnimation.CustomSlotMaterials[slotObject] = material; but it's really unclear to me on how to override the atlas material in an efficient manner.

The Skeleton Custom Materials is nice but seems a bit "hacky" since it loops through all of the slots, if I understand it correctly? It would really like for some references and examples regarding how to best achieve it in C# in an efficient manner especially since it seems to be a topic which pops up every now and then.
Finally,(without having to delve too deep into the structure of spine) arent we looking at a substantial overhead when overriding materials with the way that spine is structured? Overhead is of a concern since we're working a mobile title, and that material swapping will occur quite often).

Hopefully I've just missed or overlooked something.

Thanks
fmar123
Posts: 3

Pharan

What you want is CustomMaterialOverride.
skeletonAnimation.CustomMaterialOverride.Add(originalMaterial, newMaterial);
and if you want to remove it.
skeletonAnimation.CustomMaterialOverride.Clear();
The performance hit there is negligible. You should test it on device to confirm.

The performance hit of CustomSlotMaterial is worse because that's the one that causes it to check every slot because that's what you use for a custom material for a specific slot, rather than the whole thing.

Additionally, if you are using a single material, you can turn on the optional "Use Single Submesh" checkbox.
This skips checking for texture swaps and just uses the first Material it finds for the whole thing.
This is opt-in so that users who use gargantuan multi-page atlases will work by default.

NVIDIA Share_2017-07-26_21-38-45.png



If CustomMaterialOverride bothers you, you can make a separate component that executes a LateUpdate after SkeletonRenderer's LateUpdate (this is when the renderer materials are checked and set), and set your custom material on the MeshRenderer yourself. It's really up to you.
User avatar
Pharan

Pharan
Posts: 4431

fmar123

Thank you for the reply, Pharan.

Another question.

Currently working with SkeletonGraphic in tandem with Unity UI and I've noticed that theres no SkeletonGraphic.CustomSlotMaterials function for setting a slot material to something else.

Is there any other way to go about doing that?
fmar123
Posts: 3

Pharan

For SkeletonGraphic, it's much easier. Just replace the material on the SkeletonGraphic.
That property doesn't update every frame so it won't overwrite your changes.

If you just need to replace the texture, you can set the OverrideTexture property.

It's done this way because this is how the underlying UnityEngine.UI.MaskableGraphic class works with the Unity UI system.
User avatar
Pharan

Pharan
Posts: 4431

fmar123

But how would I go about changing the material for a specific slot using SkeletonGraphic? The method that you mentioned would replace the material for the entire graphic, no?
fmar123
Posts: 3

Pharan

UnityEngine.UI.MaskableGraphic only supports displaying one material.
So sadly, SkeletonGraphic has this limitation too.
User avatar
Pharan

Pharan
Posts: 4431


Return to Unity