diff --git a/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs b/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs index bf25ef008..e489ac2d7 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs @@ -128,6 +128,7 @@ namespace Spine.Unity.Playables { } int inputCount = playable.GetInputCount(); + float rootSpeed = GetRootPlayableSpeed(playable); // Ensure correct buffer size. if (this.lastInputWeights == null || this.lastInputWeights.Length < inputCount) { @@ -185,15 +186,16 @@ namespace Spine.Unity.Playables { } else trackEntry = state.SetAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop); + float clipSpeed = (float)clipPlayable.GetSpeed(); trackEntry.EventThreshold = clipData.eventThreshold; trackEntry.DrawOrderThreshold = clipData.drawOrderThreshold; - trackEntry.TrackTime = (float)clipPlayable.GetTime() * (float)clipPlayable.GetSpeed(); - trackEntry.TimeScale = (float)clipPlayable.GetSpeed(); + trackEntry.TrackTime = (float)clipPlayable.GetTime() * clipSpeed * rootSpeed; + trackEntry.TimeScale = clipSpeed * rootSpeed; trackEntry.AttachmentThreshold = clipData.attachmentThreshold; trackEntry.HoldPrevious = clipData.holdPrevious; if (clipData.customDuration) - trackEntry.MixDuration = customMixDuration; + trackEntry.MixDuration = customMixDuration / rootSpeed; timelineStartedTrackEntry = trackEntry; } @@ -227,6 +229,7 @@ namespace Spine.Unity.Playables { if (animationStateComponent.IsNullOrDestroyed() || skeletonComponent == null) return; int inputCount = playable.GetInputCount(); + float rootSpeed = GetRootPlayableSpeed(playable); int lastNonZeroWeightTrack = -1; for (int i = 0; i < inputCount; i++) { @@ -256,12 +259,12 @@ namespace Spine.Unity.Playables { var fromClip = (ScriptPlayable)playable.GetInput(lastNonZeroWeightTrack - 1); var fromClipData = fromClip.GetBehaviour(); fromAnimation = fromClipData.animationReference != null ? fromClipData.animationReference.Animation : null; - fromClipTime = (float)fromClip.GetTime() * (float)fromClip.GetSpeed(); + fromClipTime = (float)fromClip.GetTime() * (float)fromClip.GetSpeed() * rootSpeed; fromClipLoop = fromClipData.loop; } Animation toAnimation = clipData.animationReference != null ? clipData.animationReference.Animation : null; - float toClipTime = (float)inputPlayableClip.GetTime() * (float)inputPlayableClip.GetSpeed(); + float toClipTime = (float)inputPlayableClip.GetTime() * (float)inputPlayableClip.GetSpeed() * rootSpeed; float mixDuration = clipData.mixDuration; if (!clipData.customDuration && fromAnimation != null && toAnimation != null) { @@ -316,6 +319,24 @@ namespace Spine.Unity.Playables { } #endif + float GetRootPlayableSpeed (Playable playable) { + PlayableGraph graph = playable.GetGraph(); + int rootPlayableCount = graph.GetRootPlayableCount(); + if (rootPlayableCount == 1) + return (float)graph.GetRootPlayable(0).GetSpeed(); + else { + for (int rootIndex = 0; rootIndex < rootPlayableCount; ++rootIndex) { + var rootPlayable = graph.GetRootPlayable(rootIndex); + for (int i = 0, n = rootPlayable.GetInputCount(); i < n; ++i) { + var playableChild = rootPlayable.GetInput(i); + if (playableChild.Equals(playable)) { + return (float)rootPlayable.GetSpeed(); + } + } + } + } + return 1.0f; + } float GetCustomMixDuration (SpineAnimationStateBehaviour clipData) { if (clipData.useBlendDuration) {