From f25f33fbc5017edaa6a1b24f2acf7d76c1d807e1 Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Tue, 17 Feb 2015 17:33:30 -0800 Subject: [PATCH] MixMode list added to SkeletonAnimator --- .../Editor/SkeletonAnimatorInspector.cs | 16 ++-- .../Assets/spine-unity/SkeletonAnimator.cs | 94 ++++++++++++++++--- 2 files changed, 88 insertions(+), 22 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs index dfbac484c..333ccefcd 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonAnimatorInspector.cs @@ -34,22 +34,22 @@ using Spine; [CustomEditor(typeof(SkeletonAnimator))] public class SkeletonAnimatorInspector : SkeletonRendererInspector { - protected SerializedProperty animationName, loop, timeScale; - protected bool isPrefab; + protected SerializedProperty layerMixModes; protected override void OnEnable () { base.OnEnable(); - animationName = serializedObject.FindProperty("_animationName"); - loop = serializedObject.FindProperty("loop"); - timeScale = serializedObject.FindProperty("timeScale"); - - if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab) - isPrefab = true; + layerMixModes = serializedObject.FindProperty("layerMixModes"); + } protected override void gui () { base.gui(); + + + EditorGUILayout.PropertyField(layerMixModes, true); + + serializedObject.ApplyModifiedProperties(); } } diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs index f218ae89a..3b950c5e0 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs @@ -6,6 +6,9 @@ using Spine; [RequireComponent(typeof(Animator))] public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { + public enum MixMode { AlwaysMix, MixNext, SpineStyle } + public MixMode[] layerMixModes = new MixMode[0]; + public event UpdateBonesDelegate UpdateLocal { add { _UpdateLocal += value; } remove { _UpdateLocal -= value; } @@ -42,12 +45,18 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { } animator = GetComponent(); + + } void Update () { - if (skeleton == null) + if (!valid) return; + if (layerMixModes.Length != animator.layerCount) { + System.Array.Resize(ref layerMixModes, animator.layerCount); + } + skeleton.Update(Time.deltaTime); //apply @@ -64,22 +73,79 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { var nextStateInfo = animator.GetNextAnimatorStateInfo(i); var nextClipInfo = animator.GetNextAnimationClipState(i); - foreach (var info in clipInfo) { - float weight = info.weight * layerWeight; - if (weight == 0) - continue; + MixMode mode = layerMixModes[i]; - float time = stateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); - } + if (mode == MixMode.AlwaysMix) { + //always use Mix instead of Applying the first non-zero weighted clip + foreach (var info in clipInfo) { + float weight = info.weight * layerWeight; + if (weight == 0) + continue; - foreach (var info in nextClipInfo) { - float weight = info.weight * layerWeight; - if (weight == 0) - continue; + float time = stateInfo.normalizedTime * info.clip.length; + animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); + } - float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); + foreach (var info in nextClipInfo) { + float weight = info.weight * layerWeight; + if (weight == 0) + continue; + + float time = nextStateInfo.normalizedTime * info.clip.length; + animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); + } + } else if (mode >= MixMode.MixNext) { + //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; + + float time = stateInfo.normalizedTime * info.clip.length; + animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null); + break; + } + + //mix the rest + for (; c < clipInfo.Length; c++) { + var info = clipInfo[c]; + float weight = info.weight * layerWeight; + if (weight == 0) + continue; + + float time = stateInfo.normalizedTime * info.clip.length; + animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); + } + + c = 0; + + //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; + + float time = nextStateInfo.normalizedTime * info.clip.length; + animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null); + break; + } + } + + //mix the rest + for (; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; + float weight = info.weight * layerWeight; + if (weight == 0) + continue; + + float time = nextStateInfo.normalizedTime * info.clip.length; + animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); + } } }