• RuntimesUnity
  • Problem when assigning SkeletonData to SkeletonAnimation at runtime.

Problem statement

I have a spine project imported in Unity and rendered in a prefab.
That project was recently updated and reimported in Unity.
No error from the importer:

skin_lot_3_ville_Atlas :: Imported with 5 material
Changes to 'Assets/Content/Spine/NPC/City/Lot3/skin_lot_3_ville.json' or atlas detected. Clearing SkeletonDataAsset: Assets/Content/Spine/NPC/City/Lot3/skin_lot_3_ville_SkeletonData.asset

After that, when the prefab assign that skeletonData into the SkeletonAnimation, it's triggering a flood of errors in the console when I run the game.

ArgumentNullException: Value cannot be null.
Parameter name: source
UnityEngine.Material..ctor (UnityEngine.Material source) (at <f7237cf7abef49bfbb552d7eb076e422>:0)
Spine.Unity.SkeletonRenderer.InitSpriteMaskMaterialsForMaskType (UnityEngine.Rendering.CompareFunction maskFunction, UnityEngine.Material[]& materialsToFill) (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:704)
Spine.Unity.SkeletonRenderer.InitSpriteMaskMaterialsOutsideMask () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:692)
Spine.Unity.SkeletonRenderer.AssignSpriteMaskMaterials () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:680)
Spine.Unity.SkeletonRenderer.LateUpdateMesh () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:566)
Spine.Unity.SkeletonRenderer.LateUpdate () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:459)
Spine.Unity.SkeletonAnimation.LateUpdate () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonAnimation.cs:283)
Spine.Unity.SkeletonRenderer.Initialize (System.Boolean overwrite, System.Boolean quiet) (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:427)
Spine.Unity.SkeletonAnimation.Initialize (System.Boolean overwrite, System.Boolean quiet) (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonAnimation.cs:188)
Hotel.Gameplay.NpcModel.<Rebuild>g__Resolve|39_0 (Spine.Unity.SkeletonDataAsset skeletonData) (at Assets/Content/Hotel/Gameplay/NpcModel.cs:230)
Hotel.Utility.AssetUtil+<>c__DisplayClass1_0`1[T].<LoadAsset>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] handle) (at Assets/Content/Hotel/Utility/AssetUtil.cs:31)
DelegateList`1[T].Invoke (T res) (at ./Library/PackageCache/com.unity.addressables@1.21.20/Runtime/ResourceManager/Util/DelegateList.cs:75)
UnityEngine.Debug:LogException(Exception)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at ./Library/PackageCache/com.unity.addressables@1.21.20/Runtime/ResourceManager/Util/DelegateList.cs:79)
UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate() (at ./Library/PackageCache/com.unity.addressables@1.21.20/Runtime/ResourceManager/Util/DelayedActionManager.cs:162)

After digging a bit and comparing to other skeleton it seems to be caused by an empty material in the material list of the SkeletonAnimation

Additional Info : There's a Skeleton Render Separator added to the SkeletonAnimation prefab for the characters. In the prefab, the SkeletonAnimation has mask interaction outside mask set.

The previous version of the spine project did not trigger any error. The difference between the previous one and the one causing the errors is a change from spine 4.1.23 to 4.1.24 and the project is more complex than previous one.

Prefab component: SpineAnimation, MeshRenderer, MeshFilter, Skeleton Render Separator, Custom Script, Box Collider

The code I used to swap the SkeletonData:

skeleton.skeletonDataAsset = skeletonData;
skeleton.initialSkinName = SkinName;
skeleton.Initialize(true, true);

Note that this code was working OK with the previous version of the project.

As I could not solve the issue, I removed all Spine related scripts from the prefab and added them using code. The code above became:

skeleton = SkeletonAnimation.AddToGameObject(gameObject, skeletonData);
GetComponent<MeshRenderer>().sortingOrder = 30;
var slot1 = skeleton.Skeleton.FindSlot("Bras_OL");
var slot2 = skeleton.Skeleton.FindSlot("Jambe_UL");
skeleton.separatorSlots.Clear();
skeleton.separatorSlots.Add(slot1);
skeleton.separatorSlots.Add(slot2);
skeleton.Skeleton.SetSkin(SkinName);
                
_separator = SkeletonRenderSeparator.AddToSkeletonRenderer(skeleton);
_separator.enabled = false;

Using that method, the materials in the mesh renderer don't have an empty value and everything is working correctly but it's less convenient and I can't tweak the prefab using the inspector anymore.

I don't know if the problem came from a feature we used in the spine project or from the upgrade from 4.1.23 to 4.1.24.

Any help would be appreciated.

Runtime information

tried with

Spine 4.1.24
spine-unity Runtime 4.1.21
spine-csharp Runtime 4.1.0
Spine Universal RP Shaders 4.1.21

and the latest to date:

spine-unity Runtime 4.1.27
spine-csharp Runtime 4.1.2
Spine Universal RP Shaders 4.1.40

Related Discussions
...

