So, I encountered some odd behavior when using the Hero skeleton that comes with the example assets with the spine Unity runtime package, and upon digging, I think I found a bug, with a proposed fix, well, at least what I changed in the Slot.cs class to make it behave correctly. The behavior was that the sword that the Hero holds shrinks, then grows, when switching from Idle to Run animations. You'll almost always get this if you step into unity with the Hero loaded in with the default (Idle) animation, then in the first possible Update in a script, switch it to his Run animation, then step into the next frame (after the Render) and you should see his sword shrink.
Here's some pictures to show this behavior:
This is the hero in his Idle post in the first rendered frame:
Loading Image
Then, this code is executed
_skeletonAnimation.AnimationName = RunAnimationName;
Then, once the skeleton animation is updated, i.e Mixing is applied (since Idle was the previous animation)
Loading Image
You can see the sword has mysteriously shrunk.
What I think is happening when the Hero is loaded in, the Idle animation data is loaded, and the MeshAttachment is added to the "weapon" slot. However, when the animation is switched to Run, a FFDTimeline is executed via the Mix() function in the Animation.cs, which attempts to alpha blend the attachment in the weapon slot's vertices. This is where I think the bug is creeping out.
I found that in the Slot.cs, it seems to cache the attachments vertices (if it is a mesh attachment) in the attachmentVertices variable. However, this variable is zero initialized, and never gets updated when a Mesh attachment is actually added.
public Attachment Attachment {
get {
return attachment;
}
set {
if (attachment == value) return;
attachment = value;
attachmentTime = bone.skeleton.time;
attachmentVerticesCount = 0;
}
}
This means the animation will alpha blend the zero initialized vertices (due to not being set) with the previous swords animation (Idle) position. This causes the sword mesh to shrink due to the alpha blending, then grow. The problem is, if this animation gets overridden, the mixing stops and the sword could possible stay shrunk if it does not have enough time to blend/grow.
I grabbed the actual vertices of the sword mesh, and the vertex blending looks like this
[0]: 0 -> 1.795f
[1]: 0 -> -0.3393999f
[2]: 0 -> -0.364900023f
[3]: 0 -> -0.3464f
[4]: 0 -> -0.367200017f
[5]: 0 -> 0.3434999f
[6]: 0 -> 1.7927f
[7]: 0 -> 0.3505f
Anyways, tl;dr the code change I made to get this to not happen is simple:
public Attachment Attachment {
get {
return attachment;
}
set {
if (attachment == value) return;
attachment = value;
attachmentTime = bone.skeleton.time;
attachmentVerticesCount = 0;
if (attachment is MeshAttachment)
{
attachmentVertices = ((MeshAttachment) attachment).Vertices;
attachmentVerticesCount = attachmentVertices.Length;
}
}
}
If the attachment is a mesh i.e has verticles, then set the attachmentVertices.
That way, when the blending occurs, it wont go from
[0]: 1.795f -> 1.795f
[1]: -0.3393999f -> -0.3393999f
[2]: -0.364900023f -> -0.364900023f
[3]: -0.3464f -> -0.3464f
[4]: -0.367200017f -> -0.367200017f
[5]: 0.3434999f -> 0.3434999f
[6]: 1.7927f -> 1.7927f
[7]: 0.3505f -> 0.3505f
i.e no change, so not shrunken sword, and if the animation gets override, the sword won't stay shrunk.