Açıklama Yok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridPaletteBrushes.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEngine;
  6. using UnityEditorInternal;
  7. using Object = UnityEngine.Object;
  8. namespace UnityEditor.Tilemaps
  9. {
  10. internal class GridPaletteBrushes : ScriptableSingleton<GridPaletteBrushes>
  11. {
  12. internal static readonly string s_SessionStateLastUsedBrush = "GridPaletteBrushes.LastUsedBrush";
  13. internal static readonly string s_LibraryPath = "Library/GridBrush";
  14. private static readonly string s_GridBrushExtension = ".asset";
  15. private static bool s_RefreshCache;
  16. [SerializeField] private List<GridBrushBase> m_Brushes;
  17. public static List<GridBrushBase> brushes
  18. {
  19. get
  20. {
  21. if (instance.m_Brushes == null || instance.m_Brushes.Count == 0 || s_RefreshCache)
  22. {
  23. instance.RefreshBrushesCache();
  24. s_RefreshCache = false;
  25. }
  26. return instance.m_Brushes;
  27. }
  28. }
  29. private string[] m_BrushNames;
  30. public static string[] brushNames
  31. {
  32. get
  33. {
  34. return instance.m_BrushNames;
  35. }
  36. }
  37. private string[] m_BrushTooltips;
  38. public static string[] brushTooltips
  39. {
  40. get
  41. {
  42. return instance.m_BrushTooltips;
  43. }
  44. }
  45. private Dictionary<Type, Texture2D> m_BrushIcons;
  46. public static Texture2D GetBrushIcon(Type brushType)
  47. {
  48. Texture2D iconTex;
  49. if (instance.m_BrushIcons != null && instance.m_BrushIcons.TryGetValue(brushType, out iconTex))
  50. {
  51. return iconTex;
  52. }
  53. return Texture2D.redTexture;
  54. }
  55. private void OnDisable()
  56. {
  57. FlushCache();
  58. }
  59. public GridBrushBase GetLastUsedBrush()
  60. {
  61. var sessionIndex = SessionState.GetInt(s_SessionStateLastUsedBrush, -1);
  62. if (sessionIndex >= 0 && brushes.Count > sessionIndex)
  63. return brushes[sessionIndex];
  64. if (sessionIndex == -1)
  65. StoreLastUsedBrush(brushes[0]);
  66. return brushes[0];
  67. }
  68. public void StoreLastUsedBrush(GridBrushBase brush)
  69. {
  70. int index = brushes.IndexOf(brush);
  71. SessionState.SetInt(s_SessionStateLastUsedBrush, index);
  72. }
  73. public static Type GetDefaultBrushType()
  74. {
  75. Type defaultType = typeof(GridBrush);
  76. int count = 0;
  77. foreach (var type in TypeCache.GetTypesWithAttribute<CustomGridBrushAttribute>())
  78. {
  79. var attrs = type.GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
  80. if (attrs != null && attrs.Length > 0)
  81. {
  82. if (attrs[0].defaultBrush)
  83. {
  84. defaultType = type;
  85. count++;
  86. }
  87. }
  88. }
  89. if (count > 1)
  90. {
  91. Debug.LogWarning("Multiple occurrences of defaultBrush == true found. It should only be declared once.");
  92. }
  93. return defaultType;
  94. }
  95. public static void GridBrushAssetChanged(GridBrushBase brush)
  96. {
  97. if (brush == null)
  98. return;
  99. if (IsLibraryBrush(brush))
  100. {
  101. instance.SaveLibraryGridBrushAsset(brush);
  102. }
  103. }
  104. private void RefreshBrushesCache()
  105. {
  106. if (m_Brushes == null)
  107. m_Brushes = new List<GridBrushBase>();
  108. if (m_Brushes.Count == 0 || !(m_Brushes[0] is GridBrush))
  109. {
  110. Type defaultType = GetDefaultBrushType();
  111. GridBrushBase defaultBrush = LoadOrCreateLibraryGridBrushAsset(defaultType);
  112. m_Brushes.Insert(0, defaultBrush);
  113. m_Brushes[0].name = GetBrushDropdownName(m_Brushes[0]);
  114. }
  115. var brushTypes = TypeCache.GetTypesDerivedFrom<GridBrushBase>().Where(t => t != typeof(GridBrush));
  116. foreach (var brushType in brushTypes)
  117. {
  118. if (IsDefaultInstanceVisibleGridBrushType(brushType))
  119. {
  120. var brush = LoadOrCreateLibraryGridBrushAsset(brushType);
  121. if (brush != null)
  122. m_Brushes.Add(brush);
  123. }
  124. }
  125. string[] guids = AssetDatabase.FindAssets("t:GridBrushBase");
  126. foreach (string guid in guids)
  127. {
  128. string path = AssetDatabase.GUIDToAssetPath(guid);
  129. var brush = AssetDatabase.LoadAssetAtPath(path, typeof(GridBrushBase)) as GridBrushBase;
  130. if (brush != null && IsAssetVisibleGridBrushType(brush.GetType()))
  131. m_Brushes.Add(brush);
  132. }
  133. m_BrushNames = new string[m_Brushes.Count];
  134. m_BrushTooltips = new string[m_Brushes.Count];
  135. m_BrushIcons = new Dictionary<Type, Texture2D>();
  136. for (int i = 0; i < m_Brushes.Count; i++)
  137. {
  138. m_BrushNames[i] = m_Brushes[i].name;
  139. var editor = Editor.CreateEditor(m_Brushes[i]) as GridBrushEditorBase;
  140. m_BrushTooltips[i] = editor != null ? editor.tooltip : null;
  141. m_BrushIcons[m_Brushes[i].GetType()] = editor != null ? editor.icon : Texture2D.redTexture;
  142. DestroyImmediate(editor);
  143. }
  144. }
  145. internal static bool IsDefaultInstanceVisibleGridBrushType(Type brushType)
  146. {
  147. CustomGridBrushAttribute[] customBrushes = brushType.GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
  148. if (customBrushes != null && customBrushes.Length > 0)
  149. {
  150. return !customBrushes[0].hideDefaultInstance;
  151. }
  152. return false;
  153. }
  154. private bool IsAssetVisibleGridBrushType(Type brushType)
  155. {
  156. CustomGridBrushAttribute[] customBrushes = brushType.GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
  157. if (customBrushes != null && customBrushes.Length > 0 && GridBrushPickStoreSettingsProvider.GetUserBrushPickStore() == null)
  158. {
  159. return !customBrushes[0].hideAssetInstances;
  160. }
  161. return false;
  162. }
  163. private void SaveLibraryGridBrushAsset(GridBrushBase brush)
  164. {
  165. var gridBrushPath = GenerateGridBrushInstanceLibraryPath(brush.GetType());
  166. string folderPath = Path.GetDirectoryName(gridBrushPath);
  167. if (!Directory.Exists(folderPath))
  168. {
  169. Directory.CreateDirectory(folderPath);
  170. }
  171. InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { brush }, gridBrushPath, EditorSettings.serializationMode != SerializationMode.ForceBinary);
  172. }
  173. private GridBrushBase LoadOrCreateLibraryGridBrushAsset(Type brushType)
  174. {
  175. var serializedObjects = InternalEditorUtility.LoadSerializedFileAndForget(GenerateGridBrushInstanceLibraryPath(brushType));
  176. if (serializedObjects != null && serializedObjects.Length > 0)
  177. {
  178. GridBrushBase brush = serializedObjects[0] as GridBrushBase;
  179. if (brush != null && brush.GetType() == brushType)
  180. return brush;
  181. }
  182. return CreateLibraryGridBrushAsset(brushType);
  183. }
  184. private GridBrushBase CreateLibraryGridBrushAsset(Type brushType)
  185. {
  186. GridBrushBase brush = ScriptableObject.CreateInstance(brushType) as GridBrushBase;
  187. brush.hideFlags = HideFlags.DontSave;
  188. brush.name = GetBrushDropdownName(brush);
  189. SaveLibraryGridBrushAsset(brush);
  190. return brush;
  191. }
  192. private string GenerateGridBrushInstanceLibraryPath(Type brushType)
  193. {
  194. var path = FileUtil.CombinePaths(s_LibraryPath, brushType + s_GridBrushExtension);
  195. path = FileUtil.NiceWinPath(path);
  196. return path;
  197. }
  198. private string GetBrushDropdownName(GridBrushBase brush)
  199. {
  200. // Asset Brushes use the asset name
  201. if (!IsLibraryBrush(brush))
  202. return brush.name;
  203. // Library Brushes
  204. CustomGridBrushAttribute[] customBrushes = brush.GetType().GetCustomAttributes(typeof(CustomGridBrushAttribute), false) as CustomGridBrushAttribute[];
  205. if (customBrushes != null && customBrushes.Length > 0 && customBrushes[0].defaultName.Length > 0)
  206. return customBrushes[0].defaultName;
  207. if (brush.GetType() == typeof(GridBrush))
  208. return "Default Brush";
  209. return brush.GetType().Name;
  210. }
  211. private static bool IsLibraryBrush(GridBrushBase brush)
  212. {
  213. return !AssetDatabase.Contains(brush);
  214. }
  215. // TODO: Better way of clearing caches than AssetPostprocessor
  216. public class AssetProcessor : AssetPostprocessor
  217. {
  218. public override int GetPostprocessOrder()
  219. {
  220. return 1;
  221. }
  222. private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
  223. {
  224. if (!GridPaintingState.savingPalette)
  225. FlushCache();
  226. }
  227. }
  228. internal static void FlushCache()
  229. {
  230. s_RefreshCache = true;
  231. if (instance.m_Brushes != null)
  232. {
  233. foreach (var brush in instance.m_Brushes)
  234. {
  235. if (!EditorUtility.IsPersistent(brush))
  236. DestroyImmediate(brush);
  237. }
  238. instance.m_Brushes.Clear();
  239. GridPaintingState.FlushCache();
  240. }
  241. }
  242. internal static void RefreshCache()
  243. {
  244. if (s_RefreshCache)
  245. {
  246. s_RefreshCache = false;
  247. instance.RefreshBrushesCache();
  248. }
  249. }
  250. }
  251. }