Browse Source

[unity] Added support for Timeline in Unity 2019, using existing components. Please visit Edit-Preferences-Spine to enable Timeline support. Closes #1326.

Harald Csaszar 6 years ago
parent
commit
cb615007d6

+ 207 - 61
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs

@@ -45,6 +45,10 @@
 #define NEWHIERARCHYWINDOWCALLBACKS
 #define NEWHIERARCHYWINDOWCALLBACKS
 #endif
 #endif
 
 
+#if UNITY_2019_1_OR_NEWER
+#define NEW_TIMELINE_AS_PACKAGE
+#endif
+
 using UnityEngine;
 using UnityEngine;
 using UnityEditor;
 using UnityEditor;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -1788,94 +1792,236 @@ namespace Spine.Unity.Editor {
 		internal static class SpineTK2DEditorUtility {
 		internal static class SpineTK2DEditorUtility {
 			const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
 			const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
 
 
-			static bool IsInvalidGroup (BuildTargetGroup group) {
-				int gi = (int)group;
-				return
-					gi == 15 || gi == 16
-					||
-					group == BuildTargetGroup.Unknown;
+			internal static void EnableTK2D () {
+				SpineBuildEnvUtility.DisableSpineAsmdefFiles();
+				SpineBuildEnvUtility.EnableBuildDefine(SPINE_TK2D_DEFINE);
 			}
 			}
 
 
-			internal static void EnableTK2D () {
-				bool added = false;
+			internal static void DisableTK2D () {
+				SpineBuildEnvUtility.EnableSpineAsmdefFiles();
+				SpineBuildEnvUtility.DisableBuildDefine(SPINE_TK2D_DEFINE);
+			}
+		}
+
+		public static class SpinePackageDependencyUtility
+		{
+			public enum RequestState {
+				NoRequestIssued = 0,
+				InProgress,
+				Success,
+				Failure
+			}
+
+			#if NEW_TIMELINE_AS_PACKAGE
+			const string SPINE_TIMELINE_PACKAGE_DOWNLOADED_DEFINE = "SPINE_TIMELINE_PACKAGE_DOWNLOADED";
+			const string TIMELINE_PACKAGE_NAME = "com.unity.timeline";
+			const string TIMELINE_ASMDEF_DEPENDENCY_STRING = "\"Unity.Timeline\"";
+			static UnityEditor.PackageManager.Requests.AddRequest timelineRequest = null;
+			
+			/// <summary>
+			/// Enables Spine's Timeline components by downloading the Timeline Package in Unity 2019 and newer
+			/// and setting respective compile definitions once downloaded.
+			/// </summary>
+			internal static void EnableTimelineSupport () {
+				Debug.Log("Downloading Timeline package " + TIMELINE_PACKAGE_NAME + ".");
+				timelineRequest = UnityEditor.PackageManager.Client.Add(TIMELINE_PACKAGE_NAME);
+				// Note: unfortunately there is no callback provided, only polling support.
+				// So polling HandlePendingAsyncTimelineRequest() is necessary.
 
 
-				DisableSpineAsmdefFiles();
+				EditorApplication.update -= UpdateAsyncTimelineRequest;
+				EditorApplication.update += UpdateAsyncTimelineRequest;
+			}
 
 
-				foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
-					if (IsInvalidGroup(group))
-						continue;
+			public static void UpdateAsyncTimelineRequest () {
+				HandlePendingAsyncTimelineRequest();
+			}
 
 
-					string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
-					if (!defines.Contains(SPINE_TK2D_DEFINE)) {
-						added = true;
-						if (defines.EndsWith(";", System.StringComparison.Ordinal))
-							defines = defines + SPINE_TK2D_DEFINE;
-						else
-							defines = defines + ";" + SPINE_TK2D_DEFINE;
+			public static RequestState HandlePendingAsyncTimelineRequest () {
+				if (timelineRequest == null)
+					return RequestState.NoRequestIssued;
 
 
-						PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
+				var status = timelineRequest.Status;
+				if (status == UnityEditor.PackageManager.StatusCode.InProgress) {
+					return RequestState.InProgress;
+				}
+				else {
+					EditorApplication.update -= UpdateAsyncTimelineRequest;
+					timelineRequest = null;
+					if (status == UnityEditor.PackageManager.StatusCode.Failure) {
+						Debug.LogError("Download of package " + TIMELINE_PACKAGE_NAME + " failed!");
+						return RequestState.Failure;
+					}
+					else { // status == UnityEditor.PackageManager.StatusCode.Success
+						HandleSuccessfulTimelinePackageDownload();
+						return RequestState.Success;
 					}
 					}
 				}
 				}
+			}
 
 
-				if (added) {
-					Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE);
-				} else {
-					Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE);
-				}
+			internal static void DisableTimelineSupport () {
+				SpineBuildEnvUtility.DisableBuildDefine(SPINE_TIMELINE_PACKAGE_DOWNLOADED_DEFINE);
+				SpineBuildEnvUtility.RemoveDependencyFromAsmdefFile(TIMELINE_ASMDEF_DEPENDENCY_STRING);
 			}
 			}
 
 
