diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs
index c480494ce..abab61c1a 100644
--- a/spine-csharp/src/AnimationState.cs
+++ b/spine-csharp/src/AnimationState.cs
@@ -268,7 +268,8 @@ namespace Spine {
} else {
int[] timelineMode = current.timelineMode.Items;
- bool firstFrame = current.timelinesRotation.Count != timelineCount << 1;
+ bool shortestRotation = current.shortestRotation;
+ bool firstFrame = !shortestRotation && current.timelinesRotation.Count != timelineCount << 1;
if (firstFrame) current.timelinesRotation.Resize(timelineCount << 1);
float[] timelinesRotation = current.timelinesRotation.Items;
@@ -276,7 +277,7 @@ namespace Spine {
Timeline timeline = timelines[ii];
MixBlend timelineBlend = timelineMode[ii] == AnimationState.Subsequent ? blend : MixBlend.Setup;
var rotateTimeline = timeline as RotateTimeline;
- if (rotateTimeline != null)
+ if (!shortestRotation && rotateTimeline != null)
ApplyRotateTimeline(rotateTimeline, skeleton, applyTime, mix, timelineBlend, timelinesRotation,
ii << 1, firstFrame);
else if (timeline is AttachmentTimeline)
@@ -383,7 +384,8 @@ namespace Spine {
int[] timelineMode = from.timelineMode.Items;
TrackEntry[] timelineHoldMix = from.timelineHoldMix.Items;
- bool firstFrame = from.timelinesRotation.Count != timelineCount << 1;
+ bool shortestRotation = from.shortestRotation;
+ bool firstFrame = !shortestRotation && from.timelinesRotation.Count != timelineCount << 1;
if (firstFrame) from.timelinesRotation.Resize(timelineCount << 1);
float[] timelinesRotation = from.timelinesRotation.Items;
@@ -419,7 +421,7 @@ namespace Spine {
}
from.totalAlpha += alpha;
var rotateTimeline = timeline as RotateTimeline;
- if (rotateTimeline != null) {
+ if (!shortestRotation && rotateTimeline != null) {
ApplyRotateTimeline(rotateTimeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1,
firstFrame);
} else if (timeline is AttachmentTimeline) {
@@ -990,7 +992,7 @@ namespace Spine {
internal int trackIndex;
- internal bool loop, holdPrevious, reverse;
+ internal bool loop, holdPrevious, reverse, shortestRotation;
internal float eventThreshold, attachmentThreshold, drawOrderThreshold;
internal float animationStart, animationEnd, animationLast, nextAnimationLast;
internal float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale = 1f;
@@ -1257,6 +1259,14 @@ namespace Spine {
/// If true, the animation will be applied in reverse. Events are not fired when an animation is applied in reverse.
public bool Reverse { get { return reverse; } set { reverse = value; } }
+ ///
+ /// If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the
+ /// shortest rotation direction may change during the mix.
+ ///
+ /// If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
+ /// of the mix. Defaults to false.
+ public bool ShortestRotation { get { return shortestRotation; } set { shortestRotation = value; } }
+
/// Returns true if this entry is for the empty animation. See ,
/// , and .
public bool IsEmptyAnimation { get { return animation == AnimationState.EmptyAnimation; } }