• Unity
  • How to dynamically load/unload Skeleton Data Assets

Hey!

I'm currently working on a game based on hundreds of cards (look like polaroid pictures).

Screenshot:

The foreground (vulture) and background (recording studio) are both Spine Skeletons. We want the photos to animate.

The problem is:
We have a lot of characters and backgrounds for the pictures so we need to load and unload them because of memory management. Some of them have got pretty big atlases.

When the background is an static image file I can use:

Texture2D texture;

void LoadTexture() {
    texture = Resources.Load<Texture2D>("Art/Backgrounds/Spine/garage/garageHD");
}

void UnloadTexture() {
    Resources.UnloadAsset(texture);
}

Everything works fine. The textures are properly loading and unloading from memory.

I would like to use similar code for Spine Skeletons. I created this one:

private GameObject createdSkeletonObject;

void LoadSkeleton() {
    var skeletonDataAsset = Resources.Load<SkeletonDataAsset>("Art/Backgrounds/Spine/studio/studio_SkeletonData");
    
var newSkeleton = Instantiate(gameObject); newSkeleton.AddComponent<SkeletonAnimation>(); newSkeleton.GetComponent<SkeletonAnimation>().skeletonDataAsset = skeletonDataAsset; newSkeleton.GetComponent<SkeletonAnimation>().Initialize(true); createdSkeletonObject = newSkeleton.gameObject; } void UnloadSkeleton() { var meshRenderer = createdSkeletonObject.GetComponent<MeshRenderer>(); Resources.UnloadAsset(meshRenderer.material.mainTexture); Destroy(createdSkeletonObject); }

The problem is. I can load the animation and I can unload it, but only once. When I want to load the same Skeleton Data Asset once again I do not see it on the screen. In hierarchy, everything looks fine.

Do you know how can I solve this problem? Maybe another way of unloading textures? I wanted to unload whole Skeleton Data Asset, but it does not disappear from the memory.

Related Discussions
...

Thanks for the detailled writeup. Actually it should work to unload the whole SkeletonDataAsset and would be the proper way.

Strangely it seems as if Unity either has changed behaviour between Unity 2017.1 and 2019.2 in regards to resource unloading, or they have simply fixed a bug: If I add a call to Resources.UnloadUnusedAssets(); at the end of the UnloadSkeleton() method, I see the expected behaviour in the 2019.2 profiler:

In contrast, in Unity 2017.1 the profiler did not show any effect on the allocated texture memory.
So either the profiler showed incorrect data in 2017.1 or the texture unload did not happen.

I have not tested other Unity versions, but I would suggest you either perform some tests on the target device with the real executable, or upgrade to a Unity version where the behaviour seems to be as expected. A third solution would of course be to change from a Resources workflow to a different one, e.g. using AssetBundles, etc, if this is possible.

For easier testing, the full unload code used is as follows:

void UnloadSkeleton () {
   Resources.UnloadAsset(skeletonDataAsset);
   skeletonDataAsset = null;

   Destroy(createdSkeletonObject);
      
Resources.UnloadUnusedAssets(); }

Hope this helps.

Hey Harald,

thank you for your post - it worked like a charm!
Everything is tested on the target device and works as it should be.

Hey, yery glad to hear, thanks for letting us know!

trafcio wrote

Everything is tested on the target device and works as it should be.

May I ask which Unity version worked in the end - did you stay at your version or did you have to upgrade? Just asking because this may be very valuable information for other Spine users. Thanks in advance!