+			internal static void HandleSuccessfulTimelinePackageDownload () {
 
 
-			internal static void DisableTK2D () {
-				bool removed = false;
+				SpineBuildEnvUtility.AddDependencyToAsmdefFile(TIMELINE_ASMDEF_DEPENDENCY_STRING);
+				SpineBuildEnvUtility.EnableBuildDefine(SPINE_TIMELINE_PACKAGE_DOWNLOADED_DEFINE);
+			}
+			#endif
+		}
+	}
 
 
-				EnableSpineAsmdefFiles();
+	public static class SpineBuildEnvUtility
+	{
+		static bool IsInvalidGroup (BuildTargetGroup group) {
+			int gi = (int)group;
+			return
+				gi == 15 || gi == 16
+				||
+				group == BuildTargetGroup.Unknown;
+		}
 
 
-				foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
-					if (IsInvalidGroup(group))
-						continue;
+		public static bool EnableBuildDefine (string define) {
+			
+			bool wasDefineAdded = false;
+			Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" below");
+			foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
+				if (IsInvalidGroup(group))
+					continue;
 
 
-					string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
-					if (defines.Contains(SPINE_TK2D_DEFINE)) {
-						removed = true;
-						if (defines.Contains(SPINE_TK2D_DEFINE + ";"))
-							defines = defines.Replace(SPINE_TK2D_DEFINE + ";", "");
-						else
-							defines = defines.Replace(SPINE_TK2D_DEFINE, "");
+				string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
+				if (!defines.Contains(define)) {
+					wasDefineAdded = true;
+					if (defines.EndsWith(";", System.StringComparison.Ordinal))
+						defines += define;
+					else
+						defines += ";" + define;
+					
+					PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
+				}
+			}
+			Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" above");
 
 
-						PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
-					}
+			if (wasDefineAdded) {
+				Debug.LogWarning("Setting Scripting Define Symbol " + define);
+			}
+			else {
+				Debug.LogWarning("Already Set Scripting Define Symbol " + define);
+			}
+			return wasDefineAdded;
+		}
+
+		public static bool DisableBuildDefine (string define) {
+			
+			bool wasDefineRemoved = false;
+			foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
+				if (IsInvalidGroup(group))
+					continue;
+
+				string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
+				if (defines.Contains(define)) {
+					wasDefineRemoved = true;
+					if (defines.Contains(define + ";"))
+						defines = defines.Replace(define + ";", "");
+					else
+						defines = defines.Replace(define, "");
+
+					PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
 				}
 				}
