From 7481a059315194b1ab922028f90611cabad63610 Mon Sep 17 00:00:00 2001 From: pharan Date: Tue, 13 Jun 2017 08:51:53 +0800 Subject: [PATCH] [unity] Update calls to Timeline/Animation.Apply. And other cleanup. --- .../Assets/Examples/Scripts/SpineGauge.cs | 2 +- .../Editor/SkeletonAnimationInspector.cs | 4 +- .../spine-unity/Editor/SkeletonBaker.cs | 34 +-- .../SkeletonGraphic/SkeletonGraphic.cs | 2 +- .../Assets/spine-unity/SkeletonAnimation.cs | 5 +- .../Assets/spine-unity/SkeletonAnimator.cs | 280 +++++++++--------- .../Assets/spine-unity/SkeletonExtensions.cs | 26 +- 7 files changed, 186 insertions(+), 167 deletions(-) diff --git a/spine-unity/Assets/Examples/Scripts/SpineGauge.cs b/spine-unity/Assets/Examples/Scripts/SpineGauge.cs index ffe0a8505..b89ebf577 100644 --- a/spine-unity/Assets/Examples/Scripts/SpineGauge.cs +++ b/spine-unity/Assets/Examples/Scripts/SpineGauge.cs @@ -65,7 +65,7 @@ namespace Spine.Unity.Examples { if (fillAnimation == null) return; } - fillAnimation.Apply(skeleton, 0, percent, false, null, 1f, true, false); + fillAnimation.Apply(skeleton, 0, percent, false, null, 1f, MixPose.Setup, MixDirection.In); skeleton.Update(Time.deltaTime); skeleton.UpdateWorldTransform(); diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs index 9a53b3104..8d4672615 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonAnimationInspector.cs @@ -115,8 +115,8 @@ namespace Spine.Unity.Editor { Spine.Animation animationToUse = skeletonAnimation.skeleton.Data.FindAnimation(animationName.stringValue); if (!Application.isPlaying) { - if (animationToUse != null) animationToUse.Apply(skeletonAnimation.skeleton, 0f, 0f, false, null, 1f, true, false); - skeletonAnimation.Update(); + if (animationToUse != null) animationToUse.PoseSkeleton(skeletonAnimation.Skeleton, 0f); + skeletonAnimation.Update(0); skeletonAnimation.LateUpdate(); requireRepaint = true; } else { diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs index 521b71f42..71f5fe406 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs @@ -931,7 +931,7 @@ namespace Spine.Unity.Editor { Skeleton skeleton = bone.Skeleton; bool inheritRotation = bone.Data.TransformMode.InheritsRotation(); - animation.Apply(skeleton, 0, 0, true, null, 1f, true, false); + animation.PoseSkeleton(skeleton, 0); skeleton.UpdateWorldTransform(); float duration = animation.Duration; @@ -952,7 +952,6 @@ namespace Spine.Unity.Editor { int steps = Mathf.CeilToInt(duration / bakeIncrement); float currentTime = 0; - float lastTime = 0; float angle = rotation; for (int i = 1; i <= steps; i++) { @@ -960,7 +959,7 @@ namespace Spine.Unity.Editor { if (i == steps) currentTime = duration; - animation.Apply(skeleton, lastTime, currentTime, true, null, 1f, true, false); + animation.PoseSkeleton(skeleton, currentTime, true); skeleton.UpdateWorldTransform(); int pIndex = listIndex - 1; @@ -969,11 +968,7 @@ namespace Spine.Unity.Editor { pk = keys[pIndex]; - if (inheritRotation) - rotation = bone.AppliedRotation; - else { - rotation = GetUninheritedRotation(bone); - } + rotation = inheritRotation ? bone.AppliedRotation : GetUninheritedRotation(bone); angle += Mathf.DeltaAngle(angle, rotation); @@ -988,7 +983,6 @@ namespace Spine.Unity.Editor { keys[pIndex] = pk; listIndex++; - lastTime = currentTime; } curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); @@ -1058,7 +1052,7 @@ namespace Spine.Unity.Editor { currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); lastTime = time; listIndex++; @@ -1085,7 +1079,7 @@ namespace Spine.Unity.Editor { currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); lastTime = time; listIndex++; @@ -1104,7 +1098,7 @@ namespace Spine.Unity.Editor { if (i == steps) currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); px = xKeys[listIndex - 1]; py = yKeys[listIndex - 1]; @@ -1201,7 +1195,7 @@ namespace Spine.Unity.Editor { currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); lastTime = time; listIndex++; @@ -1228,7 +1222,7 @@ namespace Spine.Unity.Editor { currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); lastTime = time; listIndex++; @@ -1246,7 +1240,7 @@ namespace Spine.Unity.Editor { if (i == steps) currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); px = xKeys[listIndex - 1]; py = yKeys[listIndex - 1]; @@ -1330,7 +1324,7 @@ namespace Spine.Unity.Editor { currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); lastTime = time; listIndex++; @@ -1355,7 +1349,7 @@ namespace Spine.Unity.Editor { currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); lastTime = time; listIndex++; @@ -1365,7 +1359,7 @@ namespace Spine.Unity.Editor { float time = frames[f]; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); skeleton.UpdateWorldTransform(); rotation = frames[f + 1] + boneData.Rotation; @@ -1379,7 +1373,7 @@ namespace Spine.Unity.Editor { if (i == steps) currentTime = time; - timeline.Apply(skeleton, lastTime, currentTime, null, 1, false, false); + timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixPose.Setup, MixDirection.In); skeleton.UpdateWorldTransform(); pk = keys[listIndex - 1]; @@ -1407,7 +1401,7 @@ namespace Spine.Unity.Editor { curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); string path = GetPath(boneData); - string propertyName = "localEulerAnglesBaked"; + const string propertyName = "localEulerAnglesBaked"; EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs index 5fa0f4a99..4961088f1 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs +++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs @@ -242,7 +242,7 @@ namespace Spine.Unity { // Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above. var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation); if (animationObject != null) - animationObject.Apply(skeleton, 0f, 0f, false, null, 1f, true, false); + animationObject.PoseSkeleton(skeleton, 0); } Update(0); } diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs index 7b2c4e6d6..7296c4616 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimation.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimation.cs @@ -150,7 +150,7 @@ namespace Spine.Unity { // Assume SkeletonAnimation is valid for skeletonData and skeleton. Checked above. var animationObject = skeletonDataAsset.GetSkeletonData(false).FindAnimation(_animationName); if (animationObject != null) - animationObject.Apply(skeleton, 0f, 0f, false, null, 1f, true, false); + animationObject.PoseSkeleton(skeleton, 0f); } Update(0); } @@ -162,10 +162,11 @@ namespace Spine.Unity { #endif } - public void Update () { + void Update () { Update(Time.deltaTime); } + /// Progresses the AnimationState according to the given deltaTime, and applies it to the Skeleton. Use Time.deltaTime to update manually. Use deltaTime 0 to update without progressing the time. public void Update (float deltaTime) { if (!valid) return; diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs index c71984456..f3f58cbcd 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs @@ -40,9 +40,6 @@ namespace Spine.Unity { public enum MixMode { AlwaysMix, MixNext, SpineStyle } public MixMode[] layerMixModes = new MixMode[0]; - public bool autoReset = true; - List previousAnimations = new List(); - #region Bone Callbacks (ISkeletonAnimation) protected event UpdateBonesDelegate _UpdateLocal; protected event UpdateBonesDelegate _UpdateWorld; @@ -66,122 +63,164 @@ namespace Spine.Unity { public event UpdateBonesDelegate UpdateComplete { add { _UpdateComplete += value; } remove { _UpdateComplete -= value; } } #endregion - readonly Dictionary animationTable = new Dictionary(); - readonly Dictionary clipNameHashCodeTable = new Dictionary(); - Animator animator; + public class SpineMecanimTranslator { + readonly Dictionary animationTable = new Dictionary(); + readonly Dictionary clipNameHashCodeTable = new Dictionary(); + Animator animator; + + List previousAnimations = new List(); + public bool autoReset = true; + + public void Initialize (Animator animator, SkeletonDataAsset skeletonDataAsset) { + this.animator = animator; + animationTable.Clear(); + clipNameHashCodeTable.Clear(); + var data = skeletonDataAsset.GetSkeletonData(true); + foreach (var a in data.Animations) + animationTable.Add(a.Name.GetHashCode(), a); + } + + public void Apply (Skeleton skeleton, ref MixMode[] layerMixModes) { + + if (layerMixModes.Length < animator.layerCount) + System.Array.Resize(ref layerMixModes, animator.layerCount); + + //skeleton.Update(Time.deltaTime); // Doesn't actually do anything, currently. (Spine 3.5). + + // Clear Previous + if (autoReset) { + var previousAnimations = this.previousAnimations; + for (int i = 0, n = previousAnimations.Count; i < n; i++) + previousAnimations[i].SetKeyedItemsToSetupPose(skeleton); + + previousAnimations.Clear(); + for (int layer = 0, n = animator.layerCount; layer < n; layer++) { + float layerWeight = (layer == 0) ? 1 : animator.GetLayerWeight(layer); // Animator.GetLayerWeight always returns 0 on the first layer. Should be interpreted as 1. + if (layerWeight <= 0) continue; + + AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer); + + bool hasNext = nextStateInfo.fullPathHash != 0; + AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(layer); + AnimatorClipInfo[] nextClipInfo = animator.GetNextAnimatorClipInfo(layer); + + for (int c = 0; c < clipInfo.Length; c++) { + var info = clipInfo[c]; + float weight = info.weight * layerWeight; if (weight == 0) continue; + previousAnimations.Add(animationTable[NameHashCode(info.clip)]); + } + if (hasNext) { + for (int c = 0; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; + float weight = info.weight * layerWeight; if (weight == 0) continue; + previousAnimations.Add(animationTable[NameHashCode(info.clip)]); + } + } + } + } + + // Apply + for (int layer = 0, n = animator.layerCount; layer < n; layer++) { + float layerWeight = (layer == 0) ? 1 : animator.GetLayerWeight(layer); // Animator.GetLayerWeight always returns 0 on the first layer. Should be interpreted as 1. + AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(layer); + AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer); + + bool hasNext = nextStateInfo.fullPathHash != 0; + AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(layer); + AnimatorClipInfo[] nextClipInfo = animator.GetNextAnimatorClipInfo(layer); + //UNITY 4 + //bool hasNext = nextStateInfo.nameHash != 0; + //var clipInfo = animator.GetCurrentAnimationClipState(i); + //var nextClipInfo = animator.GetNextAnimationClipState(i); + + MixMode mode = layerMixModes[layer]; + if (mode == MixMode.AlwaysMix) { + // Always use Mix instead of Applying the first non-zero weighted clip. + for (int c = 0; c < clipInfo.Length; c++) { + var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; + animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, MixPose.Current, MixDirection.In); + } + if (hasNext) { + for (int c = 0; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; + animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixPose.Current, MixDirection.In); + } + } + } else { // case MixNext || SpineStyle + // Apply first non-zero weighted clip + int c = 0; + for (; c < clipInfo.Length; c++) { + var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; + animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, 1f, MixPose.Current, MixDirection.In); + break; + } + // Mix the rest + for (; c < clipInfo.Length; c++) { + var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; + animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, MixPose.Current, MixDirection.In); + } + + c = 0; + if (hasNext) { + // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) + if (mode == MixMode.SpineStyle) { + for (; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; + animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, MixPose.Current, MixDirection.In); + break; + } + } + // Mix the rest + for (; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; + animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixPose.Current, MixDirection.In); + } + } + } + } + } + + static float AnimationTime (float normalizedTime, float clipLength, bool loop, bool reversed) { + if (reversed) + normalizedTime = (1-normalizedTime + (int)normalizedTime) + (int)normalizedTime; + float time = normalizedTime * clipLength; + if (loop) return time; + const float EndSnapEpsilon = 1f/30f; // Workaround for end-duration keys not being applied. + return (clipLength - time < EndSnapEpsilon) ? clipLength : time; // return a time snapped to clipLength; + } + + static float AnimationTime (float normalizedTime, float clipLength, bool reversed) { + if (reversed) + normalizedTime = (1-normalizedTime + (int)normalizedTime) + (int)normalizedTime; + + return normalizedTime * clipLength; + } + + int NameHashCode (AnimationClip clip) { + int clipNameHashCode; + if (!clipNameHashCodeTable.TryGetValue(clip, out clipNameHashCode)) { + clipNameHashCode = clip.name.GetHashCode(); + clipNameHashCodeTable.Add(clip, clipNameHashCode); + } + return clipNameHashCode; + } + } + + public SpineMecanimTranslator translator; public override void Initialize (bool overwrite) { if (valid && !overwrite) return; base.Initialize(overwrite); if (!valid) return; - animationTable.Clear(); - clipNameHashCodeTable.Clear(); - animator = GetComponent(); - var data = skeletonDataAsset.GetSkeletonData(true); - foreach (var a in data.Animations) - animationTable.Add(a.Name.GetHashCode(), a); + translator = new SpineMecanimTranslator(); + translator.Initialize(GetComponent(), this.skeletonDataAsset); } public void Update () { if (!valid) return; - if (layerMixModes.Length < animator.layerCount) - System.Array.Resize(ref layerMixModes, animator.layerCount); - - //skeleton.Update(Time.deltaTime); // Doesn't actually do anything, currently. (Spine 3.5). - - // Clear Previous - if (autoReset) { - var previousAnimations = this.previousAnimations; - for (int i = 0, n = previousAnimations.Count; i < n; i++) - previousAnimations[i].SetKeyedItemsToSetupPose(skeleton); - - previousAnimations.Clear(); - for (int layer = 0, n = animator.layerCount; layer < n; layer++) { - float layerWeight = (layer == 0) ? 1 : animator.GetLayerWeight(layer); // Animator.GetLayerWeight always returns 0 on the first layer. Should be interpreted as 1. - if (layerWeight <= 0) continue; - - AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer); - - bool hasNext = nextStateInfo.fullPathHash != 0; - AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(layer); - AnimatorClipInfo[] nextClipInfo = animator.GetNextAnimatorClipInfo(layer); - - for (int c = 0; c < clipInfo.Length; c++) { - var info = clipInfo[c]; - float weight = info.weight * layerWeight; if (weight == 0) continue; - previousAnimations.Add(animationTable[NameHashCode(info.clip)]); - } - if (hasNext) { - for (int c = 0; c < nextClipInfo.Length; c++) { - var info = nextClipInfo[c]; - float weight = info.weight * layerWeight; if (weight == 0) continue; - previousAnimations.Add(animationTable[NameHashCode(info.clip)]); - } - } - } - } - - // Apply - for (int layer = 0, n = animator.layerCount; layer < n; layer++) { - float layerWeight = (layer == 0) ? 1 : animator.GetLayerWeight(layer); // Animator.GetLayerWeight always returns 0 on the first layer. Should be interpreted as 1. - AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(layer); - AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer); - - bool hasNext = nextStateInfo.fullPathHash != 0; - AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(layer); - AnimatorClipInfo[] nextClipInfo = animator.GetNextAnimatorClipInfo(layer); - //UNITY 4 - //bool hasNext = nextStateInfo.nameHash != 0; - //var clipInfo = animator.GetCurrentAnimationClipState(i); - //var nextClipInfo = animator.GetNextAnimationClipState(i); - - MixMode mode = layerMixModes[layer]; - if (mode == MixMode.AlwaysMix) { - // Always use Mix instead of Applying the first non-zero weighted clip. - for (int c = 0; c < clipInfo.Length; c++) { - var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; - animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, false, false); - } - if (hasNext) { - for (int c = 0; c < nextClipInfo.Length; c++) { - var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; - animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, false, false); - } - } - } else { // case MixNext || SpineStyle - // Apply first non-zero weighted clip - int c = 0; - for (; c < clipInfo.Length; c++) { - var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; - animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, 1f, false, false); - break; - } - // Mix the rest - for (; c < clipInfo.Length; c++) { - var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; - animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed <0), stateInfo.loop, null, weight, false, false); - } - - c = 0; - if (hasNext) { - // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) - if (mode == MixMode.SpineStyle) { - for (; c < nextClipInfo.Length; c++) { - var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; - animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, false, false); - break; - } - } - // Mix the rest - for (; c < nextClipInfo.Length; c++) { - var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; - animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, false, false); - } - } - } - } + translator.Apply(skeleton, ref layerMixModes); // UpdateWorldTransform and Bone Callbacks { @@ -199,30 +238,5 @@ namespace Spine.Unity { _UpdateComplete(this); } } - - static float AnimationTime (float normalizedTime, float clipLength, bool loop, bool reversed) { - if (reversed) - normalizedTime = (1-normalizedTime + (int)normalizedTime) + (int)normalizedTime; - float time = normalizedTime * clipLength; - if (loop) return time; - const float EndSnapEpsilon = 1f/30f; // Workaround for end-duration keys not being applied. - return (clipLength - time < EndSnapEpsilon) ? clipLength : time; // return a time snapped to clipLength; - } - - static float AnimationTime (float normalizedTime, float clipLength, bool reversed) { - if (reversed) - normalizedTime = (1-normalizedTime + (int)normalizedTime) + (int)normalizedTime; - - return normalizedTime * clipLength; - } - - int NameHashCode (AnimationClip clip) { - int clipNameHashCode; - if (!clipNameHashCodeTable.TryGetValue(clip, out clipNameHashCode)) { - clipNameHashCode = clip.name.GetHashCode(); - clipNameHashCodeTable.Add(clip, clipNameHashCode); - } - return clipNameHashCode; - } } } diff --git a/spine-unity/Assets/spine-unity/SkeletonExtensions.cs b/spine-unity/Assets/spine-unity/SkeletonExtensions.cs index cfba986e4..018297e75 100644 --- a/spine-unity/Assets/spine-unity/SkeletonExtensions.cs +++ b/spine-unity/Assets/spine-unity/SkeletonExtensions.cs @@ -283,11 +283,6 @@ namespace Spine { #endregion #region Posing - [System.Obsolete("Old Animation.Apply method signature. Please use the 8 parameter signature. See summary to learn about the extra arguments.")] - public static void Apply (this Spine.Animation animation, Skeleton skeleton, float lastTime, float time, bool loop, ExposedList events) { - animation.Apply(skeleton, lastTime, time, loop, events, 1f, false, false); - } - internal static void SetPropertyToSetupPose (this Skeleton skeleton, int propertyID) { int tt = propertyID >> 24; var timelineType = (TimelineType)tt; @@ -326,6 +321,9 @@ namespace Spine { case TimelineType.Color: skeleton.slots.Items[i].SetColorToSetupPose(); break; + case TimelineType.TwoColor: + skeleton.slots.Items[i].SetColorToSetupPose(); + break; case TimelineType.Deform: skeleton.slots.Items[i].attachmentVertices.Clear(); break; @@ -341,6 +339,8 @@ namespace Spine { ikc.mix = ikc.data.mix; ikc.bendDirection = ikc.data.bendDirection; break; + + // TransformConstraint case TimelineType.TransformConstraint: var tc = skeleton.transformConstraints.Items[i]; var tcData = tc.data; @@ -384,6 +384,9 @@ namespace Spine { slot.g = slot.data.g; slot.b = slot.data.b; slot.a = slot.data.a; + slot.r2 = slot.data.r2; + slot.g2 = slot.data.g2; + slot.b2 = slot.data.b2; } /// Sets a slot's attachment to setup pose. If you have the slotIndex, Skeleton.SetSlotAttachmentToSetupPose is faster. @@ -411,17 +414,24 @@ namespace Spine { /// The name of the animation to use. /// The time of the pose within the animation. /// Wraps the time around if it is longer than the duration of the animation. - public static void PoseWithAnimation (this Skeleton skeleton, string animationName, float time, bool loop) { + public static void PoseWithAnimation (this Skeleton skeleton, string animationName, float time, bool loop = false) { // Fail loud when skeleton.data is null. Spine.Animation animation = skeleton.data.FindAnimation(animationName); if (animation == null) return; - animation.Apply(skeleton, 0, time, loop, null, 1f, false, false); + animation.Apply(skeleton, 0, time, loop, null, 1f, MixPose.Setup, MixDirection.In); + } + + /// Pose a skeleton according to a given time in an animation. + public static void PoseSkeleton (this Animation animation, Skeleton skeleton, float time, bool loop = false) { + animation.Apply(skeleton, 0, time, loop, null, 1f, MixPose.Setup, MixDirection.In); } /// Resets Skeleton parts to Setup Pose according to a Spine.Animation's keyed items. public static void SetKeyedItemsToSetupPose (this Animation animation, Skeleton skeleton) { - animation.Apply(skeleton, 0, 0, false, null, 0, true, true); + animation.Apply(skeleton, 0, 0, false, null, 0, MixPose.Setup, MixDirection.Out); } + + #endregion #region Skins