From 39dfca8263a32be7d35148f6a793ccae8a8c4bf5 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 29 Sep 2021 19:32:48 +0200 Subject: [PATCH 1/8] [Unity] Fixed `Update When Invisible` mode causing strange Event timing. Closes #1954. --- spine-csharp/src/AnimationState.cs | 59 +++++++++++-------- .../Components/SkeletonAnimation.cs | 18 +++++- .../spine-unity/Components/SkeletonGraphic.cs | 7 ++- .../spine-unity/Components/SkeletonMecanim.cs | 12 ++++ .../Components/SkeletonRenderer.cs | 6 +- 5 files changed, 72 insertions(+), 30 deletions(-) diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index e8c97d595..db55683b0 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -309,9 +309,11 @@ namespace Spine { return applied; } - /// Version of only applying EventTimelines for lightweight off-screen updates. + /// Version of only applying and updating time at + /// EventTimelines for lightweight off-screen updates. + /// When set to false, only animation times of TrackEntries are updated. // Note: This method is not part of the libgdx reference implementation. - public bool ApplyEventTimelinesOnly (Skeleton skeleton) { + public bool ApplyEventTimelinesOnly (Skeleton skeleton, bool issueEvents = true) { if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); ExposedList events = this.events; @@ -323,24 +325,28 @@ namespace Spine { applied = true; // Apply mixing from entries first. - if (current.mixingFrom != null) ApplyMixingFromEventTimelinesOnly(current, skeleton); + if (current.mixingFrom != null) ApplyMixingFromEventTimelinesOnly(current, skeleton, issueEvents); // Apply current entry. float animationLast = current.animationLast, animationTime = current.AnimationTime; - int timelineCount = current.animation.timelines.Count; - Timeline[] timelines = current.animation.timelines.Items; - for (int ii = 0; ii < timelineCount; ii++) { - Timeline timeline = timelines[ii]; - if (timeline is EventTimeline) - timeline.Apply(skeleton, animationLast, animationTime, events, 1.0f, MixBlend.Setup, MixDirection.In); + + if (issueEvents) { + int timelineCount = current.animation.timelines.Count; + Timeline[] timelines = current.animation.timelines.Items; + for (int ii = 0; ii < timelineCount; ii++) { + Timeline timeline = timelines[ii]; + if (timeline is EventTimeline) + timeline.Apply(skeleton, animationLast, animationTime, events, 1.0f, MixBlend.Setup, MixDirection.In); + } + QueueEvents(current, animationTime); + events.Clear(false); } - QueueEvents(current, animationTime); - events.Clear(false); current.nextAnimationLast = animationTime; current.nextTrackLast = current.trackTime; } - queue.Drain(); + if (issueEvents) + queue.Drain(); return applied; } @@ -434,11 +440,14 @@ namespace Spine { return mix; } - /// Version of only applying EventTimelines for lightweight off-screen updates. + /// Version of only applying and updating time at + /// EventTimelines for lightweight off-screen updates. + /// When set to false, only animation times of TrackEntries are updated. // Note: This method is not part of the libgdx reference implementation. - private float ApplyMixingFromEventTimelinesOnly (TrackEntry to, Skeleton skeleton) { + private float ApplyMixingFromEventTimelinesOnly (TrackEntry to, Skeleton skeleton, bool issueEvents) { TrackEntry from = to.mixingFrom; - if (from.mixingFrom != null) ApplyMixingFromEventTimelinesOnly(from, skeleton); + if (from.mixingFrom != null) ApplyMixingFromEventTimelinesOnly(from, skeleton, issueEvents); + float mix; if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. @@ -452,16 +461,18 @@ namespace Spine { if (eventBuffer == null) return mix; float animationLast = from.animationLast, animationTime = from.AnimationTime; - int timelineCount = from.animation.timelines.Count; - Timeline[] timelines = from.animation.timelines.Items; - for (int i = 0; i < timelineCount; i++) { - Timeline timeline = timelines[i]; - if (timeline is EventTimeline) - timeline.Apply(skeleton, animationLast, animationTime, eventBuffer, 0, MixBlend.Setup, MixDirection.Out); - } + if (issueEvents) { + int timelineCount = from.animation.timelines.Count; + Timeline[] timelines = from.animation.timelines.Items; + for (int i = 0; i < timelineCount; i++) { + Timeline timeline = timelines[i]; + if (timeline is EventTimeline) + timeline.Apply(skeleton, animationLast, animationTime, eventBuffer, 0, MixBlend.Setup, MixDirection.Out); + } - if (to.mixDuration > 0) QueueEvents(from, animationTime); - this.events.Clear(false); + if (to.mixDuration > 0) QueueEvents(from, animationTime); + this.events.Clear(false); + } from.nextAnimationLast = animationTime; from.nextTrackLast = from.trackTime; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs index 4d774134b..1fafbfac8 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs @@ -206,8 +206,10 @@ namespace Spine.Unity { return; UpdateAnimationStatus(deltaTime); - if (updateMode == UpdateMode.OnlyAnimationStatus) + if (updateMode == UpdateMode.OnlyAnimationStatus) { + state.ApplyEventTimelinesOnly(skeleton, issueEvents: false); return; + } ApplyAnimation(); } @@ -224,7 +226,7 @@ namespace Spine.Unity { if (updateMode != UpdateMode.OnlyEventTimelines) state.Apply(skeleton); else - state.ApplyEventTimelinesOnly(skeleton); + state.ApplyEventTimelinesOnly(skeleton, issueEvents : true); if (_UpdateLocal != null) _UpdateLocal(this); @@ -246,6 +248,18 @@ namespace Spine.Unity { if (!wasUpdatedAfterInit) Update(0); base.LateUpdate(); } + + public override void OnBecameVisible () { + UpdateMode previousUpdateMode = updateMode; + updateMode = UpdateMode.FullUpdate; + + // OnBecameVisible is called after LateUpdate() + if (previousUpdateMode != UpdateMode.FullUpdate && + previousUpdateMode != UpdateMode.EverythingExceptMesh) + Update(0); + if (previousUpdateMode != UpdateMode.FullUpdate) + LateUpdate(); + } } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs index c9a2191bb..a11d3409c 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -265,10 +265,13 @@ namespace Spine.Unity { wasUpdatedAfterInit = true; if (updateMode < UpdateMode.OnlyAnimationStatus) return; + UpdateAnimationStatus(deltaTime); - if (updateMode == UpdateMode.OnlyAnimationStatus) + if (updateMode == UpdateMode.OnlyAnimationStatus) { + state.ApplyEventTimelinesOnly(skeleton, issueEvents: false); return; + } ApplyAnimation(); } @@ -303,7 +306,7 @@ namespace Spine.Unity { if (updateMode != UpdateMode.OnlyEventTimelines) state.Apply(skeleton); else - state.ApplyEventTimelinesOnly(skeleton); + state.ApplyEventTimelinesOnly(skeleton, issueEvents: true); if (UpdateLocal != null) UpdateLocal(this); diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs index a67b42a87..c32f0fa55 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -140,6 +140,18 @@ namespace Spine.Unity { base.LateUpdate(); } + public override void OnBecameVisible () { + UpdateMode previousUpdateMode = updateMode; + updateMode = UpdateMode.FullUpdate; + + // OnBecameVisible is called after LateUpdate() + if (previousUpdateMode != UpdateMode.FullUpdate && + previousUpdateMode != UpdateMode.EverythingExceptMesh) + Update(); + if (previousUpdateMode != UpdateMode.FullUpdate) + LateUpdate(); + } + [System.Serializable] public class MecanimTranslator { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs index 935019df8..1ea62a110 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs @@ -554,11 +554,13 @@ namespace Spine.Unity { OnMeshAndMaterialsUpdated(this); } - public void OnBecameVisible () { + public virtual void OnBecameVisible () { UpdateMode previousUpdateMode = updateMode; updateMode = UpdateMode.FullUpdate; + + // OnBecameVisible is called after LateUpdate() if (previousUpdateMode != UpdateMode.FullUpdate) - LateUpdate(); // OnBecameVisible is called after LateUpdate() + LateUpdate(); } public void OnBecameInvisible () { From 8ea166b3315638d7fa77648c4f118be290065511 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 29 Sep 2021 21:10:58 +0200 Subject: [PATCH 2/8] [unity] Fixed json vs binary file detection. --- .../spine-unity/Asset Types/SkeletonDataCompatibility.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs index 02910f609..6404a1357 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataCompatibility.cs @@ -173,11 +173,16 @@ namespace Spine.Unity { int i = 0; if (content.Length >= 3 && content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF) // skip potential BOM i = 3; + bool openingBraceFound = false; for (; i < numCharsToCheck; ++i) { char c = (char)content[i]; if (char.IsWhiteSpace(c)) continue; - return c == '{'; + if (!openingBraceFound) { + if (c == '{') openingBraceFound = true; + else return false; + } else + return c == '"'; } return true; } From 5142ecc9ca8348378e53ca0792523afac8f33984 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 29 Sep 2021 21:33:53 +0200 Subject: [PATCH 3/8] [unity] Minor: whitespace changes to please formatting checks. --- .../Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs index 1fafbfac8..e60746008 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs @@ -226,7 +226,7 @@ namespace Spine.Unity { if (updateMode != UpdateMode.OnlyEventTimelines) state.Apply(skeleton); else - state.ApplyEventTimelinesOnly(skeleton, issueEvents : true); + state.ApplyEventTimelinesOnly(skeleton, issueEvents: true); if (_UpdateLocal != null) _UpdateLocal(this); From 9155d6e2f0228449f375d678c7e7c9c6285e40fb Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Sat, 2 Oct 2021 09:34:46 +0200 Subject: [PATCH 4/8] [csharp] Fixed Bone.UpdateAppliedTransform being public instead of internal. --- spine-csharp/src/Bone.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs index 74dc8e94e..1fb9e69e2 100644 --- a/spine-csharp/src/Bone.cs +++ b/spine-csharp/src/Bone.cs @@ -274,7 +274,7 @@ namespace Spine { /// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after /// calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. /// - internal void UpdateAppliedTransform () { + public void UpdateAppliedTransform () { Bone parent = this.parent; if (parent == null) { ax = worldX - skeleton.x; From eb5a776d72c2d3a2c563737f0ab8a8c82b953c9e Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Tue, 5 Oct 2021 19:03:10 +0200 Subject: [PATCH 5/8] [csharp] Port of commit d9b882e. Added TrackEntry.IsEmptyAnimation. --- spine-csharp/src/AnimationState.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index db55683b0..5cd73b7a9 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -40,7 +40,7 @@ namespace Spine { /// See Applying Animations in the Spine Runtimes Guide. /// public class AnimationState { - static readonly Animation EmptyAnimation = new Animation("", new ExposedList(), 0); + internal static readonly Animation EmptyAnimation = new Animation("", new ExposedList(), 0); /// 1) A previously applied timeline has set this property. /// Result: Mix from the current pose to the timeline pose. @@ -1253,6 +1253,10 @@ 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; } } + /// Returns true if this entry is for the empty animation. See , + /// , and . + public bool IsEmptyAnimation { get { return animation == AnimationState.EmptyAnimation; }} + /// /// /// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the From 702322e27b929d58dea725760f5c558c4f18d914 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 6 Oct 2021 09:18:18 +0200 Subject: [PATCH 6/8] [csharp] Minor cleanup: Fixed whitespace to please format checks. --- spine-csharp/src/AnimationState.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index 5cd73b7a9..23e6c6e13 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -1255,7 +1255,7 @@ namespace Spine { /// Returns true if this entry is for the empty animation. See , /// , and . - public bool IsEmptyAnimation { get { return animation == AnimationState.EmptyAnimation; }} + public bool IsEmptyAnimation { get { return animation == AnimationState.EmptyAnimation; } } /// /// From 38a42e41c691f5e1402c2be1c2b6a6802fdcdf52 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 6 Oct 2021 20:30:58 +0200 Subject: [PATCH 7/8] [unity] Fixed Timeline clip EaseIn from empty animation or blank space. Closes #1961. --- .../SpineAnimationStateClipInspector.cs | 2 +- .../SpineAnimationStateMixerBehaviour.cs | 133 ++++++++++-------- .../package.json | 2 +- 3 files changed, 80 insertions(+), 57 deletions(-) diff --git a/spine-unity/Modules/com.esotericsoftware.spine.timeline/Editor/SpineAnimationStateClipInspector.cs b/spine-unity/Modules/com.esotericsoftware.spine.timeline/Editor/SpineAnimationStateClipInspector.cs index e280ed3de..c160d2d74 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.timeline/Editor/SpineAnimationStateClipInspector.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.timeline/Editor/SpineAnimationStateClipInspector.cs @@ -79,7 +79,7 @@ namespace Spine.Unity.Editor { if (timelineClip == null) return; - float blendInDur = (float)timelineClip.blendInDuration; + float blendInDur = System.Math.Max((float)timelineClip.blendInDuration, (float)timelineClip.easeInDuration); bool isBlendingNow = blendInDur > 0; bool wasBlendingBefore = timelineClipInfo.previousBlendInDuration > 0; 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 c5bdefbae..aa9fa5086 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 @@ -38,8 +38,10 @@ namespace Spine.Unity.Playables { public class SpineAnimationStateMixerBehaviour : PlayableBehaviour { float[] lastInputWeights; - bool lastAnyTrackPlaying = false; + bool lastAnyClipPlaying = false; public int trackIndex; + ScriptPlayable[] startingClips + = new ScriptPlayable[2]; IAnimationStateComponent animationStateComponent; bool pauseWithDirector = true; @@ -135,60 +137,81 @@ namespace Spine.Unity.Playables { this.lastInputWeights[i] = default(float); } var lastInputWeights = this.lastInputWeights; - bool anyTrackPlaying = false; + int numStartingClips = 0; + bool anyClipPlaying = false; // Check all clips. If a clip that was weight 0 turned into weight 1, call SetAnimation. for (int i = 0; i < inputCount; i++) { float lastInputWeight = lastInputWeights[i]; float inputWeight = playable.GetInputWeight(i); - bool trackStarted = lastInputWeight == 0 && inputWeight > 0; + bool clipStarted = lastInputWeight == 0 && inputWeight > 0; if (inputWeight > 0) - anyTrackPlaying = true; + anyClipPlaying = true; lastInputWeights[i] = inputWeight; - if (trackStarted) { - ScriptPlayable inputPlayable = (ScriptPlayable)playable.GetInput(i); - SpineAnimationStateBehaviour clipData = inputPlayable.GetBehaviour(); - - pauseWithDirector = !clipData.dontPauseWithDirector; - endAtClipEnd = !clipData.dontEndWithClip; - endMixOutDuration = clipData.endMixOutDuration; - - if (clipData.animationReference == null) { - float mixDuration = clipData.customDuration ? clipData.mixDuration : state.Data.DefaultMix; - state.SetEmptyAnimation(trackIndex, mixDuration); - } else { - if (clipData.animationReference.Animation != null) { - Spine.TrackEntry trackEntry = state.SetAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop); - - trackEntry.EventThreshold = clipData.eventThreshold; - trackEntry.DrawOrderThreshold = clipData.drawOrderThreshold; - trackEntry.TrackTime = (float)inputPlayable.GetTime() * (float)inputPlayable.GetSpeed(); - trackEntry.TimeScale = (float)inputPlayable.GetSpeed(); - trackEntry.AttachmentThreshold = clipData.attachmentThreshold; - trackEntry.HoldPrevious = clipData.holdPrevious; - - if (clipData.customDuration) - trackEntry.MixDuration = clipData.mixDuration; - - timelineStartedTrackEntry = trackEntry; - } - //else Debug.LogWarningFormat("Animation named '{0}' not found", clipData.animationName); - } - - // Ensure that the first frame ends with an updated mesh. - if (skeletonAnimation) { - skeletonAnimation.Update(0); - skeletonAnimation.LateUpdate(); - } else if (skeletonGraphic) { - skeletonGraphic.Update(0); - skeletonGraphic.LateUpdate(); - } + if (clipStarted && numStartingClips < 2) { + ScriptPlayable clipPlayable = (ScriptPlayable)playable.GetInput(i); + startingClips[numStartingClips++] = clipPlayable; } } - if (lastAnyTrackPlaying && !anyTrackPlaying) + // unfortunately order of clips can be wrong when two start at the same time, we have to sort clips + if (numStartingClips == 2) { + ScriptPlayable clipPlayable0 = startingClips[0]; + ScriptPlayable clipPlayable1 = startingClips[1]; + if (clipPlayable0.GetDuration() > clipPlayable1.GetDuration()) { // swap, clip 0 ends after clip 1 + startingClips[0] = clipPlayable1; + startingClips[1] = clipPlayable0; + } + } + + for (int j = 0; j < numStartingClips; ++j) { + ScriptPlayable clipPlayable = startingClips[j]; + SpineAnimationStateBehaviour clipData = clipPlayable.GetBehaviour(); + pauseWithDirector = !clipData.dontPauseWithDirector; + endAtClipEnd = !clipData.dontEndWithClip; + endMixOutDuration = clipData.endMixOutDuration; + + if (clipData.animationReference == null) { + float mixDuration = clipData.customDuration ? clipData.mixDuration : state.Data.DefaultMix; + state.SetEmptyAnimation(trackIndex, mixDuration); + } else { + if (clipData.animationReference.Animation != null) { + TrackEntry currentEntry = state.GetCurrent(trackIndex); + Spine.TrackEntry trackEntry; + if (currentEntry == null && (clipData.customDuration && clipData.mixDuration > 0)) { + state.SetEmptyAnimation(trackIndex, 0); // ease in requires empty animation + trackEntry = state.AddAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop, 0); + } else + trackEntry = state.SetAnimation(trackIndex, clipData.animationReference.Animation, clipData.loop); + + trackEntry.EventThreshold = clipData.eventThreshold; + trackEntry.DrawOrderThreshold = clipData.drawOrderThreshold; + trackEntry.TrackTime = (float)clipPlayable.GetTime() * (float)clipPlayable.GetSpeed(); + trackEntry.TimeScale = (float)clipPlayable.GetSpeed(); + trackEntry.AttachmentThreshold = clipData.attachmentThreshold; + trackEntry.HoldPrevious = clipData.holdPrevious; + + if (clipData.customDuration) + trackEntry.MixDuration = clipData.mixDuration; + + timelineStartedTrackEntry = trackEntry; + } + //else Debug.LogWarningFormat("Animation named '{0}' not found", clipData.animationName); + } + + // Ensure that the first frame ends with an updated mesh. + if (skeletonAnimation) { + skeletonAnimation.Update(0); + skeletonAnimation.LateUpdate(); + } else if (skeletonGraphic) { + skeletonGraphic.Update(0); + skeletonGraphic.LateUpdate(); + } + } + startingClips[0] = startingClips[1] = ScriptPlayable.Null; + if (lastAnyClipPlaying && !anyClipPlaying) HandleClipEnd(); - this.lastAnyTrackPlaying = anyTrackPlaying; + this.lastAnyClipPlaying = anyClipPlaying; } #if SPINE_EDITMODEPOSE @@ -251,25 +274,25 @@ namespace Spine.Unity.Playables { if (fromAnimation != null && mixDuration > 0 && toClipTime < mixDuration) { dummyAnimationState = dummyAnimationState ?? new AnimationState(skeletonComponent.SkeletonDataAsset.GetAnimationStateData()); - var toTrack = dummyAnimationState.GetCurrent(0); - var fromTrack = toTrack != null ? toTrack.MixingFrom : null; - bool isAnimationTransitionMatch = (toTrack != null && toTrack.Animation == toAnimation && fromTrack != null && fromTrack.Animation == fromAnimation); + var toEntry = dummyAnimationState.GetCurrent(0); + var fromEntry = toEntry != null ? toEntry.MixingFrom : null; + bool isAnimationTransitionMatch = (toEntry != null && toEntry.Animation == toAnimation && fromEntry != null && fromEntry.Animation == fromAnimation); if (!isAnimationTransitionMatch) { dummyAnimationState.ClearTracks(); - fromTrack = dummyAnimationState.SetAnimation(0, fromAnimation, fromClipLoop); - fromTrack.AllowImmediateQueue(); + fromEntry = dummyAnimationState.SetAnimation(0, fromAnimation, fromClipLoop); + fromEntry.AllowImmediateQueue(); if (toAnimation != null) { - toTrack = dummyAnimationState.SetAnimation(0, toAnimation, clipData.loop); - toTrack.HoldPrevious = clipData.holdPrevious; + toEntry = dummyAnimationState.SetAnimation(0, toAnimation, clipData.loop); + toEntry.HoldPrevious = clipData.holdPrevious; } } // Update track times. - fromTrack.TrackTime = fromClipTime; - if (toTrack != null) { - toTrack.TrackTime = toClipTime; - toTrack.MixTime = toClipTime; + fromEntry.TrackTime = fromClipTime; + if (toEntry != null) { + toEntry.TrackTime = toClipTime; + toEntry.MixTime = toClipTime; } // Apply Pose diff --git a/spine-unity/Modules/com.esotericsoftware.spine.timeline/package.json b/spine-unity/Modules/com.esotericsoftware.spine.timeline/package.json index f03c692b2..2110d205b 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.timeline/package.json +++ b/spine-unity/Modules/com.esotericsoftware.spine.timeline/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.timeline", "displayName": "Spine Timeline Extensions", "description": "This plugin provides integration of spine-unity for the Unity Timeline.\n\nPrerequisites:\nIt requires a working installation of the spine-unity and spine-csharp runtimes as UPM packages (not as spine-unity unitypackage), version 4.0.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", - "version": "4.0.5", + "version": "4.0.6", "unity": "2018.3", "author": { "name": "Esoteric Software", From 555c124a4440526ac2b89232e12037563c0e0100 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Wed, 6 Oct 2021 20:34:29 +0200 Subject: [PATCH 8/8] [unity] Updated second package.json file version number as well. See commit 38a42e41. See #1961. --- .../package-no-spine-unity-dependency.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-unity/Modules/com.esotericsoftware.spine.timeline/package-no-spine-unity-dependency.json b/spine-unity/Modules/com.esotericsoftware.spine.timeline/package-no-spine-unity-dependency.json index 3d231ddbe..48028d42e 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.timeline/package-no-spine-unity-dependency.json +++ b/spine-unity/Modules/com.esotericsoftware.spine.timeline/package-no-spine-unity-dependency.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.timeline", "displayName": "Spine Timeline Extensions", "description": "This plugin provides integration of spine-unity for the Unity Timeline.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime (via the spine-unity unitypackage), version 4.0.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", - "version": "4.0.5", + "version": "4.0.6", "unity": "2018.3", "author": { "name": "Esoteric Software",