+			}
 
 
-				if (removed) {
-					Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE);
-				} else {
-					Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE);
+			if (wasDefineRemoved) {
+				Debug.LogWarning("Removing Scripting Define Symbol " + define);
+			}
+			else {
+				Debug.LogWarning("Already Removed Scripting Define Symbol " + define);
+			}
+			return wasDefineRemoved;
+		}
+
+		public static void DisableSpineAsmdefFiles () {
+			SetAsmdefFileActive("spine-unity-editor", false);
+			SetAsmdefFileActive("spine-unity", false);
+		}
+
+		public static void EnableSpineAsmdefFiles () {
+			SetAsmdefFileActive("spine-unity-editor", true);
+			SetAsmdefFileActive("spine-unity", true);
+		}
+
+		public static void AddDependencyToAsmdefFile (string dependencyName) {
+			string asmdefName = "spine-unity";
+			string filePath = FindAsmdefFile(asmdefName);
+			if (string.IsNullOrEmpty(filePath))
+				return;
+
+			if (System.IO.File.Exists(filePath)) {
+				string fileContent = File.ReadAllText(filePath);
+				// this simple implementation shall suffice for now.
+				if (!fileContent.Contains(dependencyName)) {
+					fileContent = fileContent.Replace(@"""references"": [",
+													@"""references"": [" + dependencyName);
+					File.WriteAllText(filePath, fileContent);
 				}
 				}
 			}
 			}
+		}
 
 
-			internal static void DisableSpineAsmdefFiles() {
-				SetAsmdefFileActive("spine-unity-editor", false);
-				SetAsmdefFileActive("spine-unity", false);
+		public static void RemoveDependencyFromAsmdefFile (string dependencyName) {
+			string asmdefName = "spine-unity";
+			string filePath = FindAsmdefFile(asmdefName);
+			if (string.IsNullOrEmpty(filePath))
+				return;
+
+			if (System.IO.File.Exists(filePath)) {
+				string fileContent = File.ReadAllText(filePath);
+				// this simple implementation shall suffice for now.
+				if (fileContent.Contains(dependencyName)) {
+					fileContent = fileContent.Replace(dependencyName, "");
+					File.WriteAllText(filePath, fileContent);
+				}
 			}
 			}
+		}
 
 
-			internal static void EnableSpineAsmdefFiles() {
-				SetAsmdefFileActive("spine-unity-editor", true);
-				SetAsmdefFileActive("spine-unity", true);
+		internal static string FindAsmdefFile (string filename) {
+			string filePath = FindAsmdefFile(filename, isDisabledFile: false);
+			if (string.IsNullOrEmpty(filePath))
+				filePath = FindAsmdefFile(filename, isDisabledFile: true);
+			return filePath;
+		}
+
+		internal static string FindAsmdefFile (string filename, bool isDisabledFile) {
+
+			string typeSearchString = isDisabledFile ? " t:TextAsset" : " t:AssemblyDefinitionAsset";
+			string extension = isDisabledFile ? ".txt" : ".asmdef";
+			string filenameWithExtension = filename + (isDisabledFile ? ".txt" : ".asmdef");
+			string[] guids = AssetDatabase.FindAssets(filename + typeSearchString);
+			foreach (string guid in guids) {
+				string currentPath = AssetDatabase.GUIDToAssetPath(guid);
+				if (!string.IsNullOrEmpty(currentPath)) {
+					if (System.IO.Path.GetFileName(currentPath) == filenameWithExtension)
+						return currentPath;
+				}
 			}
 			}
+			return null;
+		}
 
 
-			internal static void SetAsmdefFileActive(string filename, bool setActive) {
+		internal static void SetAsmdefFileActive (string filename, bool setActive) {
 
 
-				string typeSearchString = setActive ? " t:TextAsset" : " t:AssemblyDefinitionAsset";
-				string[] guids = AssetDatabase.FindAssets(filename + typeSearchString);
-				foreach (string guid in guids) {
-					string currentPath = AssetDatabase.GUIDToAssetPath(guid);
-					string targetPath = System.IO.Path.ChangeExtension(currentPath, setActive ? "asmdef" : "txt");
-					if (System.IO.File.Exists(currentPath) && !System.IO.File.Exists(targetPath)) {
-						System.IO.File.Copy(currentPath, targetPath);
-						System.IO.File.Copy(currentPath + ".meta", targetPath + ".meta");
-					}
-					AssetDatabase.DeleteAsset(currentPath);
+			string typeSearchString = setActive ? " t:TextAsset" : " t:AssemblyDefinitionAsset";
+			string extensionBeforeChange = setActive ? "txt" : "asmdef";
+			string[] guids = AssetDatabase.FindAssets(filename + typeSearchString);
+			foreach (string guid in guids) {
+				string currentPath = AssetDatabase.GUIDToAssetPath(guid);
+				if (!System.IO.Path.HasExtension(extensionBeforeChange)) // asmdef is also found as t:TextAsset, so check
+					continue;
+
+				string targetPath = System.IO.Path.ChangeExtension(currentPath, setActive ? "asmdef" : "txt");
+				if (System.IO.File.Exists(currentPath) && !System.IO.File.Exists(targetPath)) {
+					System.IO.File.Copy(currentPath, targetPath);
+					System.IO.File.Copy(currentPath + ".meta", targetPath + ".meta");
 				}
 				}
+				AssetDatabase.DeleteAsset(currentPath);
 			}
 			}
 		}
 		}
 	}
 	}