Spinebot The bot seems to imply that it's a bug in the runtime but maybe I'm missing something and what I do to swap the SkeletonData in the SkeletonAnimation is illegal.

@Ultraspider Sorry that Spinebot's reply wasn't really helpful, I've just deleted it so it doesn't confuse others.

My best guess it that the problem originates from the newly exported skeleton now requiring fewer atlas texture pages than the previously exported one, while your prefab still has references to the old materials, leading to the first entry being set to null since the material and texture with index _6 no longer exists.

You could have a try whether hitting Reload next to the SkeletonData property in the SkeletonAnimation inspector resolves the issue, re-populating the list.

If this does not resolve the issue, and you still see an incorrectly populated list, perhaps the _Atlas asset has not been regenerated and repopulated properly. Could you then please share a screenshot of the _Atlas asset? Please also share a screenshot of the folder that contains your problematic skeleton's textures and materials.

Another typical guess would be that there are leftover .meta files of the materials or textures around, however I doubt that's the case given your Inspector screenshot.

  • Ultraspider ответили на это сообщение.

    Harald Thank you for your answer.

    I can already bring some answers.
    The updated project has the same amount of materials than the previous version. There was never a _6 in the project history.

    When trying to fix the issue, I hit the reload button several time in play mode to see if it made a difference. It did not have any effect.
    I also tried removing materials from the inspector, they are removed but it does not change the flood of error in the console. As soon as I hit reload after removing the materials, they are added back with the None in the first slot.

    Looking at the inspector for the skeleton and atlas I did not see any warnings or anything.
    Here are the folder before and after the project update.

    Except the .private file that I deleted because it was left over by Plastic they are similar.

    And here are the screenshots of the atlas before and after the update. (Sorry they are quite long)

    I don't see anything wrong here.

    • Harald ответили на это сообщение.

      Ultraspider When trying to fix the issue, I hit the reload button several time in play mode to see if it made a difference.

      Why in play mode? You should fix your prefabs and scenes before entering play mode.
      What happens with the prefab if you add it to a scene normally? Does it display correctly, and what happens when you hit Reload?

      Does the preview in the SkeletonDataAsset Inspector display your skeleton normally?
      Can you instantiate the skeleton by dragging it to a scene, and does it display normally then?

      And here are the screenshots of the atlas before and after the update. (Sorry they are quite long)

      Thanks for sharing the screenshots. Unfortunately the resolution is too small to be usable.
      The attachments are not relevant here, could you please just show the top part (with the materials)?

      • Ultraspider ответили на это сообщение.

        Harald Sorry I wasn't aware the picture would be resized.

        Here are the screenshots.

        They look identical before and after the update.

        The reason I'm testing in playmode is because the prefab is a generic NPC prefab and its role is to load the correct SkeletonDataAsset in the SkeletonAnimation it contains to display the right skin depending on the NPC data using the code from my first post.
        I continued testing outside of playmode and was able to pinpoint exactly when the null material is added to the list. It has to do with the Separator Slot Name.
        If I add Jambe_UL in the Separator Slot Names and hit Reload, the null material is added to the list. As soon as I remove it, the null material disappears, even without hitting Reload (and hitting Reload does not add it back at this point)

        This works:

        This does not:

        For a reason I can't explain yet, it does not happen with other slot names. I selected the ones right above and below in the list (Bras_UL or Jambe_OL) and it does not make the null material appear in the list.

        Do you have any idea why a specific slot name in the Separator Slot Names would cause that?
        I don't think I have something special with that slot in the project

        EDIT: the tests above have been done on a "fresh" SkeletonAnimation dragged in the scene from the SkeletonDataAsset, not on my prefab.

        I was able to reproduce the issue in a brand new project containing only the spine asset.
        If you are interested, tell me how to send you that.

        • Misaki ответили на это сообщение.

          Ultraspider Thanks for your detailed report! Please send the repro project to contact@esotericsoftware.com with the URL of this forum thread in the body of the email so we know the context. Then we can take a look at what's wrong.

          • Ultraspider ответили на это сообщение.

            Misaki Hi, the mail has been sent with a Dropbox link to a zip archive.
            Thanks for your help.

            @Ultraspider Thanks for sending the reproduction project. Unfortunately the Unity project just contains an empty scene SampleScene, no prefab, and no other hints on how to reproduce the issue.

            @Ultraspider We have just pushed a bugfix to the 4.1 and 4.2-beta branches. New spine-unity unitypackages are available for download here as usual:
            https://esotericsoftware.com/spine-unity-download
            Please let us know if this resolves the issues on your end as well. Please note that you might need to hit Reload or enable the RenderSeparator once to ensure that the material references and parts renderers are properly populated.

            Thanks for reporting!

            • Ultraspider ответили на это сообщение.

              Harald Hello
              Yes it does solve the issue, I don't have errors in the console anymore even when the material 0 in the list is null.

              Thank you for your help and for the fix release.

              @Ultraspider Glad to hear, thanks for getting back to us.