Без опису
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

GridPaletteBrushes.cs 8.5KB

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