grylloidea Transition between idle_3 <-> run_shield is broken when using SkeletonMecanim. It takes longer rotation.
With SkeletonAnimation, everything is fine.
The problem is not as trivial unfortunately. The issue lies with the two animations containing rotation values differing by 360 degrees, one being at around -37.26 while the other is at around 351.82:
Animation "run_shield":
"run_shield": {
"bones": {
"shoulder_L": {
"rotate": [
{
"value": 23.95,
"curve": [
0.1,
23.95,
0.3,
-37.26
]
},
{
"time": 0.4,
"value": -37.26,
"curve": [
0.5,
-37.26,
0.7,
23.95
]
},
{
"time": 0.8,
"value": 23.95
}
],
.. vs. animation "idle_3":
"idle_3": {
"bones": {
"shoulder_L": {
"rotate": [
{
"value": 351.82,
"curve": [
0.117,
351.82,
0.35,
356.39
]
},
{
"time": 0.4667,
"value": 356.39,
"curve": [
0.583,
356.39,
0.817,
351.82
]
},
{
"time": 0.9333,
"value": 351.82
}
],
Thus the easy fix would be to ensure that the animations key the same local rotations, not differing by whole 360 degree rotations.
You can also mimic the same undesired behaviour in SkeletonAnimation
with AnimationState
via ShortestRotation = true
:
var entry = skeletonAnimation.AnimationState.AddAnimation(0, "run_shield", true, transitionTime);
entry.ShortestRotation = true;
This will always evaluate the rotation direction differently, i.e. each frame, see the documentation here. Otherwise when false
, the direction is evaluated only once and then the direction is kept during the whole transition.
Unfortunately SkeletonMecanim
just uses Animation.Apply
instead of the stateful AnimationState
which provides much more flexibility and is thus recommended over SkeletonMecanim
wherever possible.