diff --git a/spine-csharp/src/AnimationStateData.cs b/spine-csharp/src/AnimationStateData.cs index eea87429e..bf36b2c55 100644 --- a/spine-csharp/src/AnimationStateData.cs +++ b/spine-csharp/src/AnimationStateData.cs @@ -35,7 +35,7 @@ using System.Collections.Generic; namespace Spine { public class AnimationStateData { internal SkeletonData skeletonData; - private Dictionary, float> animationToMixTime = new Dictionary, float>(); + private Dictionary animationToMixTime = new Dictionary(AnimationPairComparer.Instance); internal float defaultMix; public SkeletonData SkeletonData { get { return skeletonData; } } @@ -56,16 +56,41 @@ namespace Spine { public void SetMix (Animation from, Animation to, float duration) { if (from == null) throw new ArgumentNullException("from cannot be null."); if (to == null) throw new ArgumentNullException("to cannot be null."); - KeyValuePair key = new KeyValuePair(from, to); + AnimationPair key = new AnimationPair(from, to); animationToMixTime.Remove(key); animationToMixTime.Add(key, duration); } public float GetMix (Animation from, Animation to) { - KeyValuePair key = new KeyValuePair(from, to); + AnimationPair key = new AnimationPair(from, to); float duration; if (animationToMixTime.TryGetValue(key, out duration)) return duration; return defaultMix; } + + struct AnimationPair { + public readonly Animation a1; + public readonly Animation a2; + + public AnimationPair (Animation a1, Animation a2) { + this.a1 = a1; + this.a2 = a2; + } + } + + // Avoids boxing in the dictionary. + class AnimationPairComparer : IEqualityComparer { + internal static readonly AnimationPairComparer Instance = new AnimationPairComparer(); + + bool IEqualityComparer.Equals (AnimationPair x, AnimationPair y) { + return ReferenceEquals(x.a1, y.a1) && ReferenceEquals(x.a2, y.a2); + } + + int IEqualityComparer.GetHashCode (AnimationPair obj) { + // from Tuple.CombineHashCodes // return (((h1 << 5) + h1) ^ h2); + int h1 = obj.a1.GetHashCode(); + return (((h1 << 5) + h1) ^ obj.a2.GetHashCode()); + } + } } } diff --git a/spine-csharp/src/Skin.cs b/spine-csharp/src/Skin.cs index 4c1c1edaa..2f6b86019 100644 --- a/spine-csharp/src/Skin.cs +++ b/spine-csharp/src/Skin.cs @@ -61,13 +61,13 @@ namespace Spine { public void FindNamesForSlot (int slotIndex, List names) { if (names == null) throw new ArgumentNullException("names cannot be null."); foreach (AttachmentKeyTuple key in attachments.Keys) - if (key.SlotIndex == slotIndex) names.Add(key.Name); + if (key.slotIndex == slotIndex) names.Add(key.name); } public void FindAttachmentsForSlot (int slotIndex, List attachments) { if (attachments == null) throw new ArgumentNullException("attachments cannot be null."); foreach (KeyValuePair entry in this.attachments) - if (entry.Key.SlotIndex == slotIndex) attachments.Add(entry.Value); + if (entry.Key.slotIndex == slotIndex) attachments.Add(entry.Value); } override public String ToString () { @@ -77,37 +77,37 @@ namespace Spine { /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. internal void AttachAll (Skeleton skeleton, Skin oldSkin) { foreach (KeyValuePair entry in oldSkin.attachments) { - int slotIndex = entry.Key.SlotIndex; + int slotIndex = entry.Key.slotIndex; Slot slot = skeleton.slots.Items[slotIndex]; if (slot.attachment == entry.Value) { - Attachment attachment = GetAttachment(slotIndex, entry.Key.Name); + Attachment attachment = GetAttachment(slotIndex, entry.Key.name); if (attachment != null) slot.Attachment = attachment; } } } - // Avoids boxing in the dictionary. - private class AttachmentKeyTupleComparer : IEqualityComparer { - internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer(); + struct AttachmentKeyTuple { + public readonly int slotIndex; + public readonly string name; + internal readonly int nameHashCode; - bool IEqualityComparer.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) { - return o1.SlotIndex == o2.SlotIndex && o1.NameHashCode == o2.NameHashCode && o1.Name == o2.Name; - } - - int IEqualityComparer.GetHashCode (AttachmentKeyTuple o) { - return o.SlotIndex; + public AttachmentKeyTuple (int slotIndex, string name) { + this.slotIndex = slotIndex; + this.name = name; + nameHashCode = this.name.GetHashCode(); } } - private class AttachmentKeyTuple { - public readonly int SlotIndex; - public readonly string Name; - public readonly int NameHashCode; + // Avoids boxing in the dictionary. + class AttachmentKeyTupleComparer : IEqualityComparer { + internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer(); - public AttachmentKeyTuple (int slotIndex, string name) { - SlotIndex = slotIndex; - Name = name; - NameHashCode = Name.GetHashCode(); + bool IEqualityComparer.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) { + return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name; + } + + int IEqualityComparer.GetHashCode (AttachmentKeyTuple o) { + return o.slotIndex; } } } diff --git a/spine-unity/Assets/Examples/Spine/Raptor/raptor.skel.bytes b/spine-unity/Assets/Examples/Spine/Raptor/raptor.skel.bytes deleted file mode 100644 index 507d86e2e..000000000 Binary files a/spine-unity/Assets/Examples/Spine/Raptor/raptor.skel.bytes and /dev/null differ diff --git a/spine-unity/Assets/Examples/Spine/Raptor/raptor.skel.bytes.meta b/spine-unity/Assets/Examples/Spine/Raptor/raptor.skel.bytes.meta deleted file mode 100644 index 7dae281bc..000000000 --- a/spine-unity/Assets/Examples/Spine/Raptor/raptor.skel.bytes.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5d6edb328bfcef44a9d1bf852e5724bc -timeCreated: 1427642224 -licenseType: Free -TextScriptImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs index 440f3d7f8..5784b6fc3 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs @@ -147,9 +147,14 @@ public class SkeletonDataAssetInspector : Editor { GUILayout.Space(32); if (GUILayout.Button(new GUIContent("Generate Mecanim Controller"), GUILayout.Width(195), GUILayout.Height(20))) SkeletonBaker.GenerateMecanimAnimationClips(m_skeletonDataAsset); - //GUILayout.Label(new GUIContent("Alternative to SkeletonAnimation, not a requirement.", SpineEditorUtilities.Icons.warning)); GUILayout.EndHorizontal(); EditorGUILayout.LabelField("SkeletonAnimator is the Mecanim alternative to SkeletonAnimation. It is not required.", EditorStyles.miniLabel); + } else { + GUILayout.BeginHorizontal(); + GUILayout.Space(32); + if (GUILayout.Button(new GUIContent("Update Controller Animations"), GUILayout.Width(195), GUILayout.Height(20))) + SkeletonBaker.GenerateMecanimAnimationClips(m_skeletonDataAsset); + GUILayout.EndHorizontal(); } EditorGUI.indentLevel--; } @@ -228,6 +233,7 @@ public class SkeletonDataAssetInspector : Editor { } + void DrawReimportButton () { EditorGUI.BeginDisabledGroup(skeletonJSON.objectReferenceValue == null); if (GUILayout.Button(new GUIContent("Attempt Reimport", SpineEditorUtilities.Icons.warning))) { @@ -302,10 +308,14 @@ public class SkeletonDataAssetInspector : Editor { if (!showAnimationList) return; - if (GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) { - StopAnimation(); - m_skeletonAnimation.skeleton.SetToSetupPose(); - m_requireRefresh = true; + if (m_skeletonAnimation != null && m_skeletonAnimation.state != null) { + if (GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) { + StopAnimation(); + m_skeletonAnimation.skeleton.SetToSetupPose(); + m_requireRefresh = true; + } + } else { + EditorGUILayout.HelpBox("Animations can be previewed if you expand the Preview window below.", MessageType.Info); } EditorGUILayout.LabelField("Name", "Duration"); @@ -498,6 +508,10 @@ public class SkeletonDataAssetInspector : Editor { private Color m_originColor = new Color(0.3f, 0.3f, 0.3f, 1); private void StopAnimation () { + if (m_skeletonAnimation == null) { + Debug.LogWarning("Animation was stopped but preview doesn't exist. It's possible that the Preview Panel is closed."); + } + m_skeletonAnimation.state.ClearTrack(0); m_playing = false; } @@ -562,7 +576,7 @@ public class SkeletonDataAssetInspector : Editor { m_initialized = true; AdjustCameraGoals(true); } catch { - + // WARNING: Suppresses errors. } } } @@ -861,6 +875,7 @@ public class SkeletonDataAssetInspector : Editor { if (position.Contains(current.mousePosition)) { m_orthoGoal += current.delta.y; + m_orthoGoal = Mathf.Max(0.01f, m_orthoGoal); GUIUtility.hotControl = controlID; current.Use(); } @@ -959,4 +974,4 @@ public class SkeletonDataAssetInspector : Editor { tex = this.m_previewUtility.EndStaticPreview(); return tex; } -} \ No newline at end of file +} diff --git a/spine-unity/Assets/spine-unity/BoneFollower.cs b/spine-unity/Assets/spine-unity/BoneFollower.cs index 5cfb97b51..43c18fac8 100644 --- a/spine-unity/Assets/spine-unity/BoneFollower.cs +++ b/spine-unity/Assets/spine-unity/BoneFollower.cs @@ -40,14 +40,8 @@ using Spine; [AddComponentMenu("Spine/BoneFollower")] public class BoneFollower : MonoBehaviour { - [System.NonSerialized] - public bool - valid; + #region Inspector public SkeletonRenderer skeletonRenderer; - public Bone bone; - public bool followZPosition = true; - public bool followBoneRotation = true; - public SkeletonRenderer SkeletonRenderer { get { return skeletonRenderer; } set { @@ -55,15 +49,21 @@ public class BoneFollower : MonoBehaviour { Reset(); } } - - /// If a bone isn't set, boneName is used to find the bone. - [SpineBone(dataField: "skeletonRenderer")] public String boneName; + + public bool followZPosition = true; + public bool followBoneRotation = true; public bool resetOnAwake = true; - protected Transform cachedTransform; - protected Transform skeletonTransform; + #endregion + + [NonSerialized] + public bool valid; + + [NonSerialized] + public Bone bone; + Transform skeletonTransform; public void HandleResetRenderer (SkeletonRenderer skeletonRenderer) { Reset(); @@ -71,21 +71,21 @@ public class BoneFollower : MonoBehaviour { public void Reset () { bone = null; - cachedTransform = transform; valid = skeletonRenderer != null && skeletonRenderer.valid; - if (!valid) - return; - skeletonTransform = skeletonRenderer.transform; + if (!valid) return; + + skeletonTransform = skeletonRenderer.transform; skeletonRenderer.OnRebuild -= HandleResetRenderer; skeletonRenderer.OnRebuild += HandleResetRenderer; + #if UNITY_EDITOR if (Application.isEditor) DoUpdate(); + #endif } void OnDestroy () { - //cleanup if (skeletonRenderer != null) skeletonRenderer.OnRebuild -= HandleResetRenderer; } @@ -112,33 +112,33 @@ public class BoneFollower : MonoBehaviour { if (bone == null) { Debug.LogError("Bone not found: " + boneName, this); return; - } else { - } } - Spine.Skeleton skeleton = skeletonRenderer.skeleton; + Skeleton skeleton = skeletonRenderer.skeleton; float flipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f; + Transform thisTransform = this.transform; - if (cachedTransform.parent == skeletonTransform) { - cachedTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : cachedTransform.localPosition.z); + // Recommended setup: Use local transform properties if Spine GameObject is parent + if (thisTransform.parent == skeletonTransform) { + thisTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : thisTransform.localPosition.z); if (followBoneRotation) { - Vector3 rotation = cachedTransform.localRotation.eulerAngles; - cachedTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.WorldRotationX * flipRotation); + Vector3 rotation = thisTransform.localRotation.eulerAngles; + thisTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.WorldRotationX * flipRotation); } + // For special cases: Use transform world properties if transform relationship is complicated } else { Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f)); if (!followZPosition) - targetWorldPosition.z = cachedTransform.position.z; + targetWorldPosition.z = thisTransform.position.z; - cachedTransform.position = targetWorldPosition; + thisTransform.position = targetWorldPosition; if (followBoneRotation) { - Vector3 rotation = skeletonTransform.rotation.eulerAngles; - - cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, skeletonTransform.rotation.eulerAngles.z + (bone.WorldRotationX * flipRotation)); + Vector3 worldRotation = skeletonTransform.rotation.eulerAngles; + thisTransform.rotation = Quaternion.Euler(worldRotation.x, worldRotation.y, skeletonTransform.rotation.eulerAngles.z + (bone.WorldRotationX * flipRotation)); } } diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs index 44ae92a43..033235775 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs @@ -4,6 +4,8 @@ * SkeletonBaker added by Mitch Thompson * Full irrevocable rights and permissions granted to Esoteric Software *****************************************************************************/ +#define SPINE_SKELETON_ANIMATOR + using UnityEngine; using UnityEditor; using UnityEditorInternal; @@ -44,6 +46,133 @@ using Spine; /// public static class SkeletonBaker { + + #region SkeletonAnimator's Mecanim Clips +#if SPINE_SKELETON_ANIMATOR + public static void GenerateMecanimAnimationClips (SkeletonDataAsset skeletonDataAsset) { + //skeletonDataAsset.Clear(); + var data = skeletonDataAsset.GetSkeletonData(true); + if (data == null) { + Debug.LogError("SkeletonData failed!", skeletonDataAsset); + return; + } + + string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset); + string controllerPath = dataPath.Replace("_SkeletonData", "_Controller").Replace(".asset", ".controller"); + +#if UNITY_5 + UnityEditor.Animations.AnimatorController controller; + + if (skeletonDataAsset.controller != null) { + controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller; + controllerPath = AssetDatabase.GetAssetPath(controller); + } else { + if (File.Exists(controllerPath)) { + if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) { + controller = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); + } else { + controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + } + } else { + controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + } + + } +#else + UnityEditorInternal.AnimatorController controller; + + if (skeletonDataAsset.controller != null) { + controller = (UnityEditorInternal.AnimatorController)skeletonDataAsset.controller; + controllerPath = AssetDatabase.GetAssetPath(controller); + } else { + if (File.Exists(controllerPath)) { + if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) { + controller = (UnityEditorInternal.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); + } else { + controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + } + } else { + controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); + } + } +#endif + + skeletonDataAsset.controller = controller; + EditorUtility.SetDirty(skeletonDataAsset); + + UnityEngine.Object[] objs = AssetDatabase.LoadAllAssetsAtPath(controllerPath); + + var unityAnimationClipTable = new Dictionary(); + var spineAnimationTable = new Dictionary(); + + foreach (var o in objs) { + //Debug.LogFormat("({0}){1} : {3} + {2} + {4}", o.GetType(), o.name, o.hideFlags, o.GetInstanceID(), o.GetHashCode()); + // There is a bug in Unity 5.3.3 (and likely before) that creates + // a duplicate AnimationClip when you duplicate a Mecanim Animator State. + // These duplicates seem to be identifiable by their HideFlags, so we'll exclude them. + if (o is AnimationClip) { + var clip = o as AnimationClip; + if (!clip.HasFlag(HideFlags.HideInHierarchy)) { + if (unityAnimationClipTable.ContainsKey(clip.name)) { + Debug.LogWarningFormat("Duplicate AnimationClips were found named {0}", clip.name); + } + unityAnimationClipTable.Add(clip.name, clip); + } + } + } + + foreach (var anim in data.Animations) { + string name = anim.Name; + spineAnimationTable.Add(name, anim); + + if (unityAnimationClipTable.ContainsKey(name) == false) { + //generate new dummy clip + AnimationClip newClip = new AnimationClip(); + newClip.name = name; +#if !(UNITY_5) + AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic); +#endif + AssetDatabase.AddObjectToAsset(newClip, controller); + unityAnimationClipTable.Add(name, newClip); + } + + AnimationClip clip = unityAnimationClipTable[name]; + + clip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, anim.Duration, 0)); + var settings = AnimationUtility.GetAnimationClipSettings(clip); + settings.stopTime = anim.Duration; + + SetAnimationSettings(clip, settings); + + AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]); + + foreach (Timeline t in anim.Timelines) { + if (t is EventTimeline) { + ParseEventTimeline((EventTimeline)t, clip, SendMessageOptions.DontRequireReceiver); + } + } + + EditorUtility.SetDirty(clip); + + unityAnimationClipTable.Remove(name); + } + + //clear no longer used animations + foreach (var clip in unityAnimationClipTable.Values) { + AnimationClip.DestroyImmediate(clip, true); + } + + AssetDatabase.Refresh(); + AssetDatabase.SaveAssets(); + } + + static bool HasFlag (this UnityEngine.Object o, HideFlags flagToCheck) { + return (o.hideFlags & flagToCheck) == flagToCheck; + } +#endif + #endregion + + #region Baking /// /// Interval between key sampling for Bezier curves, IK controlled bones, and Inherit Rotation effected bones. /// @@ -89,8 +218,8 @@ public static class SkeletonBaker { } #endif - Dictionary existingClipTable = new Dictionary(); - List unusedClipNames = new List(); + var existingClipTable = new Dictionary(); + var unusedClipNames = new List(); Object[] animObjs = AssetDatabase.LoadAllAssetsAtPath(controllerPath); foreach (Object o in animObjs) { @@ -344,115 +473,6 @@ public static class SkeletonBaker { } - public static void GenerateMecanimAnimationClips (SkeletonDataAsset skeletonDataAsset) { - var data = skeletonDataAsset.GetSkeletonData(true); - if (data == null) { - Debug.LogError("SkeletonData failed!", skeletonDataAsset); - return; - } - - string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset); - string controllerPath = dataPath.Replace("_SkeletonData", "_Controller").Replace(".asset", ".controller"); - - -#if UNITY_5 - UnityEditor.Animations.AnimatorController controller; - - if (skeletonDataAsset.controller != null) { - controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller; - controllerPath = AssetDatabase.GetAssetPath(controller); - } else { - if (File.Exists(controllerPath)) { - if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) { - controller = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); - } else { - controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); - } - } else { - controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); - } - - } -#else - UnityEditorInternal.AnimatorController controller; - - if (skeletonDataAsset.controller != null) { - controller = (UnityEditorInternal.AnimatorController)skeletonDataAsset.controller; - controllerPath = AssetDatabase.GetAssetPath(controller); - } else { - if (File.Exists(controllerPath)) { - if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) { - controller = (UnityEditorInternal.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); - } else { - controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); - } - } else { - controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); - } - } -#endif - - skeletonDataAsset.controller = controller; - EditorUtility.SetDirty(skeletonDataAsset); - - Object[] objs = AssetDatabase.LoadAllAssetsAtPath(controllerPath); - - Dictionary clipTable = new Dictionary(); - Dictionary animTable = new Dictionary(); - - foreach (var o in objs) { - if (o is AnimationClip) { - clipTable.Add(o.name, (AnimationClip)o); - } - } - - foreach (var anim in data.Animations) { - string name = anim.Name; - animTable.Add(name, anim); - - if (clipTable.ContainsKey(name) == false) { - //generate new dummy clip - AnimationClip newClip = new AnimationClip(); - newClip.name = name; -#if UNITY_5 -#else - AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic); -#endif - - AssetDatabase.AddObjectToAsset(newClip, controller); - clipTable.Add(name, newClip); - } - - AnimationClip clip = clipTable[name]; - - clip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, anim.Duration, 0)); - var settings = AnimationUtility.GetAnimationClipSettings(clip); - settings.stopTime = anim.Duration; - - SetAnimationSettings(clip, settings); - - AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]); - - foreach (Timeline t in anim.Timelines) { - if (t is EventTimeline) { - ParseEventTimeline((EventTimeline)t, clip, SendMessageOptions.DontRequireReceiver); - } - } - - EditorUtility.SetDirty(clip); - - clipTable.Remove(name); - } - - //clear no longer used animations - foreach (var clip in clipTable.Values) { - AnimationClip.DestroyImmediate(clip, true); - } - - AssetDatabase.Refresh(); - AssetDatabase.SaveAssets(); - } - static Bone extractionBone; static Slot extractionSlot; @@ -747,17 +767,6 @@ public static class SkeletonBaker { return arr; } - static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) { -#if UNITY_5 - AnimationUtility.SetAnimationClipSettings(clip, settings); -#else - MethodInfo methodInfo = typeof(AnimationUtility).GetMethod("SetAnimationClipSettings", BindingFlags.Static | BindingFlags.NonPublic); - methodInfo.Invoke(null, new object[] { clip, settings }); - - EditorUtility.SetDirty(clip); -#endif - } - static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) { var animation = skeletonData.FindAnimation(name); @@ -864,7 +873,7 @@ public static class SkeletonBaker { ae.functionName = ev.Data.Name; ae.messageOptions = eventOptions; - if (ev.String != "" && ev.String != null) { + if (!string.IsNullOrEmpty(ev.String)) { ae.stringParameter = ev.String; } else { if (ev.Int == 0 && ev.Float == 0) { @@ -1447,7 +1456,6 @@ public static class SkeletonBaker { AnimationUtility.SetEditorCurve(clip, yBind, new AnimationCurve()); EditorCurveBinding zBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".z"); AnimationUtility.SetEditorCurve(clip, zBind, curve); - } static string GetPath (BoneData b) { @@ -1461,4 +1469,18 @@ public static class SkeletonBaker { return GetPathRecurse(b.Parent) + "/" + b.Name; } + #endregion + + static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) { +#if UNITY_5 + AnimationUtility.SetAnimationClipSettings(clip, settings); +#else + MethodInfo methodInfo = typeof(AnimationUtility).GetMethod("SetAnimationClipSettings", BindingFlags.Static | BindingFlags.NonPublic); + methodInfo.Invoke(null, new object[] { clip, settings }); + + EditorUtility.SetDirty(clip); +#endif + } + + } diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs index 95ec58550..17284f978 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs @@ -117,8 +117,8 @@ public class SkeletonRendererInspector : Editor { new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility")); EditorGUILayout.Space(); - const float MinZSpacing = 0f; - const float MaxZSpacing = 0.1f; + const float MinZSpacing = -0.1f; + const float MaxZSpacing = 0f; EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing); EditorGUILayout.PropertyField(normals); diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index 11e9c737a..d99750ab3 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -1135,10 +1135,13 @@ public class SpineEditorUtilities : AssetPostprocessor { static void EnableTK2D () { bool added = false; foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) { + if (group == BuildTargetGroup.Unknown) + continue; + string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group); if (!defines.Contains(SPINE_TK2D_DEFINE)) { added = true; - if (defines.EndsWith(";")) + if (defines.EndsWith(";", System.StringComparison.Ordinal)) defines = defines + SPINE_TK2D_DEFINE; else defines = defines + ";" + SPINE_TK2D_DEFINE; diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs index 94079c6ad..3fe90035f 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityInspector.cs @@ -94,21 +94,20 @@ public class SkeletonUtilityInspector : Editor { } - void OnDestroy () { - - } - void OnSceneGUI () { if (skeleton == null) { OnEnable(); return; } - float flipRotation = skeleton.FlipX ? -1 : 1; + // MITCH + //float flipRotation = skeleton.FlipX ? -1 : 1; + const float flipRotation = 1; foreach (Bone b in skeleton.Bones) { Vector3 vec = transform.TransformPoint(new Vector3(b.WorldX, b.WorldY, 0)); + // MITCH Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX * flipRotation); Vector3 forward = transform.TransformDirection(rot * Vector3.right); forward *= flipRotation;