SGameSpritePackerPolicy.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using UnityEditor.Sprites;
  6. using System.Collections.Generic;
  7. // DefaultPackerPolicy will pack rectangles no matter what Sprite mesh type is unless their packing tag contains "[TIGHT]".
  8. class GameSpritePackerPolicy : UnityEditor.Sprites.IPackerPolicy
  9. {
  10. private static int MAX_SIZE = 1024;
  11. private static int SRPITE_MAX_SIZE = 256;
  12. protected class Entry
  13. {
  14. public Sprite sprite;
  15. public AtlasSettings settings;
  16. public string atlasName;
  17. public SpritePackingMode packingMode;
  18. public int anisoLevel;
  19. }
  20. private const uint kDefaultPaddingPower = 2; // Good for base and two mip levels.
  21. public virtual int GetVersion() { return 1; }
  22. protected virtual string TagPrefix { get { return "[TIGHT]"; } }
  23. protected virtual bool AllowTightWhenTagged { get { return true; } }
  24. public bool AllowSequentialPacking { get { return true; } }
  25. public void OnGroupAtlases(BuildTarget target, PackerJob job, int[] textureImporterInstanceIDs)
  26. {
  27. List<Entry> entries = new List<Entry>();
  28. foreach (int instanceID in textureImporterInstanceIDs)
  29. {
  30. TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID) as TextureImporter;
  31. TextureImporterSettings tis = new TextureImporterSettings();
  32. ti.ReadTextureSettings(tis);
  33. Sprite[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath).Select(x => x as Sprite).Where(x => x != null).ToArray();
  34. foreach (Sprite sprite in sprites)
  35. {
  36. string packTag = ti.spritePackingTag;
  37. string[] split = packTag.Split('_');
  38. int size = MAX_SIZE;
  39. if (split.Length >= 2)
  40. {
  41. int tmp = size;
  42. if (int.TryParse(split[1], out tmp))
  43. {
  44. if (tmp >= 64)
  45. {
  46. size = tmp;
  47. }
  48. }
  49. }
  50. int clrFlag = 0;
  51. if (split.Length >= 3)
  52. {
  53. int tmp = clrFlag;
  54. if (int.TryParse(split[2], out tmp))
  55. {
  56. clrFlag = tmp;
  57. }
  58. }
  59. int forceFlag = 0;
  60. if(split.Length >= 4)
  61. {
  62. int.TryParse(split[3], out forceFlag);
  63. }
  64. if(forceFlag == 0 && (sprite.rect.width > SRPITE_MAX_SIZE || sprite.rect.height > SRPITE_MAX_SIZE))
  65. {
  66. continue;
  67. }
  68. Entry entry = new Entry();
  69. entry.sprite = sprite;
  70. if (clrFlag == 16)
  71. {
  72. #if UNITY_STANDALONE
  73. entry.settings.format = TextureFormat.ARGB4444; //ins.desiredFormat;
  74. #else
  75. entry.settings.format = TextureFormat.RGBA4444; //ins.desiredFormat;
  76. #endif
  77. }else if(clrFlag == 32)
  78. {
  79. entry.settings.format = TextureFormat.ARGB32;
  80. }
  81. else
  82. {
  83. #if UNITY_STANDALONE
  84. entry.settings.format = TextureFormat.DXT5; //ins.desiredFormat;
  85. #elif UNITY_IOS
  86. entry.settings.format = TextureFormat.ASTC_6x6; //ins.desiredFormat;
  87. #elif UNITY_ANDROID
  88. entry.settings.format = TextureFormat.ETC2_RGBA8; //ins.desiredFormat;
  89. #endif
  90. }
  91. //entry.settings.usageMode = ins.usageMode;
  92. entry.settings.colorSpace = ColorSpace.Linear; // ins.colorSpace;
  93. entry.settings.compressionQuality = (int) UnityEditor.TextureCompressionQuality.Normal; //ins.compressionQuality;
  94. entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode), ti.filterMode) ? ti.filterMode : FilterMode.Bilinear;
  95. entry.settings.maxWidth = size;
  96. entry.settings.maxHeight = size;
  97. entry.settings.generateMipMaps = ti.mipmapEnabled;
  98. if (ti.mipmapEnabled)
  99. entry.settings.paddingPower = kDefaultPaddingPower;
  100. string atlasName = ParseAtlasName(ti.spritePackingTag);
  101. atlasName = atlasName.Replace("{FileName}", sprite.name);
  102. entry.atlasName = atlasName;
  103. entry.packingMode = GetPackingMode(ti.spritePackingTag, tis.spriteMeshType);
  104. entry.anisoLevel = ti.anisoLevel;
  105. entries.Add(entry);
  106. }
  107. Resources.UnloadAsset(ti);
  108. }
  109. // First split sprites into groups based on atlas name
  110. var atlasGroups =
  111. from e in entries
  112. group e by e.atlasName;
  113. foreach (var atlasGroup in atlasGroups)
  114. {
  115. int page = 0;
  116. // Then split those groups into smaller groups based on texture settings
  117. var settingsGroups =
  118. from t in atlasGroup
  119. group t by t.settings;
  120. foreach (var settingsGroup in settingsGroups)
  121. {
  122. string atlasName = atlasGroup.Key;
  123. if (settingsGroups.Count() > 1)
  124. atlasName += string.Format(" (Group {0})", page);
  125. AtlasSettings settings = settingsGroup.Key;
  126. settings.anisoLevel = 1;
  127. // Use the highest aniso level from all entries in this atlas
  128. if (settings.generateMipMaps)
  129. foreach (Entry entry in settingsGroup)
  130. if (entry.anisoLevel > settings.anisoLevel)
  131. settings.anisoLevel = entry.anisoLevel;
  132. job.AddAtlas(atlasName, settings);
  133. foreach (Entry entry in settingsGroup)
  134. {
  135. job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode, SpritePackingRotation.None);
  136. }
  137. ++page;
  138. }
  139. }
  140. }
  141. protected bool IsTagPrefixed(string packingTag)
  142. {
  143. packingTag = packingTag.Trim();
  144. if (packingTag.Length < TagPrefix.Length)
  145. return false;
  146. return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);
  147. }
  148. private string ParseAtlasName(string packingTag)
  149. {
  150. string name = packingTag.Trim();
  151. if (IsTagPrefixed(name))
  152. name = name.Substring(TagPrefix.Length).Trim();
  153. return (name.Length == 0) ? "(unnamed)" : name;
  154. }
  155. private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshType meshType)
  156. {
  157. if (meshType == SpriteMeshType.Tight)
  158. if (IsTagPrefixed(packingTag) == AllowTightWhenTagged)
  159. return SpritePackingMode.Tight;
  160. return SpritePackingMode.Rectangle;
  161. }
  162. }