SpriteSkin rootBone and boneTransforms can not be edited at runtime

I want to assign UnityEngine.U2D.Animation.SpriteSkin to my gameObject programmatically.
My object has SpiteRenderer. I assign Sprite with configured bones to it.
After that, I create the Sprite bones structure using the code I copied from UnityEngine.U2D.Animation.SpriteSkinUtility.CreateBoneHierarchy

var spriteBones = spriteRenderer.sprite.GetBones();
        var boneTransforms = new Transform[spriteBones.Length];
        Transform rootBone = null;
        for (var i = 0; i < spriteBones.Length; ++i)
        {
            CreateBoneGameObject(i, spriteBones, boneTransforms, transform);
            if (spriteBones[i].parentId < 0 && rootBone == null)
            {
                rootBone = boneTransforms[i];
            }
        }

static void CreateBoneGameObject(int index, SpriteBone[] spriteBones, Transform[] transforms, Transform root)
    {
        if (transforms[index] != null) return;
        var spriteBone = spriteBones[index];
        if (spriteBone.parentId >= 0)
        {
            CreateBoneGameObject(spriteBone.parentId, spriteBones, transforms, root);
        }

        var go = new GameObject(spriteBone.name);
        var transform = go.transform;
        if (spriteBone.parentId >= 0)
        {
            transform.SetParent(transforms[spriteBone.parentId]);
        }
        else
        {
            transform.SetParent(root);
        }

        transform.localPosition = spriteBone.position;
        transform.localRotation = spriteBone.rotation;
        transform.localScale = Vector3.one;
        transforms[index] = transform;
    }

After that I add SpriteSkin to my object

var spriteSkin = GetComponent<SpriteSkin>();
        if (spriteSkin == null)
        {
            spriteSkin = gameObject.AddComponent<SpriteSkin>();
            spriteSkin.enabled = true;
        }

But SpriteSkin properties rootBone and boneTransforms are internal and cannot be changed.

I was still able to change them using reflection like this:

var rootBoneProperty = typeof(SpriteSkin).GetProperty(nameof(SpriteSkin.rootBone));
        rootBoneProperty!.SetValue(spriteSkin, rootBone, BindingFlags.NonPublic | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture);
        //spriteSkin.rootBone = rootBone;

        var boneTransformsProperty = typeof(SpriteSkin).GetProperty(nameof(SpriteSkin.boneTransforms));
        boneTransformsProperty!.SetValue(spriteSkin, boneTransforms, BindingFlags.NonPublic | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture);
        //spriteSkin.boneTransforms = boneTransforms;

After that, I add the Animator component to the object, and the animation works as expected.
But that’s probably not the best solution.

Am I missing some obvious way of setting SpriteSkin data at runtime,
Or programmatically changing bones is not supported intentionally?

3 Likes

Although a bit brute force, I was completely unable to find any other solution. This broke me through a wall I didn’t think I could make it through. Thanks so much!

You should be able to edit the bone information via UnityEngine.Sprite. Even though the GetBones and SetBones methods aren’t documented they are public functions.

I am not sure why Unity devs didn’t opted to have wrapper functions for this on the SpriteSkin component though.

1 Like

This is for editing the SpriteBone data though. Not the boneTransforms. My mistake.

I am asking the same question about Auto Rebind and ended up having to use the reflection hack for now as well

1 Like

Thank you for your feedback @shatulsky @tonytopper

In 2D Animation 10.1.0 we’ve added the SetRootBone, and SetBoneTransforms methods that will allow you to modify the root bone as well as bone transforms.

We usually don’t backport new public APIs to previous Unity versions, however, you could use these two helper methods that should work with previous Unity versions (SetRootBone, SetBoneTransforms). Please note that these helper methods are provided as is and didn’t go through our QA process. I hope this will unblock you!

Upgraded to 2023, so I have 10.1.0 now. It wasn’t smooth. Detailed in Unity Version Upgrade Causes Numerous Issues in Sprite 2D Content .

1 Like

Thank you for sharing. I will reply in that thread.