+ 2 - 2
spine-unity/Assets/Spine/Editor/spine-unity/Modules/Timeline/Editor/SpineSkeletonFlipDrawer.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using UnityEditor;
 using UnityEditor;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;
@@ -53,4 +53,4 @@ public class SpineSkeletonFlipDrawer : PropertyDrawer
 		EditorGUI.PropertyField(singleFieldRect, flipYProp);
 		EditorGUI.PropertyField(singleFieldRect, flipYProp);
     }
     }
 }
 }
-#endif
+#endif

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/PlayableHandle Component/SkeletonAnimationPlayableHandle.cs

@@ -58,7 +58,7 @@ namespace Spine.Unity.Playables {
 		public override Skeleton Skeleton {	get { return skeletonAnimation.Skeleton; } }
 		public override Skeleton Skeleton {	get { return skeletonAnimation.Skeleton; } }
 		public override SkeletonData SkeletonData { get { return skeletonAnimation.Skeleton.data; } }
 		public override SkeletonData SkeletonData { get { return skeletonAnimation.Skeleton.data; } }
 
 
-		#if UNITY_2017 || UNITY_2018
+		#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 		void Awake () {
 		void Awake () {
 			if (skeletonAnimation == null)
 			if (skeletonAnimation == null)
 				skeletonAnimation = GetComponent<SkeletonAnimation>();
 				skeletonAnimation = GetComponent<SkeletonAnimation>();

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateBehaviour.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using System;
 using System;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateClip.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using System;
 using System;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs

@@ -29,7 +29,7 @@
 
 
 #define SPINE_EDITMODEPOSE
 #define SPINE_EDITMODEPOSE
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using System;
 using System;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineAnimationState/SpineAnimationStateTrack.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;
 using UnityEngine.Timeline;
 using UnityEngine.Timeline;

+ 2 - 2
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipBehaviour.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using System;
 using System;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;
@@ -37,4 +37,4 @@ using UnityEngine.Timeline;
 public class SpineSkeletonFlipBehaviour : PlayableBehaviour {
 public class SpineSkeletonFlipBehaviour : PlayableBehaviour {
     public bool flipX, flipY;
     public bool flipX, flipY;
 }
 }
-#endif
+#endif

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipClip.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
 using System;
 using System;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipMixerBehaviour.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
  using System;
  using System;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;

+ 1 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Timeline/SpineSkeletonFlip/SpineSkeletonFlipTrack.cs

@@ -27,7 +27,7 @@
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#if UNITY_2017 || UNITY_2018
+#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
  using UnityEngine;
  using UnityEngine;
 using UnityEngine.Playables;
 using UnityEngine.Playables;
 using UnityEngine.Timeline;
 using UnityEngine.Timeline;