• Unity
  • Question about attachments and disabled renderers

Related Discussions
...

The Setup:

I have a GameObject with 4 children. Each child has a SkeletonAnimation and MeshRenderer. This children correspond to facing directions (up, down, left, & right). A script in the parent controls which of these meshes are turned on depending on which way the character is facing.

A separate singleton script, which holds a reference to that top-level GameObject , is responsible for calling Update(dt) and LateUpdate() at the appropriate time on each SkeletonAnimation.

We have code to attach a Sprite to the skeleton

void attachSpriteToSkeleton(SkeletonAnimation _skelAnim, MeshRenderer _mesh, Slot _slot, Sprite _sprite)
{
      if (_skelAnim == null) {
         return;
      }
      //Get handle to a few things that we'll be using it a lot
      var skel = _skelAnim.skeleton;
      string slotName = _slot.Data.Name;
      string newAttachmentName = _sprite.name;
      //All attachment changes will be applied to the skin. We use a clone so other instances will not be affected.
      var newSkin = skel.UnshareSkin(true, false);
      //Create an attachment from a Unity Sprite
      var newAttachment = _sprite.ToRegionAttachmentPMAClone(_mesh.material);
      //Add the attachement to the slot
      int slotIndex = _skelAnim.skeleton.FindSlotIndex(slotName);
      newSkin.SetAttachment(slotIndex, newAttachmentName, newAttachment);
      //Set the skin to the one we made, and then make our attachments visible. 
      //Note that any keying to the slot in the anim will still be recognized, so make sure that's all good to go! 
      skel.SetSkin(newSkin);
      skel.SetToSetupPose();
      skel.SetAttachment(slotName, newAttachmentName);
}

and to unattach

void unattachSpriteFromSkeleton(SkeletonAnimation _skelAnim, Slot _slot)
{
    if (_skelAnim) {
        var skel = _skelAnim.skeleton;
        skel.SetSlotAttachmentToSetupPose(skel.FindSlotIndex(_slot.Data.Name));
    }
}

Any time we want to attach or unattach, we call this code on ALL the SkeletonAnimations (regardless of whether it's currently rendering or not)

Now to the actual setup. The game launches with the character facing Left. We call the attachment code on all 4 our SkeletonAnimations to have our character pickup a stick. Then on some user input, we have the character drop the stick. When that character faces any other direction, I'd expect to not see the character holding the stick. This is actually what plays out with the setup I've described above

The Issue:
I've put in some logic to prevent all the SkeletonAnimations from Updating/LateUpdating by simply checknig if their renderer is enabled. Once I did this, I noticed that after dropping the stick, and turning another direction, the character shows as holding the stick for one frame before going back to the expected animation. I've attempted to call Update(dt) and LateUpdate() immediately after calling the attach/unattach code, but that doesn't seem to solve my problem either. I was wondering if anyone could help with this.

please let me know if anything needs clarification, I know this is super long winded.

Thank you!

Thanks for your detailled and clear writeup.

What comes to my mind is if you are calling LateUpdate() on the SkeletonRenderer and the MeshRenderer is not enabled, it will not update and return without updating the mesh (see this code section), so the manual call will not have any effect.

If this turns out to be the problem, you could call LateUpdate() on the SkeletonAnimation component once when enabling the respective MeshRenderer.

Thank you Harald! That solved my problem. I called Update(0); LateUpdate(); when enabling the specific SkeletonAnimation.

Glad to hear! Thanks for letting us know!