• Unity
  • SkeletonGraphic problem

I have an animation mixing two pictures together. When I used SkeletonAnimation in gameplay everything worked properly and I saw 2 materials on Unity's Inspector window. But when I used SkeletonGraphic to use that animation as the UI, there was a visual error. The material I see now uses only one. Is there a way to fix this problem?

Related Discussions
...
  • 編集済み

As noted on the documentation page on SkeletonGraphic, you have to enable Advanced - Multiple Canvas Renderers:
spine-unity Runtime Documentation: SkeletonGraphic Component
Basically a CanvasRenderer is limited to a single material, this parameter generates multiple CanvasRenderers as a workaround.

6日 後
Harald wrote

As noted on the documentation page on SkeletonGraphic, you have to enable Advanced - Multiple Canvas Renderers:
spine-unity Runtime Documentation: SkeletonGraphic Component
Basically a CanvasRenderer is limited to a single material, this parameter generates multiple CanvasRenderers as a workaround.

Thank you, I have another problem with SkeletonGraphic is that when I use it often I lose the texture but when using SkeletonAnimation everything is normal, something is very strange.

Can you please describe in more detail what you mean by "use it often"? Do you mean that there are many SkeletonGraphic GameObjects in your scene, or do you swap Skins often, do you repack atlas textures often, or something completely different?

Harald wrote

Can you please describe in more detail what you mean by "use it often"? Do you mean that there are many SkeletonGraphic GameObjects in your scene, or do you swap Skins often, do you repack atlas textures often, or something completely different?


Did I do something wrong?

giangnb wrote

Did I do something wrong?

Yes, you posted a screenshot of your code instead of pasting it as

[code]text

[/code]
😉 But your syntax highlighting is nice, so it makes up for that. 8)

Joking aside: In case the SetSkin() line at the bottom of your screenshot is the last one, please add the following code to update the attachments:

skeletonGraphic.Skeleton.SetSlotsToSetupPose();
skeletonGraphic.AnimationState.Apply(skeletonGraphic.Skeleton);
Harald wrote
giangnb wrote

Did I do something wrong?

Yes, you posted a screenshot of your code instead of pasting it as

[code]text

[/code]
😉 But your syntax highlighting is nice, so it makes up for that. 8)

Joking aside: In case the SetSkin() line at the bottom of your screenshot is the last one, please add the following code to update the attachments:

skeletonGraphic.Skeleton.SetSlotsToSetupPose();
skeletonGraphic.AnimationState.Apply(skeletonGraphic.Skeleton);
private void SetSkin(int outfitIdx = 0, int weaponIdx = 0, int idSkin = -1)
   {
       skeletonGraphic.initialSkinName = null;
       skeletonGraphic.Initialize(true);
       if (idSkin == -1)
       {
           var data = skeletonGraphic.skeletonDataAsset.GetSkeletonData(false);
           Skin mySkin = new Skin("Custom Skin");
           //Skin baseSkin = data.FindSkin("skin_base");
           Skin outfitSkin = data.FindSkin("outfit/outfit_" + outfitIdx);
           string weaponName = "sword";
           switch (heroID)
           {
               case 0:
                   weaponName = "sword";
                   break;
               case 1:
                   weaponName = "bow";
                   break;
               case 2:
                   weaponName = "gun";
                   break;
               case 3:
                   weaponName = "weapon";
                   break;
               case 4:
                   weaponName = "spear";
                   break;
               default:
                   break;
           }
           Skin weaponSkin = data.FindSkin("weapon/" + weaponName + "_" + weaponIdx);
           //mySkin.AddAttachments(baseSkin);
           mySkin.AddAttachments(outfitSkin);
           mySkin.AddAttachments(weaponSkin);
           skeletonGraphic.Skeleton.SetSkin(mySkin);
       }
       else
       {
           skeletonGraphic.Skeleton.SetSkin(UtilityGame.GetFullSkinName(heroID, idSkin));
       }
       skeletonGraphic.Skeleton.SetSlotsToSetupPose();
       skeletonGraphic.AnimationState.Apply(skeletonGraphic.Skeleton);
       skeletonGraphic.Update(Time.deltaTime);
   }

I am using Unity 2019.4.8 and Spine 3.8. And the export structure is like the image below, I tried the code you just put, but it doesn't work


I also couldn't find

Advanced - Multiple Canvas Renderers 

at SkeletonGraphic on Inspector

giangnb wrote

I also couldn't find
Advanced - Multiple Canvas Renderers
at SkeletonGraphic on Inspector

I assumed that you enabled this parameter, as you said Thank you, I have another problem with SkeletonGraphic after that suggestion. Without the Advanced - Multiple Canvas Renderers parameter enabled it will not display multiple atlas textures, as said earlier. If your SkeletonGraphic Inspector does not offer this parameter, you are using an old spine-unity package. Please update to the latest 3.8 package listed here:
Spine Unity Download: Download

Harald wrote
giangnb wrote

I also couldn't find
Advanced - Multiple Canvas Renderers
at SkeletonGraphic on Inspector

I assumed that you enabled this parameter, as you said Thank you, I have another problem with SkeletonGraphic after that suggestion. Without the Advanced - Multiple Canvas Renderers parameter enabled it will not display multiple atlas textures, as said earlier. If your SkeletonGraphic Inspector does not offer this parameter, you are using an old spine-unity package. Please update to the latest 3.8 package listed here:
Spine Unity Download: Download

Thank you very much, my above problem has been solved. But I have a performance problem when I load the skin, I have divided the outfit into different textures. When using an outfit I just want the memory to load the set's texture, but it seems Unity is loading all the skins I have. Will Unity load all the materials in Atlas asset? Can you give me the solution, thanks

Glad your initial problem could be resolved.

Regarding loading all skins in an Atlas: Unfortunately Unity loads all referenced assets automatically. We have such partial on-demand loading on the radar, unfortunately it will take some time until we get to this task.

One workaround in the meantime would be to use a Resources.Load() / Resources.Unload based workflow.
This forum thread here describes how you can programmatically load an entire SkeletonDataAsset programmatically:
How to dynamically load/unload Skeleton Data Assets

When you only want to load Textures, you could adapt this method as follows:
First gather all original Material references of the Atlas in the Editor and save away the path strings.
Then create a cleared copy of the Atlas asset for runtime use.
Then when switching to the required skins, load the required Material and Texture, and unload no longer needed ones.