Ver código fonte

Mecanim Dummy Clip Generation Warning

There was a Unity bug causing an internal Dictionary add to fail, and thus prevent existing generated Mecanim controller from being updated.
Posted on the Unity forums here: http://forum.unity3d.com/threads/bug-hidden-duplicate-animationclips.391202/
John 9 anos atrás
pai
commit
2f3a572ff6
1 arquivos alterados com 146 adições e 124 exclusões
  1. 146 124
      spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs

+ 146 - 124
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;
 
 /// </summary>
 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<string, AnimationClip>();
+		var spineAnimationTable = new Dictionary<string, Spine.Animation>();
+
+		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
 	/// <summary>
 	/// Interval between key sampling for Bezier curves, IK controlled bones, and Inherit Rotation effected bones.
 	/// </summary>
@@ -89,8 +218,8 @@ public static class SkeletonBaker {
 			}
 #endif
 
-			Dictionary<string, AnimationClip> existingClipTable = new Dictionary<string, AnimationClip>();
-			List<string> unusedClipNames = new List<string>();
+			var existingClipTable = new Dictionary<string, AnimationClip>();
+			var unusedClipNames = new List<string>();
 			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<string, AnimationClip> clipTable = new Dictionary<string, AnimationClip>();
-		Dictionary<string, Spine.Animation> animTable = new Dictionary<string, Spine.Animation>();
-
-		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<int, List<string>> 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
+	}
+
+
 }