A game about forced loneliness, made by TACStudios
at master 450 lines 18 kB view raw
1using System; 2using System.Linq; 3using System.Collections.Generic; 4using UnityEngine; 5 6namespace UnityEditor.U2D.Sprites 7{ 8 internal class TextureImporterDataProviderFactory : 9 ISpriteDataProviderFactory<Texture2D>, 10 ISpriteDataProviderFactory<Sprite>, 11 ISpriteDataProviderFactory<TextureImporter>, 12 ISpriteDataProviderFactory<GameObject> 13 { 14 public ISpriteEditorDataProvider CreateDataProvider(Texture2D obj) 15 { 16 var ti = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(obj)) as TextureImporter; 17 if (ti != null) 18 return new TextureImporterDataProvider(ti); 19 return null; 20 } 21 22 public ISpriteEditorDataProvider CreateDataProvider(Sprite obj) 23 { 24 var ti = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(obj)) as TextureImporter; 25 if (ti != null) 26 return new TextureImporterDataProvider(ti); 27 return null; 28 } 29 30 public ISpriteEditorDataProvider CreateDataProvider(GameObject obj) 31 { 32 var spriteRenderer = obj.GetComponent<SpriteRenderer>(); 33 if (spriteRenderer != null && spriteRenderer.sprite != null) 34 { 35 var ti = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spriteRenderer.sprite)) as TextureImporter; 36 if (ti != null) 37 return new TextureImporterDataProvider(ti); 38 } 39 return null; 40 } 41 42 public ISpriteEditorDataProvider CreateDataProvider(TextureImporter obj) 43 { 44 return new TextureImporterDataProvider(obj); 45 } 46 47 [SpriteEditorAssetPathProviderAttribute] 48 static string GetAssetPathFromSpriteRenderer(UnityEngine.Object obj) 49 { 50 var go = obj as GameObject; 51 if (go != null) 52 { 53 var spriteRenderer = go.GetComponent<SpriteRenderer>(); 54 if (spriteRenderer != null && spriteRenderer.sprite != null) 55 return AssetDatabase.GetAssetPath(spriteRenderer.sprite); 56 } 57 return null; 58 } 59 60 [SpriteObjectProvider] 61 static Sprite GetSpriteObjectFromSpriteRenderer(UnityEngine.Object obj) 62 { 63 var go = obj as GameObject; 64 if (go != null) 65 { 66 var spriteRenderer = go.GetComponent<SpriteRenderer>(); 67 if (spriteRenderer != null) 68 return spriteRenderer.sprite; 69 } 70 return null; 71 } 72 } 73 74 internal class TextureImporterDataProvider : ISpriteEditorDataProvider, ISpriteNameFileIdDataProvider 75 { 76 TextureImporter m_TextureImporter; 77 SpriteNameFileIdPairExt[] m_NameFileIdPairs; 78 List<SpriteDataExt> m_SpritesMultiple; 79 SpriteDataExt m_SpriteSingle; 80 Dictionary<string, string> m_CustomMetadata; 81 82 SpriteImportMode m_SpriteImportMode = SpriteImportMode.None; 83 SecondarySpriteTexture[] m_SecondaryTextureDataTransfer; 84 SerializedObject m_CachedSerializedObject; 85 86 internal TextureImporterDataProvider(TextureImporter importer) 87 { 88 m_TextureImporter = importer; 89 if (m_TextureImporter != null) 90 { 91 m_SpriteImportMode = m_TextureImporter.spriteImportMode; 92 m_CachedSerializedObject = new SerializedObject(m_TextureImporter); 93 } 94 } 95 96 public Dictionary<string, string> customMetadata => m_CustomMetadata; 97 98 float ISpriteEditorDataProvider.pixelsPerUnit 99 { 100 get { return m_TextureImporter.spritePixelsPerUnit; } 101 } 102 103 UnityEngine.Object ISpriteEditorDataProvider.targetObject 104 { 105 get { return m_TextureImporter; } 106 } 107 108 public SpriteImportMode spriteImportMode 109 { 110 get { return m_SpriteImportMode; } 111 } 112 113 SpriteRect[] ISpriteEditorDataProvider.GetSpriteRects() 114 { 115 return spriteImportMode == SpriteImportMode.Multiple ? m_SpritesMultiple.Select(x => new SpriteDataExt(x) as SpriteRect).ToArray() : new[] { new SpriteDataExt(m_SpriteSingle) }; 116 } 117 118 public SerializedObject GetSerializedObject() 119 { 120 m_CachedSerializedObject?.UpdateIfRequiredOrScript(); 121 return m_CachedSerializedObject; 122 } 123 124 public string assetPath 125 { 126 get { return m_TextureImporter.assetPath; } 127 } 128 129 public void GetWidthAndHeight(ref int width, ref int height) 130 { 131 m_TextureImporter.GetWidthAndHeight(ref width, ref height); 132 } 133 134 void ISpriteEditorDataProvider.SetSpriteRects(SpriteRect[] spriteRects) 135 { 136 if (spriteImportMode != SpriteImportMode.Multiple && spriteImportMode != SpriteImportMode.None && spriteRects.Length == 1) 137 { 138 m_SpriteSingle.CopyFromSpriteRect(spriteRects[0]); 139 } 140 else if (spriteImportMode == SpriteImportMode.Multiple) 141 { 142 Dictionary<GUID, SpriteRect> newSprites = new Dictionary<GUID, SpriteRect>(); 143 foreach (var newSprite in spriteRects) 144 { 145 newSprites.Add(newSprite.spriteID, newSprite); 146 } 147 HashSet<long> internalIdUsed = new HashSet<long>(); 148 for (int i = m_SpritesMultiple.Count - 1; i >= 0; --i) 149 { 150 var spriteID = m_SpritesMultiple[i].spriteID; 151 if (newSprites.TryGetValue(spriteID, out SpriteRect smd)) 152 { 153 m_SpritesMultiple[i].CopyFromSpriteRect(smd); 154 internalIdUsed.Add(m_SpritesMultiple[i].internalID); 155 newSprites.Remove(spriteID); 156 } 157 else 158 { 159 m_SpritesMultiple.RemoveAt(i); 160 } 161 } 162 // Add new ones 163 var nameIdTable = GetSerializedNameFileIdTable(GetSerializedObject()); 164 // First pass map by id 165 var values = newSprites.Values.ToArray(); 166 foreach (var newSprite in values) 167 { 168 var newSpriteRect = new SpriteDataExt(newSprite); 169 var nameIdPair = nameIdTable.FirstOrDefault(x => x.GetFileGUID() == newSprite.spriteID); 170 if (nameIdPair != null && !internalIdUsed.Contains(nameIdPair.internalID)) 171 { 172 newSpriteRect.internalID = nameIdPair.internalID; 173 internalIdUsed.Add(nameIdPair.internalID); 174 m_SpritesMultiple.Add(newSpriteRect); 175 newSprites.Remove(newSprite.spriteID); 176 } 177 } 178 //Second pass map by name 179 foreach (var newSprite in newSprites.Values) 180 { 181 var newSpriteRect = new SpriteDataExt(newSprite); 182 var nameIdPair = nameIdTable.FirstOrDefault(x => x.name == newSprite.name); 183 if (nameIdPair != null && !internalIdUsed.Contains(nameIdPair.internalID)) 184 newSpriteRect.internalID = nameIdPair.internalID; 185 186 internalIdUsed.Add(newSpriteRect.internalID); 187 m_SpritesMultiple.Add(newSpriteRect); 188 } 189 } 190 } 191 192 IEnumerable<SpriteNameFileIdPair> ISpriteNameFileIdDataProvider.GetNameFileIdPairs() 193 { 194 return m_NameFileIdPairs.ToArray<SpriteNameFileIdPair>(); 195 } 196 197 void ISpriteNameFileIdDataProvider.SetNameFileIdPairs(IEnumerable<SpriteNameFileIdPair> pairs) 198 { 199 var newFileIdPair = new SpriteNameFileIdPairExt[pairs.Count()]; 200 var count = 0; 201 foreach (var pair in pairs) 202 { 203 var guid = pair.GetFileGUID(); 204 var internalId = (long)guid.GetHashCode(); 205 //check if guid is in current name id table 206 var idPair = m_NameFileIdPairs.FirstOrDefault(x => x.GetFileGUID() == guid); 207 if (idPair != null) 208 internalId = idPair.internalID; 209 else 210 { 211 // check if guid is in current sprite list 212 var sr = m_SpritesMultiple.FirstOrDefault(x => x.spriteID == guid); 213 if (sr != null) 214 internalId = sr.internalID; 215 } 216 newFileIdPair[count] = new SpriteNameFileIdPairExt(pair.name, guid, internalId); 217 count++; 218 } 219 220 m_NameFileIdPairs = newFileIdPair; 221 } 222 223 internal SpriteRect GetSpriteData(GUID guid) 224 { 225 return spriteImportMode == SpriteImportMode.Multiple ? m_SpritesMultiple.FirstOrDefault(x => x.spriteID == guid) : m_SpriteSingle; 226 } 227 228 internal int GetSpriteDataIndex(GUID guid) 229 { 230 switch (spriteImportMode) 231 { 232 case SpriteImportMode.Single: 233 case SpriteImportMode.Polygon: 234 return 0; 235 case SpriteImportMode.Multiple: 236 { 237 return m_SpritesMultiple.FindIndex(x => x.spriteID == guid); 238 } 239 default: 240 throw new InvalidOperationException(string.Format("Sprite with GUID {0} not found", guid)); 241 } 242 } 243 244 void ISpriteEditorDataProvider.Apply() 245 { 246 var so = GetSerializedObject(); 247 m_SpriteSingle.Apply(so); 248 249 var spriteSheet = so.FindProperty("m_SpriteSheet"); 250 var spriteSheetSprites = spriteSheet.FindPropertyRelative("m_Sprites"); 251 Dictionary<GUID, SpriteDataExt> newSprites = new Dictionary<GUID, SpriteDataExt>(); 252 foreach (var newSprite in m_SpritesMultiple) 253 { 254 newSprites.Add(newSprite.spriteID, newSprite); 255 } 256 257 if (spriteSheetSprites.arraySize > 0) 258 { 259 var validateCurrent = spriteSheetSprites.GetArrayElementAtIndex(0); 260 for (int i = 0; i < spriteSheetSprites.arraySize; ++i) 261 { 262 var guid = SpriteRect.GetSpriteIDFromSerializedProperty(validateCurrent); 263 // find the GUID in our sprite list and apply to it; 264 if (newSprites.TryGetValue(guid, out SpriteDataExt smd)) 265 { 266 smd.Apply(validateCurrent); 267 newSprites.Remove(guid); 268 validateCurrent.Next(false); 269 } 270 else// we can't find it, it is already deleted 271 { 272 spriteSheetSprites.DeleteArrayElementAtIndex(i); 273 --i; 274 } 275 } 276 } 277 278 // Add new ones 279 int newCount = newSprites.Count(); 280 if (newCount > 0) 281 { 282 var idx = spriteSheetSprites.arraySize; 283 spriteSheetSprites.arraySize += newCount; 284 var addCurrent = spriteSheetSprites.GetArrayElementAtIndex(idx); 285 foreach (var newSprite in newSprites.Values) 286 { 287 newSprite.Apply(addCurrent); 288 addCurrent.Next(false); 289 } 290 } 291 292 var noOfPairs = m_NameFileIdPairs.Length; 293 var pairsSo = spriteSheet.FindPropertyRelative("m_NameFileIdTable"); 294 pairsSo.arraySize = noOfPairs; 295 if (noOfPairs > 0) 296 { 297 var element = pairsSo.GetArrayElementAtIndex(0); 298 foreach (var pair in m_NameFileIdPairs) 299 { 300 pair.Apply(element); 301 element.Next(false); 302 } 303 } 304 305 SpriteSecondaryTextureDataTransfer.Apply(so, m_SecondaryTextureDataTransfer); 306 SpriteCustomDataTransfer.Apply(spriteSheet, m_CustomMetadata); 307 308 so.ApplyModifiedPropertiesWithoutUndo(); 309 } 310 311 void ISpriteEditorDataProvider.InitSpriteEditorDataProvider() 312 { 313 var so = GetSerializedObject(); 314 315 var spriteSheet = so.FindProperty("m_SpriteSheet"); 316 var spriteSheetSprites = spriteSheet.FindPropertyRelative("m_Sprites"); 317 m_SpritesMultiple = new List<SpriteDataExt>(); 318 m_SpriteSingle = new SpriteDataExt(so); 319 320 if (spriteSheetSprites.arraySize > 0) 321 { 322 var sp = spriteSheetSprites.GetArrayElementAtIndex(0); 323 for (var i = 0; i < spriteSheetSprites.arraySize; ++i) 324 { 325 var data = new SpriteDataExt(sp); 326 m_SpritesMultiple.Add(data); 327 sp.Next(false); 328 } 329 } 330 331 m_SecondaryTextureDataTransfer = SpriteSecondaryTextureDataTransfer.Load(so); 332 m_CustomMetadata = SpriteCustomDataTransfer.Load(spriteSheet); 333 334 m_NameFileIdPairs = GetSerializedNameFileIdTable(so); 335 } 336 337 SpriteNameFileIdPairExt[] GetSerializedNameFileIdTable(SerializedObject so) 338 { 339 var nameFileIdTableSo = so.FindProperty("m_SpriteSheet.m_NameFileIdTable"); 340 var arraySize = nameFileIdTableSo.arraySize; 341 var nameFileIdPairs = new SpriteNameFileIdPairExt[arraySize]; 342 if (nameFileIdPairs.Length > 0) 343 { 344 var sp = nameFileIdTableSo.GetArrayElementAtIndex(0); 345 for (var i = 0; i < nameFileIdTableSo.arraySize; ++i) 346 { 347 var spriteNameFileId = SpriteNameFileIdPairExt.GetValue(sp); 348 // check if this internal nid is already in one of the sprite. 349 // We don't check name as changing internal id can cause reference to be lost 350 var spriteRect = m_SpritesMultiple.FirstOrDefault(x => x.internalID == spriteNameFileId.internalID); 351 if (spriteRect != null) 352 spriteNameFileId.SetFileGUID(spriteRect.spriteID); 353 nameFileIdPairs[i] = spriteNameFileId; 354 sp.Next(false); 355 } 356 } 357 358 return nameFileIdPairs; 359 } 360 361 T ISpriteEditorDataProvider.GetDataProvider<T>() 362 { 363 if (typeof(T) == typeof(ISpriteBoneDataProvider)) 364 { 365 return new SpriteBoneDataTransfer(this) as T; 366 } 367 if (typeof(T) == typeof(ISpriteMeshDataProvider)) 368 { 369 return new SpriteMeshDataTransfer(this) as T; 370 } 371 if (typeof(T) == typeof(ISpriteOutlineDataProvider)) 372 { 373 return new SpriteOutlineDataTransfer(this) as T; 374 } 375 if (typeof(T) == typeof(ISpritePhysicsOutlineDataProvider)) 376 { 377 return new SpritePhysicsOutlineDataTransfer(this) as T; 378 } 379 if (typeof(T) == typeof(ITextureDataProvider)) 380 { 381 return new SpriteTextureDataTransfer(this) as T; 382 } 383 if (typeof(T) == typeof(ISecondaryTextureDataProvider)) 384 { 385 return new SpriteSecondaryTextureDataTransfer(this) as T; 386 } 387 if (typeof(T) == typeof(ISpriteCustomDataProvider)) 388 { 389 return new SpriteCustomDataTransfer(this) as T; 390 } 391 else 392 return this as T; 393 } 394 395 bool ISpriteEditorDataProvider.HasDataProvider(Type type) 396 { 397 if (type == typeof(ISpriteBoneDataProvider) || 398 type == typeof(ISpriteMeshDataProvider) || 399 type == typeof(ISpriteOutlineDataProvider) || 400 type == typeof(ISpritePhysicsOutlineDataProvider) || 401 type == typeof(ITextureDataProvider) || 402 type == typeof(ISecondaryTextureDataProvider) || 403 type == typeof(ISpriteCustomDataProvider)) 404 { 405 return true; 406 } 407 else 408 return type.IsAssignableFrom(GetType()); 409 } 410 411 public override bool Equals(object a) 412 { 413 return this == (a as TextureImporterDataProvider); 414 } 415 416 public override int GetHashCode() 417 { 418 return base.GetHashCode(); 419 } 420 421 public static bool operator!=(TextureImporterDataProvider t1, TextureImporterDataProvider t2) 422 { 423 return !(t1 == t2); 424 } 425 426 public static bool operator==(TextureImporterDataProvider t1, TextureImporterDataProvider t2) 427 { 428 if (ReferenceEquals(null, t1) && (!ReferenceEquals(null, t2) && t2.m_TextureImporter == null) || 429 ReferenceEquals(null, t2) && (!ReferenceEquals(null, t1) && t1.m_TextureImporter == null)) 430 return true; 431 432 if (!ReferenceEquals(null, t1) && !ReferenceEquals(null, t2)) 433 { 434 if (t1.m_TextureImporter == null && t2.m_TextureImporter == null || 435 t1.m_TextureImporter == t2.m_TextureImporter) 436 return true; 437 } 438 if (ReferenceEquals(t1, t2)) 439 return true; 440 441 return false; 442 } 443 444 public SecondarySpriteTexture[] secondaryTextures 445 { 446 get { return m_SecondaryTextureDataTransfer; } 447 set { m_SecondaryTextureDataTransfer = value; } 448 } 449 } 450}