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

This commit is contained in:
Harald Csaszar 2019-04-30 18:07:51 +02:00
parent 67f469b06d
commit cb615007d6
11 changed files with 227 additions and 81 deletions

View File

@ -45,6 +45,10 @@
#define NEWHIERARCHYWINDOWCALLBACKS
#endif
#if UNITY_2019_1_OR_NEWER
#define NEW_TIMELINE_AS_PACKAGE
#endif
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
@ -1788,6 +1792,88 @@ namespace Spine.Unity.Editor {
internal static class SpineTK2DEditorUtility {
const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
internal static void EnableTK2D () {
SpineBuildEnvUtility.DisableSpineAsmdefFiles();
SpineBuildEnvUtility.EnableBuildDefine(SPINE_TK2D_DEFINE);
}
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.
EditorApplication.update -= UpdateAsyncTimelineRequest;
EditorApplication.update += UpdateAsyncTimelineRequest;
}
public static void UpdateAsyncTimelineRequest () {
HandlePendingAsyncTimelineRequest();
}
public static RequestState HandlePendingAsyncTimelineRequest () {
if (timelineRequest == null)
return RequestState.NoRequestIssued;
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;
}
}
}
internal static void DisableTimelineSupport () {
SpineBuildEnvUtility.DisableBuildDefine(SPINE_TIMELINE_PACKAGE_DOWNLOADED_DEFINE);
SpineBuildEnvUtility.RemoveDependencyFromAsmdefFile(TIMELINE_ASMDEF_DEPENDENCY_STRING);
}
internal static void HandleSuccessfulTimelinePackageDownload () {
SpineBuildEnvUtility.AddDependencyToAsmdefFile(TIMELINE_ASMDEF_DEPENDENCY_STRING);
SpineBuildEnvUtility.EnableBuildDefine(SPINE_TIMELINE_PACKAGE_DOWNLOADED_DEFINE);
}
#endif
}
}
public static class SpineBuildEnvUtility
{
static bool IsInvalidGroup (BuildTargetGroup group) {
int gi = (int)group;
return
@ -1796,79 +1882,140 @@ namespace Spine.Unity.Editor {
group == BuildTargetGroup.Unknown;
}
internal static void EnableTK2D () {
bool added = false;
DisableSpineAsmdefFiles();
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)) {
added = true;
if (!defines.Contains(define)) {
wasDefineAdded = true;
if (defines.EndsWith(";", System.StringComparison.Ordinal))
defines = defines + SPINE_TK2D_DEFINE;
defines += define;
else
defines = defines + ";" + SPINE_TK2D_DEFINE;
defines += ";" + define;
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
}
}
Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" above");
if (added) {
Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE);
} else {
Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE);
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) {
internal static void DisableTK2D () {
bool removed = false;
EnableSpineAsmdefFiles();
bool wasDefineRemoved = false;
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 + ";", "");
if (defines.Contains(define)) {
wasDefineRemoved = true;
if (defines.Contains(define + ";"))
defines = defines.Replace(define + ";", "");
else
defines = defines.Replace(SPINE_TK2D_DEFINE, "");
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;
}
internal static void DisableSpineAsmdefFiles() {
public static void DisableSpineAsmdefFiles () {
SetAsmdefFileActive("spine-unity-editor", false);
SetAsmdefFileActive("spine-unity", false);
}
internal static void EnableSpineAsmdefFiles() {
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);
}
}
}
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 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) {
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);
@ -1878,7 +2025,6 @@ namespace Spine.Unity.Editor {
}
}
}
}
public class TextureModificationWarningProcessor : UnityEditor.AssetModificationProcessor
{

View File

@ -27,7 +27,7 @@
* 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 UnityEngine;
using UnityEngine.Playables;

View File

@ -58,7 +58,7 @@ namespace Spine.Unity.Playables {
public override Skeleton Skeleton { get { return skeletonAnimation.Skeleton; } }
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 () {
if (skeletonAnimation == null)
skeletonAnimation = GetComponent<SkeletonAnimation>();

View File

@ -27,7 +27,7 @@
* 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 UnityEngine;
using UnityEngine.Playables;

View File

@ -27,7 +27,7 @@
* 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 UnityEngine;
using UnityEngine.Playables;

View File

@ -29,7 +29,7 @@
#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 UnityEngine;
using UnityEngine.Playables;

View File

@ -27,7 +27,7 @@
* 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.Playables;
using UnityEngine.Timeline;

View File

@ -27,7 +27,7 @@
* 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 UnityEngine;
using UnityEngine.Playables;

View File

@ -27,7 +27,7 @@
* 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 UnityEngine;
using UnityEngine.Playables;

View File

@ -27,7 +27,7 @@
* 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 UnityEngine;
using UnityEngine.Playables;

View File

@ -27,7 +27,7 @@
* 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.Playables;
using UnityEngine.Timeline;