• RuntimesUnity
  • Skeleton stops rendering attachments after scene change in unity runtime

Hello! I need help, I'm having a weird behavior in the a skeleton. We have character customization, so we created many skins in one 4k atlas, in unity, through code I load the default or player's character customization changing the skeleton skins.
First time in level, it all looks normal(img 1). But as soon as player goes to lobby, then back to a mission on another level the skeleton either stops rendering the eyes or maybe it is rendering them in behind the hoodie?(img 2)

Every time the character spawns / respawns it loads the customization.
we have the default skin, which is the hoodie hole and laces and eyes, then we have folders to organize the rest of the skins, Bottoms (all pants, shots, skirts),hoodies, etc..
The weird part is that when this bug appears in game, it also affects the skeleton in unity, so, in the editor preview, I cannot see the eyes and hoodie hole either.

Do you have an idea of what could be causing this?
We've tested setting the default as the last skin but it renders the hole over the eyes(img3), we are also exploring to check if there's a skin that might be overwriting the eyes and hole, but this doesn't seem to be the case

Thanks!


    Related Discussions
    ...

    It sounds like you are experiencing a draw order issue or a problem with the skin setup in Unity. Here are a few steps you can take to troubleshoot and potentially resolve the issue:

    1. Check Draw Order: Ensure that the draw order of your attachments is correct. Sometimes, attachments might be rendered behind others due to incorrect draw order settings. You can adjust the draw order in the Spine editor and ensure it is correctly exported to Unity.

    2. Skin Setup: Verify that your skins are set up correctly and that no attachments are missing or incorrectly assigned. You can use the SkeletonData asset Inspector preview in Unity to switch between skins and check if all attachments are visible.

    3. Re-import Assets: Try re-importing your assets in Unity. Sometimes, re-importing can resolve issues related to asset corruption or incorrect import settings. You can do this via Assets -> Reimport.

    4. Check for Warnings: Open the skeleton's project in the Spine editor and check for any warnings related to skins. Warnings can provide valuable information about potential issues with your skin setup. Refer to the Spine User Guide on skin warnings for more details.

    5. Material Settings: Ensure that your material settings and shaders are correctly configured. Incorrect material settings can cause rendering issues. Check the material settings in the Inspector and ensure they are consistent with your other working setups.

    6. Advanced Settings: If you are using Universal Render Pipeline (URP) or other advanced rendering settings, ensure that they are correctly configured. Enabling Advanced - Fix Draw Order at your SkeletonAnimation component might help resolve draw order issues.

    If none of these steps resolve the issue, you might need to create a minimal Unity project that reproduces the problem and send it to Esoteric Software for further investigation. This will allow them to diagnose the issue more accurately.

    DunkelBlume Have you tried adding a SortingGroup component?

    This description in the documentation does not apply to your case since you mentioned that the skeleton images are packed into an atlas (presumably you mean the atlas texture page), but many problems with incorrect sorting can be solved by simply adding this component, so please try it if you have not already done so.

    DunkelBlume But as soon as player goes to lobby, then back to a mission on another level the skeleton either stops rendering the eyes or maybe it is rendering them in behind the hoodie?(img 2)

    How exactly do you switch between your level (where it displayed correctly the first time) and the lobby, and back again? What loading actions regarding skeletons do you perform at these transitions?

    How is your problematic skeleton instantiated? Is it instantiated programmatically, and if so, how?
    Is it destroyed when you unload your level and switch to the lobby?
    Or is the skeleton loaded as fixed part of the scene?

    A call which often is missing is calling skeletonAnimation.Skeleton.SetSlotsToSetupPose(); after setting your skin, however in your case I'm afraid that's not the problem.

      Harald
      Hi, so yeah. This is the code I use to load character customization

      public void LoadPlayerCustomization()
      {
          Skin newSkin = new Skin("new-random-skin");
          // Skin color
          if (characterCustomization.SkinColorSkinName != null && characterCustomization.SkinColorSkinName != "")
              newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.SkinColorPrefixes + characterCustomization.SkinColorSkinName));
          if (DragonTailObject != null)
          {
              if (characterCustomization.HoodieSkinName.Contains("Dragon"))
              {
                  if (!isCutsceneCharacter)
                  {
                      DragonTailObject.SetActive(true);
                      IsDragonTailActive = true;
                  }
                  else
                  {
                      newSkin.AddSkin(introvertSkeletonData.FindSkin(DragonTailSkinName));
                  }
              }
              else
              {
                  IsDragonTailActive = false;
                  DragonTailObject.SetActive(false);
              }
          }
          // Bottoms
          newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.BottomsPrefixes + characterCustomization.BottomsSkinName));
          // Hoodie
          newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.HoodiePrefixes + characterCustomization.HoodieSkinName));
          // Feet
          newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.FeetPrefixes + characterCustomization.FeetSkinName));
          // Accesories
          if (characterCustomization.AccessoriesSkinName != null && characterCustomization.AccessoriesSkinName != "")
          {
              newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.AccessoriesPrefixes + characterCustomization.AccessoriesSkinName));
          }
          // Power ups
          if (characterCustomization.PowerUpSkinName != null && characterCustomization.PowerUpSkinName != "")
          {
              newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.PowerUpPrefixes + characterCustomization.PowerUpSkinName));
          }
          // Default skin hold the hoodie hole, laces and the eyes
          //newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.defaultSkin));
          characterSkeleton.skeleton.SetSkin(newSkin);
          characterSkeleton.skeleton.SetSlotsToSetupPose();
      }

      Some more info:
      No draw order keyed
      No blending for the hole and laces
      Attachments are active by default, deactivated/activated in the animations only
      The skeleton is in a DontDestroyOnLoad. We load scenes async and trigger an event to notify stuff that player has "respawn". The Skeleton also listens to this and reloads character customization.

      The weird thing is that when this bug appears, it also bugs the skeleton asset in unity editor as shown in the gif.

      And recently I found that clicking the reload button of the skeleton in the inspector, reactivates the eyes, but! I don't know how to do that on runtime by code

      Or maybe there's a cache that needs to be cleared?

      @DunkelBlume Thanks for the additional info. Noticing the commented-out line:

      // Default skin hold the hoodie hole, laces and the eyes
      // newSkin.AddSkin(introvertSkeletonData.FindSkin(CharacterCustomizationSkinsPrefixes.defaultSkin));

      If you repack the skin to a single atlas texture, you would want to add the default skin as well. Note that there is no need to call FindSkin for the default skin. Unless CharacterCustomizationSkinsPrefixes.defaultSkin is something special, you can just use:
      newSkin.AddSkin(introvertSkeletonData.DefaultSkin);
      If you don't repack the skin, you can omit the line as the default skin is already automatically "added" to the skeleton.

      My following questions from my posting above remain:
      How is your problematic skeleton instantiated? Is it instantiated programmatically, and if so, how?
      Is it destroyed when you unload your level and switch to the lobby?
      Or is the skeleton loaded as fixed part of the scene?

      I forgot to mention, I commented those lines cause then it renders the hole and laces on top of Eyes, and I tried the correct way you mentioned, but no different results.

      The skeleton is part of the player prefab, which is instantiated via code
      GameObject newObject = Instantiate(prefab).gameObject;

      And the prefab is in a DontDestroyOnLoad.
      And the bug it is very consistent

      1. Player prefab loads on first opened level, al works perfect. Prefab is set to DontDestroyOnLoad,
      2. When player finishes level the system loads asyncronously another scene(Room/lobby).
      3. when the new scene is loaded it notifies the prefab and it reloads character customization. Character looks normal, no problems with the eyes and hoodie
      4. when player selects and enters the next level, it loads async
      5. when the new scene is loaded it notifies the prefab and it reloads character customization, but now character doesn't show the eyes and sometimes doesn't show the hole and laces.

      Now, during gameplay there are some animations that deactivate/activate the problematic attachments

      • Harald がこの投稿に返信しました。

        Thanks for the additional info.

        DunkelBlume Now, during gameplay there are some animations that deactivate/activate the problematic attachments

        If perhaps some animations are not mixed out (they end without an empty animation being played afterwards via e.g. AddEmptyAnimation) or even still playing, this might explain the issue. Then you might want to call AnimationState.ClearTracks() when loading a new level to remove any animations which still remain at any tracks, and then call Skeleton.SetToSetupPose() to clear all slots, bones, constraints and draw order.

        If this still does not resolve your issue, could you perhaps send us a minimal Unity project which still shows this issue? You can send it as a zip file to contact@esotericsoftware.com, briefly mentioning this forum thread so that we know the context. Then we can have a look at what's going wrong.

        Thanks!!! that solved the issue!!!

        @DunkelBlume Very glad to hear, thanks for letting us know!