I'm saving this here in case someone's on an old Unity or runtime version and needs to work around this problem.
First: Fantastic work! Thanks a lot!
1) Possible optimization
Please check the following lines in SkeletonAnimator.cs
C#
for (; c < clipInfo.Length; c++) {
var info = clipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = stateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null);
// c++ <<<<<<<<<<<<<<<<<<< FIX?
break;
}
// c = 0 <<<<<<<<<<<<< here
//mix the rest
for (; c < clipInfo.Length; c++) {
var info = clipInfo[c];
...
As far as I understand C# the 'break' exits the loop before "c++" is executed. That means the second loop starts with 'c=0'. This causes an unnecessary MIX/BLEND step in the second loop.
2) Wrong transition
Later in SkeletonAnimator.cs we have this:
C#
for (; c < nextClipInfo.Length; c++) {
var nextInfo = nextClipInfo[c];
float weight = nextInfo.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * nextInfo.clip.length;
animationTable[nextInfo.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weigh);
// debug print-out:
// xx += " | " + nextInfo.clip.name + " @ " + time + " with " + (int)(weight * 100f) + "%";
}
It seems that Unity(5.0.0f4) miss-calculates the last frame of a transition. In my case I have an animation called "idle" and start a transition to the animation "hide". I add some debug-printouts to show whats happening:
C#
// ...
anim >> idle @ 1.144762 with 100% | hide @ 0.3325924 with 75%
anim >> idle @ 1.161329 with 100% | hide @ 0.3491591 with 82%
anim >> idle @ 1.177896 with 100% | hide @ 0.3657255 with 88%
anim >> idle @ 1.194463 with 100% | hide @ 0.3822925 with 94%
anim >> hide @ 0.3988592 with 100% | hide @ 0 with 100% // <<<<<<<<< this causes trouble
anim >> hide @ 0.4154256 with 100%
First the transition looks okay. Step by step "hide" overblends "idle". However when "idle" should disappear we have one frame with two "hide" animation. The bad thing is the time of the second "hide". It is always set to zero and therefore causes wrong frames to show up.