• Unity
  • Lots of materials in inspector

  • Изменено
Related Discussions
...

Hello
Our project was starting use Spine last month
But there is some weird thing happen
Our character has 3 textures(using texture pack in spine)
and has a json file generated by export

when I import to unity,
it generate 3 material and a normal atlas(in atlas it also has 3 material)
at this step it's all go great

but when I assign SkeletonData to SkeletonAnimation
it got about 911 material in inspector with repeat materials(numbers are due to the animation that playing)
mat0, mat1, mat0, mat2, mat0 <= like this

and this sometime makes character glitch when setanimation about 1 frame
like head material using body material
I think it may relate to the above problem, because setanimation switching order and numbers of materials

anyway I think in inspector, it should be only 3 material and no repeat
can someone gives some help?
thanks

ps: English is not my first language, may have some grammar wrong using

This is a render pipeline thing, that's true for Unity and true for any other engine that needs to use DirectX/OpenGL.

When the game engine needs to render a piece from a different texture, it needs to give extra commands and/or new data to the graphics card. That's what each material in the array represents.

So when your Skeleton's draw order requires that you render:
head parts from tex1, then
arm parts from tex2, then
torso parts from tex1, then
leg parts from tex3, then
arm parts again from tex2

You'll get a list of mat1, mat2, mat1, mat3, mat2.

Each time it needs to switch textures, it needs a new material in the array.

So.
(1) It's not a bug. This is how rendering code needs to work. Pretty much anywhere. Not just Spine. Not just Unity.
(2) It doesn't mean your asset files are being duplicated. This has nothing to do with that. It only represents the number of times the MeshRenderer has to switch between materials/textures.
(3) If there's enough items in that list, it CAN slow down your game. Because sending extra instructions to the GPU does have a bit of cost.
If it's only 10 or 15 material items there for your one main character, don't worry about it. That's not a big deal. Even on mobile.
If this character is spawned several times, consider packing 1 large texture instead of 3 small ones. Because 120 draw calls instead of 8 is arguably not okay.

Also for reference to anyone else reading this in the future: How to use the multi materials in a character ?

ok, that's make sense
Now I don't mind about the draw pipeline thing

but I can't solve the issue that
when change animation
there's one frame has wrong materials for each part
like unity render the result before materials order changes
if this can be solve, all thing will go well

In our project we need assetbundle
and need to change lots weapons and equipments
so we can't let users to download lots of big and repeat one texture for character
otherwise if we only use 1, it could be weapons * equipments * otherparts
and packing textures will be very tired
then if one day we need to add one part of character
this workflow will go all over again

if anyone has better solution then using 3 texture
please let us know
thanks

That's an interesting bug.

If they're not too large, do you have permission to send your assets (json, pngs and atlases) to unity@esotericsoftware.com for testing?

sorry I don't have permission to do that, we use inner-net in company

but I found why this happened
it is because two "setanimation" are too close
our character from idle to move then suddenlly stop move and back to idle
will cause this glitch happen

if the gap is a little bit long, it goes well
but we don't want animation has any delay

does not try others yet
maybe any of those animation doing this "suddenlly switch" will cause the bug


I temporally use
lastFrameCount > Time.frameCount +1 to prevent this issue now
tested and sure it happen when setanimation has 1 frame gap
like 28frame and 29frame have setanimation fired
hope this can be fixed in future runtime
this is troubling, because I have to add this line to every setanimation method fired place in scripts

That's ok. Thanks for sharing your observations! That's really helpful for fixing the runtime.

Are you using mixing for your animations? (in its SkeletonDataAsset: are you setting any mixes? is Default Mix > 0?)
Are you animating Draw Order?

A tip for your temporary fix:
Instead of adding the line everywhere you have SetAnimation, just replace all your SetAnimation calls to a wrapper method that does the check.
Imagine a method similar to:

public TrackEntry TrySetAnimation (int trackNumber, string animationName, bool loop)
{
     if (lastFrameCount > Time.frameCount + 1) {
          skeletonAnimation.state.SetAnimation(trackNumber, animationName, loop);
     }
}

So you can call TrySetAnimation instead of directly calling SetAnimation.