A game about forced loneliness, made by TACStudios
at master 248 lines 13 kB view raw
1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using UnityEngine; 6using UnityEngine.U2D.Animation; 7using Object = UnityEngine.Object; 8 9namespace UnityEditor.U2D.Animation 10{ 11 internal static class SpriteLibraryUtilitiesEditor 12 { 13 public static void ExportSpriteLibraryToAssetFile(SpriteLibrary spriteLibrary, string savePath) 14 { 15 Debug.Assert(!string.IsNullOrEmpty(savePath) && !string.IsNullOrEmpty(Path.GetFileName(savePath))); 16 17 var serializedObject = new SerializedObject(spriteLibrary); 18 var masterLibraryProperty = serializedObject.FindProperty(SpriteLibraryComponentPropertyString.spriteLibraryAsset); 19 var libraryProperty = serializedObject.FindProperty(SpriteLibraryComponentPropertyString.library); 20 21 var masterLibraryPath = masterLibraryProperty.objectReferenceValue != null ? AssetDatabase.GetAssetPath(masterLibraryProperty.objectReferenceValue) : ""; 22 23 var overrides = new List<SpriteLibCategoryOverride>(); 24 CopySpriteLibraryToOverride(overrides, libraryProperty); 25 var assetToSave = ScriptableObject.CreateInstance<SpriteLibrarySourceAsset>(); 26 assetToSave.SetLibrary(overrides); 27 if (!string.IsNullOrEmpty(masterLibraryPath)) 28 assetToSave.SetPrimaryLibraryGUID(AssetDatabase.AssetPathToGUID(masterLibraryPath)); 29 SpriteLibrarySourceAssetImporter.SaveSpriteLibrarySourceAsset(assetToSave, savePath); 30 Object.DestroyImmediate(assetToSave); 31 32 AssetDatabase.ImportAsset(savePath); 33 var savedAsset = AssetDatabase.LoadAssetAtPath<SpriteLibraryAsset>(savePath); 34 if (savedAsset == null) 35 { 36 Debug.LogError($"Failed to export Sprite Library Asset to {savePath} asset."); 37 return; 38 } 39 40 libraryProperty.ClearArray(); 41 masterLibraryProperty.objectReferenceValue = savedAsset; 42 serializedObject.ApplyModifiedProperties(); 43 serializedObject.Update(); 44 } 45 46 public static void CopySpriteLibraryToOverride(IList<SpriteLibCategoryOverride> destination, SerializedProperty library) 47 { 48 if (destination == null || library == null || library.arraySize == 0) 49 return; 50 51 destination.Clear(); 52 53 var categoryEntries = library.GetArrayElementAtIndex(0); 54 for (var i = 0; i < library.arraySize; ++i) 55 { 56 var overrideCategory = new SpriteLibCategoryOverride() 57 { 58 categoryList = new List<SpriteCategoryEntry>(), 59 entryOverrideCount = 0, 60 fromMain = false, 61 name = categoryEntries.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue, 62 overrideEntries = new List<SpriteCategoryEntryOverride>() 63 }; 64 var entries = categoryEntries.FindPropertyRelative(SpriteLibraryPropertyString.categoryList); 65 var overrideCategoryEntries = overrideCategory.overrideEntries; 66 if (entries.arraySize > 0) 67 { 68 var entry = entries.GetArrayElementAtIndex(0); 69 for (var j = 0; j < entries.arraySize; ++j) 70 { 71 overrideCategoryEntries.Add(new SpriteCategoryEntryOverride() 72 { 73 fromMain = false, 74 name = entry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue, 75 sprite = (Sprite)entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue, 76 spriteOverride = (Sprite)entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue 77 }); 78 entry.Next(false); 79 } 80 } 81 82 destination.Add(overrideCategory); 83 categoryEntries.Next(false); 84 } 85 } 86 87 public static void UpdateLibraryWithNewMainLibrary(SpriteLibraryAsset newMainLibrary, SerializedProperty destLibrary) 88 { 89 var emptyStringArray = Array.Empty<string>(); 90 var newCategories = newMainLibrary != null ? newMainLibrary.GetCategoryNames().ToArray() : emptyStringArray; 91 92 // populate new primary 93 var newCategoryIndex = 0; 94 foreach (var newCategory in newCategories) 95 { 96 SerializedProperty existingCategory = null; 97 if (destLibrary.arraySize > 0) 98 { 99 var cat = destLibrary.GetArrayElementAtIndex(0); 100 for (var i = 0; i < destLibrary.arraySize; ++i) 101 { 102 if (cat.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue == newCategory) 103 { 104 existingCategory = cat; 105 if (i != newCategoryIndex) 106 destLibrary.MoveArrayElement(i, newCategoryIndex); 107 break; 108 } 109 110 cat.Next(false); 111 } 112 } 113 114 if (existingCategory != null) 115 { 116 if (!existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue) 117 existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true; 118 } 119 else 120 { 121 destLibrary.InsertArrayElementAtIndex(newCategoryIndex); 122 existingCategory = destLibrary.GetArrayElementAtIndex(newCategoryIndex); 123 SetPropertyName(existingCategory, newCategory); 124 existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true; 125 existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue = 0; 126 existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries).arraySize = 0; 127 } 128 129 newCategoryIndex++; 130 131 var newEntries = newMainLibrary.GetCategoryLabelNames(newCategory); 132 var entries = existingCategory.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries); 133 var newEntryIndex = 0; 134 foreach (var newEntry in newEntries) 135 { 136 SerializedProperty cacheEntry = null; 137 if (entries.arraySize > 0) 138 { 139 var ent = entries.GetArrayElementAtIndex(0); 140 for (int j = 0; j < entries.arraySize; ++j) 141 { 142 if (ent.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue == newEntry) 143 { 144 cacheEntry = ent; 145 if (j != newEntryIndex) 146 entries.MoveArrayElement(j, newEntryIndex); 147 break; 148 } 149 150 ent.Next(false); 151 } 152 } 153 154 var mainSprite = newMainLibrary.GetSprite(newCategory, newEntry); 155 if (cacheEntry == null) 156 { 157 entries.InsertArrayElementAtIndex(newEntryIndex); 158 cacheEntry = entries.GetArrayElementAtIndex(newEntryIndex); 159 SetPropertyName(cacheEntry, newEntry); 160 cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride) 161 .objectReferenceValue = mainSprite; 162 } 163 164 ++newEntryIndex; 165 if (!cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue) 166 cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain).boolValue = true; 167 if (cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue != mainSprite) 168 cacheEntry.FindPropertyRelative(SpriteLibraryPropertyString.sprite).objectReferenceValue = mainSprite; 169 } 170 } 171 172 // Remove any library or entry that is not in primary and not overridden 173 for (var i = 0; i < destLibrary.arraySize; ++i) 174 { 175 var categoryProperty = destLibrary.GetArrayElementAtIndex(i); 176 var categoryEntriesProperty = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntries); 177 var categoryFromMainProperty = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.fromMain); 178 179 var categoryName = categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue; 180 var categoryInPrimary = newCategories.Contains(categoryName); 181 var entriesInPrimary = categoryInPrimary ? newMainLibrary.GetCategoryLabelNames(categoryName) : emptyStringArray; 182 183 var categoryOverride = 0; 184 for (var j = 0; j < categoryEntriesProperty.arraySize; ++j) 185 { 186 var entry = categoryEntriesProperty.GetArrayElementAtIndex(j); 187 var entryName = entry.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue; 188 var entryInPrimary = entriesInPrimary.Contains(entryName); 189 var entryFromMainProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.fromMain); 190 var overrideSpriteProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.spriteOverride); 191 var spriteProperty = entry.FindPropertyRelative(SpriteLibraryPropertyString.sprite); 192 if (!entryInPrimary) 193 { 194 // Entry no longer in new primary. 195 // Check for override and set it to us 196 if (entryFromMainProperty.boolValue) 197 { 198 if (overrideSpriteProperty.objectReferenceValue == spriteProperty.objectReferenceValue) 199 { 200 categoryEntriesProperty.DeleteArrayElementAtIndex(j); 201 --j; 202 continue; 203 } 204 } 205 206 if (entryFromMainProperty.boolValue) 207 entryFromMainProperty.boolValue = false; 208 if (spriteProperty.objectReferenceValue != overrideSpriteProperty.objectReferenceValue) 209 spriteProperty.objectReferenceValue = overrideSpriteProperty.objectReferenceValue; 210 ++categoryOverride; 211 } 212 else 213 { 214 // Check if sprite has been override 215 if (spriteProperty.objectReferenceValue != overrideSpriteProperty.objectReferenceValue) 216 ++categoryOverride; 217 } 218 } 219 220 if (!categoryInPrimary && categoryEntriesProperty.arraySize == 0 && categoryFromMainProperty.boolValue) 221 { 222 destLibrary.DeleteArrayElementAtIndex(i); 223 --i; 224 continue; 225 } 226 227 // since there is override, and we removed the main. This category now 228 // belows to the library 229 if (!categoryInPrimary) 230 { 231 if (categoryFromMainProperty.boolValue) 232 categoryFromMainProperty.boolValue = false; 233 } 234 else 235 { 236 if (categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue != categoryOverride) 237 categoryProperty.FindPropertyRelative(SpriteLibraryPropertyString.overrideEntryCount).intValue = categoryOverride; 238 } 239 } 240 } 241 242 static void SetPropertyName(SerializedProperty sp, string newName) 243 { 244 sp.FindPropertyRelative(SpriteLibraryPropertyString.name).stringValue = newName; 245 sp.FindPropertyRelative(SpriteLibraryPropertyString.hash).intValue = SpriteLibraryUtility.GetStringHash(newName); 246 } 247 } 248}