From 04cabf7f3ce3ad5cb86aa009ad637212b0acd138 Mon Sep 17 00:00:00 2001 From: pharan Date: Wed, 15 Feb 2017 13:43:31 +0800 Subject: [PATCH] [unity] Support attachmentless/skinless skeletons. --- .../Editor/SkeletonDataAssetInspector.cs | 90 ++++++++++--------- .../Asset Types/SkeletonDataAsset.cs | 39 ++++---- .../Editor/SkeletonRendererInspector.cs | 5 +- .../Editor/SpineEditorUtilities.cs | 13 ++- 4 files changed, 82 insertions(+), 65 deletions(-) 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 e3af97f98..7b0375b1d 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs @@ -83,24 +83,6 @@ namespace Spine.Unity.Editor { SpineEditorUtilities.ConfirmInitialization(); m_skeletonDataAsset = (SkeletonDataAsset)target; - // Clear empty atlas array items. - { - bool hasNulls = false; - foreach (var a in m_skeletonDataAsset.atlasAssets) { - if (a == null) { - hasNulls = true; - break; - } - } - if (hasNulls) { - var trimmedAtlasAssets = new List(); - foreach (var a in m_skeletonDataAsset.atlasAssets) { - if (a != null) trimmedAtlasAssets.Add(a); - } - m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray(); - } - } - atlasAssets = serializedObject.FindProperty("atlasAssets"); skeletonJSON = serializedObject.FindProperty("skeletonJSON"); scale = serializedObject.FindProperty("scale"); @@ -126,8 +108,8 @@ namespace Spine.Unity.Editor { m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset)); EditorApplication.update += EditorUpdate; - m_skeletonData = m_skeletonDataAsset.GetSkeletonData(false); RepopulateWarnings(); + m_skeletonData = warnings.Count == 0 ? m_skeletonDataAsset.GetSkeletonData(false) : null; } void OnDestroy () { @@ -228,8 +210,9 @@ namespace Spine.Unity.Editor { m_previewUtility.Cleanup(); m_previewUtility = null; } - RepopulateWarnings(); - OnEnable(); + m_skeletonDataAsset.Clear(); + m_skeletonData = null; + OnEnable(); // Should call RepopulateWarnings. return; } } @@ -258,7 +241,6 @@ namespace Spine.Unity.Editor { using (new EditorGUI.DisabledGroupScope(skeletonJSON.objectReferenceValue == null)) { if (GUILayout.Button(new GUIContent("Attempt Reimport", Icons.warning))) { DoReimport(); - return; } } #else @@ -376,15 +358,12 @@ namespace Spine.Unity.Editor { void DoReimport () { SpineEditorUtilities.ImportSpineContent(new string[] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true); - if (m_previewUtility != null) { m_previewUtility.Cleanup(); m_previewUtility = null; } - RepopulateWarnings(); - OnEnable(); - + OnEnable(); // Should call RepopulateWarnings. EditorUtility.SetDirty(m_skeletonDataAsset); } @@ -535,6 +514,25 @@ namespace Spine.Unity.Editor { void RepopulateWarnings () { warnings.Clear(); + // Clear null entries. + { + bool hasNulls = false; + foreach (var a in m_skeletonDataAsset.atlasAssets) { + if (a == null) { + hasNulls = true; + break; + } + } + if (hasNulls) { + var trimmedAtlasAssets = new List(); + foreach (var a in m_skeletonDataAsset.atlasAssets) { + if (a != null) trimmedAtlasAssets.Add(a); + } + m_skeletonDataAsset.atlasAssets = trimmedAtlasAssets.ToArray(); + } + serializedObject.Update(); + } + if (skeletonJSON.objectReferenceValue == null) { warnings.Add("Missing Skeleton JSON"); } else { @@ -544,12 +542,13 @@ namespace Spine.Unity.Editor { #if !SPINE_TK2D bool detectedNullAtlasEntry = false; var atlasList = new List(); - for (int i = 0; i < atlasAssets.arraySize; i++) { - if (atlasAssets.GetArrayElementAtIndex(i).objectReferenceValue == null) { + var actualAtlasAssets = m_skeletonDataAsset.atlasAssets; + for (int i = 0; i < actualAtlasAssets.Length; i++) { + if (m_skeletonDataAsset.atlasAssets[i] == null) { detectedNullAtlasEntry = true; break; } else { - atlasList.Add(((AtlasAsset)atlasAssets.GetArrayElementAtIndex(i).objectReferenceValue).GetAtlas()); + atlasList.Add(actualAtlasAssets[i].GetAtlas()); } } @@ -642,26 +641,37 @@ namespace Spine.Unity.Editor { void CreatePreviewInstances () { this.DestroyPreviewInstances(); + if (warnings.Count > 0) { + m_skeletonDataAsset.Clear(); + return; + } + var skeletonDataAsset = (SkeletonDataAsset)target; if (skeletonDataAsset.GetSkeletonData(false) == null) return; if (this.m_previewInstance == null) { string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", ""); - m_previewInstance = SpineEditorUtilities.InstantiateSkeletonAnimation(skeletonDataAsset, skinName).gameObject; - if (m_previewInstance != null) { - m_previewInstance.hideFlags = HideFlags.HideAndDontSave; - m_previewInstance.layer = 0x1f; - m_skeletonAnimation = m_previewInstance.GetComponent(); - m_skeletonAnimation.initialSkinName = skinName; - m_skeletonAnimation.LateUpdate(); - m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true); - m_previewInstance.GetComponent().enabled = false; - m_initialized = true; + try { + m_previewInstance = SpineEditorUtilities.InstantiateSkeletonAnimation(skeletonDataAsset, skinName).gameObject; + + if (m_previewInstance != null) { + m_previewInstance.hideFlags = HideFlags.HideAndDontSave; + m_previewInstance.layer = 0x1f; + m_skeletonAnimation = m_previewInstance.GetComponent(); + m_skeletonAnimation.initialSkinName = skinName; + m_skeletonAnimation.LateUpdate(); + m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true); + m_previewInstance.GetComponent().enabled = false; + m_initialized = true; + } + + AdjustCameraGoals(true); + } catch { + DestroyPreviewInstances(); } - AdjustCameraGoals(true); } } diff --git a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs b/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs index 8fb9ee307..d995ce854 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs +++ b/spine-unity/Assets/spine-unity/Asset Types/SkeletonDataAsset.cs @@ -89,14 +89,6 @@ namespace Spine.Unity { } public SkeletonData GetSkeletonData (bool quiet) { - if (atlasAssets == null) { - atlasAssets = new AtlasAsset[0]; - if (!quiet) - Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); - Clear(); - return null; - } - if (skeletonJSON == null) { if (!quiet) Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this); @@ -104,17 +96,26 @@ namespace Spine.Unity { return null; } - #if !SPINE_TK2D - if (atlasAssets.Length == 0) { - Clear(); - return null; - } - #else - if (atlasAssets.Length == 0 && spriteCollection == null) { - Clear(); - return null; - } - #endif + // Support attachmentless/skinless SkeletonData. +// if (atlasAssets == null) { +// atlasAssets = new AtlasAsset[0]; +// if (!quiet) +// Debug.LogError("Atlas not set for SkeletonData asset: " + name, this); +// Clear(); +// return null; +// } +// #if !SPINE_TK2D +// if (atlasAssets.Length == 0) { +// Clear(); +// return null; +// } +// #else +// if (atlasAssets.Length == 0 && spriteCollection == null) { +// Clear(); +// return null; +// } +// #endif + if (skeletonData != null) return skeletonData; diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs index c3fe1d03a..c72e03421 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonRendererInspector.cs @@ -214,8 +214,9 @@ namespace Spine.Unity.Editor { if (skinNameString == initialSkinName.stringValue) skinIndex = i; } - skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins); - initialSkinName.stringValue = skins[skinIndex]; + skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins); + if (skins.Length > 0) // Support attachmentless/skinless SkeletonData. + initialSkinName.stringValue = skins[skinIndex]; } } diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index 05333e11e..b8b0b6b32 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -603,7 +603,7 @@ namespace Spine.Unity.Editor { var localAtlases = FindAtlasesAtPath(dir); var requiredPaths = GetRequiredAtlasRegions(sp); var atlasMatch = GetMatchingAtlas(requiredPaths, localAtlases); - if (atlasMatch != null) { + if (atlasMatch != null || requiredPaths.Count == 0) { IngestSpineProject(AssetDatabase.LoadAssetAtPath(sp, typeof(TextAsset)) as TextAsset, atlasMatch); } else { bool resolved = false; @@ -830,6 +830,8 @@ namespace Spine.Unity.Editor { StringReader reader = new StringReader(spineJson.text); var root = Json.Deserialize(reader) as Dictionary; + if (!root.ContainsKey("skins")) + return requiredPaths; foreach (KeyValuePair entry in (Dictionary)root["skins"]) { foreach (KeyValuePair slotEntry in (Dictionary)entry.Value) { @@ -1326,9 +1328,12 @@ namespace Spine.Unity.Editor { throw e; } - skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0]; - newSkeletonAnimation.skeleton.SetSkin(skin); - newSkeletonAnimation.initialSkinName = skin.Name; + bool noSkins = data.DefaultSkin == null && (data.Skins == null || data.Skins.Count == 0); // Support attachmentless/skinless SkeletonData. + skin = skin ?? data.DefaultSkin ?? (noSkins ? null : data.Skins.Items[0]); + if (skin != null) { + newSkeletonAnimation.initialSkinName = skin.Name; + newSkeletonAnimation.skeleton.SetSkin(skin); + } newSkeletonAnimation.skeleton.Update(0); newSkeletonAnimation.state.Update(0);