diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs index 87732549c..acad6572a 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs @@ -453,6 +453,9 @@ namespace Spine.Unity.Editor { public static class DataReloadHandler { + + internal static Dictionary savedSkeletonDataAssetAtSKeletonGraphicID = new Dictionary(); + #if NEWPLAYMODECALLBACKS internal static void OnPlaymodeStateChanged (PlayModeStateChange stateChange) { #else @@ -462,6 +465,7 @@ namespace Spine.Unity.Editor { } public static void ReloadAllActiveSkeletonsEditMode () { + if (EditorApplication.isPaused) return; if (EditorApplication.isPlaying) return; if (EditorApplication.isCompiling) return; @@ -475,10 +479,20 @@ namespace Spine.Unity.Editor { if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset); } + // Under some circumstances (e.g. on first import) SkeletonGraphic objects + // have their skeletonGraphic.skeletonDataAsset reference corrupted + // by the instance of the ScriptableObject being destroyed but still assigned. + // Here we save the skeletonGraphic.skeletonDataAsset asset path in order + // to restore it later. var activeSkeletonGraphics = GameObject.FindObjectsOfType(); foreach (var sg in activeSkeletonGraphics) { var skeletonDataAsset = sg.skeletonDataAsset; - if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset); + if (skeletonDataAsset != null) { + var assetPath = AssetDatabase.GetAssetPath(skeletonDataAsset); + var sgID = sg.GetInstanceID(); + savedSkeletonDataAssetAtSKeletonGraphicID[sgID] = assetPath; + skeletonDataAssetsToReload.Add(skeletonDataAsset); + } } foreach (var sda in skeletonDataAssetsToReload) { @@ -780,6 +794,22 @@ namespace Spine.Unity.Editor { #endif } // Any post processing of images + + // Under some circumstances (e.g. on first import) SkeletonGraphic objects + // have their skeletonGraphic.skeletonDataAsset reference corrupted + // by the instance of the ScriptableObject being destroyed but still assigned. + // Here we restore broken skeletonGraphic.skeletonDataAsset references. + var skeletonGraphicObjects = Resources.FindObjectsOfTypeAll(typeof(SkeletonGraphic)) as SkeletonGraphic[]; + foreach (var skeletonGraphic in skeletonGraphicObjects) { + + if (skeletonGraphic.skeletonDataAsset == null) { + var skeletonGraphicID = skeletonGraphic.GetInstanceID(); + if (DataReloadHandler.savedSkeletonDataAssetAtSKeletonGraphicID.ContainsKey(skeletonGraphicID)) { + string assetPath = DataReloadHandler.savedSkeletonDataAssetAtSKeletonGraphicID[skeletonGraphicID]; + skeletonGraphic.skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(assetPath); + } + } + } } static void ReloadSkeletonData (string skeletonJSONPath) { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs index bb666e21f..a195c5463 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs @@ -64,7 +64,7 @@ namespace Spine.Unity { protected override void OnValidate () { // This handles Scene View preview. base.OnValidate (); - if (this.IsValid) { + if (this.IsValid) { if (skeletonDataAsset == null) { Clear(); } else if (skeletonDataAsset.skeletonJSON == null) { @@ -100,12 +100,16 @@ namespace Spine.Unity { } } else { - if (skeletonDataAsset != null) + // Under some circumstances (e.g. sometimes on the first import) OnValidate is called + // before SpineEditorUtilities.ImportSpineContent, causing an unnecessary exception. + // The (skeletonDataAsset.skeletonJSON != null) condition serves to prevent this exception. + if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON != null) Initialize(true); - } + } } protected override void Reset () { + base.Reset(); if (material == null || material.shader != Shader.Find("Spine/SkeletonGraphic (Premultiply Alpha)")) Debug.LogWarning("SkeletonGraphic works best with the SkeletonGraphic material."); @@ -154,8 +158,17 @@ namespace Spine.Unity { } protected override void Awake () { + base.Awake (); if (!this.IsValid) { +#if UNITY_EDITOR + // workaround for special import case of open scene where OnValidate and Awake are + // called in wrong order, before setup of Spine assets. + if (!Application.isPlaying) { + if (this.skeletonDataAsset != null && this.skeletonDataAsset.skeletonJSON == null) + return; + } +#endif Initialize(false); Rebuild(CanvasUpdate.PreRender); } @@ -311,5 +324,5 @@ namespace Spine.Unity { //this.UpdateMaterial(); // TODO: This allocates memory. } #endregion - } + } }