From 7d60e4e255847565bc9e70277757cfa779cf0e96 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Sun, 11 Oct 2015 20:26:42 +0200 Subject: [PATCH] improved handling of Reimport All and some other weird asset import cases --- .../AssetDatabaseAvailabilityDetector.cs | 21 +++++++ .../AssetDatabaseAvailabilityDetector.cs.meta | 12 ++++ .../Assets/spine-unity/Editor/Resources.meta | 9 +++ .../Resources/SpriteSharpPersistentMarker.txt | 1 + .../SpriteSharpPersistentMarker.txt.meta | 8 +++ .../Editor/SpineEditorUtilities.cs | 58 +++++++++++++++++-- 6 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs create mode 100644 spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/Resources.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt create mode 100644 spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta diff --git a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs new file mode 100644 index 000000000..5b8c7a4ab --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace Spine { + public static class AssetDatabaseAvailabilityDetector { + const string MARKER_RESOURCE_NAME = "SpineAssetDatabaseMarker"; + private static bool _isMarkerLoaded; + + public static bool IsAssetDatabaseAvailable (bool forceCheck = false) { + if (!forceCheck && _isMarkerLoaded) + return true; + + TextAsset markerTextAsset = Resources.Load(MARKER_RESOURCE_NAME); + _isMarkerLoaded = markerTextAsset != null; + if (markerTextAsset != null) { + Resources.UnloadAsset(markerTextAsset); + } + + return _isMarkerLoaded; + } + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta new file mode 100644 index 000000000..00b99c134 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 25086cd81e3158b439761b73d7366c47 +timeCreated: 1444587791 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor/Resources.meta b/spine-unity/Assets/spine-unity/Editor/Resources.meta new file mode 100644 index 000000000..8d1a705d5 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 24903fdac57ee784b9597fcb751ec22f +folderAsset: yes +timeCreated: 1444565388 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt new file mode 100644 index 000000000..1a3c1a3ea --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt @@ -0,0 +1 @@ +DO NOT MOVE OR DELETE THIS FILE \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta new file mode 100644 index 000000000..7569884b2 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 57281c00bdd90ad4392f811f2b9f0da1 +timeCreated: 1444565392 +licenseType: Pro +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index 36dc47ae3..b2ea647ae 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -149,6 +149,7 @@ public class SpineEditorUtilities : AssetPostprocessor { public static string editorPath = ""; public static string editorGUIPath = ""; + static HashSet assetsImportedInWrongState; static Dictionary skeletonRendererTable; static Dictionary skeletonUtilityBoneTable; static Dictionary boundingBoxFollowerTable; @@ -173,6 +174,7 @@ public class SpineEditorUtilities : AssetPostprocessor { Icons.Initialize(); + assetsImportedInWrongState = new HashSet(); skeletonRendererTable = new Dictionary(); skeletonUtilityBoneTable = new Dictionary(); boundingBoxFollowerTable = new Dictionary(); @@ -254,8 +256,34 @@ public class SpineEditorUtilities : AssetPostprocessor { } static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { - ImportSpineContent(imported, false); + if (imported.Length == 0) + return; + + // In case user used "Assets -> Reimport All", during the import process, + // asset database is not initialized until some point. During that period, + // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath) + // will return null, and as result, assets won't be loaded even if they actually exists, + // which may lead to numerous importing errors. + // This situation also happens if Library folder is deleted from the project, which is a pretty + // common case, since when using version control systems, the Library folder must be excluded. + // + // So to avoid this, in case asset database is not available, we delay loading the assets + // until next time. + // + // Unity *always* reimports some internal assets after the process is done, so this method + // is always called once again in a state when asset database is available. + // + // Checking whether AssetDatabase is initialized is done by attempting to load + // a known "marker" asset that should always be available. Failing to load this asset + // means that AssetDatabase is not initialized. + assetsImportedInWrongState.UnionWith(imported); + if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { + string[] combinedAssets = assetsImportedInWrongState.ToArray(); + assetsImportedInWrongState.Clear(); + ImportSpineContent(combinedAssets); + } } + public static void ImportSpineContent (string[] imported, bool reimport = false) { List atlasPaths = new List(); List imagePaths = new List(); @@ -408,14 +436,34 @@ public class SpineEditorUtilities : AssetPostprocessor { skeletonDataAsset.Reset(); string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset)); - string lastHash = EditorPrefs.GetString(guid + "_hash"); - - if (lastHash != skeletonDataAsset.GetSkeletonData(true).Hash) { + string lastHash = EditorPrefs.GetString(guid + "_hash"); + + // For some weird reason sometimes Unity loses the internal Object pointer, + // and as a result, all comparisons with null returns true. + // But the C# wrapper is still alive, so we can "restore" the object + // by reloading it from its Instance ID. + AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets; + if (skeletonDataAtlasAssets != null) { + for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) { + if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) && + skeletonDataAtlasAssets[i].Equals(null) && + skeletonDataAtlasAssets[i].GetInstanceID() != 0 + ) { + skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset; + } + } + } + + SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); + string currentHash = skeletonData != null ? skeletonData.Hash : null; + if (currentHash == null || lastHash != currentHash) { //do any upkeep on synchronized assets UpdateMecanimClips(skeletonDataAsset); } - EditorPrefs.SetString(guid + "_hash", skeletonDataAsset.GetSkeletonData(true).Hash); + if (currentHash != null) { + EditorPrefs.SetString(guid + "_hash", currentHash); + } } } }