GrassDetailListBox.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using System.Collections.Generic;
  2. using UnityEditor;
  3. using UnityEngine;
  4. namespace MTE
  5. {
  6. internal class GrassDetailListBox : DetailListBox<GrassDetail>
  7. {
  8. public override void NoDetailGUI()
  9. {
  10. EditorGUILayout.LabelField(StringTable.Get(C.Warning_NoGrass));
  11. if (GUILayout.Button(StringTable.Get(C.LoadFromFile)))
  12. {
  13. string path;
  14. if(Utility.OpenFileDialog(StringTable.Get(C.Open), s_assetFileFilter, out path))
  15. {
  16. LoadDetailListFromAFile(path);
  17. }
  18. }
  19. if (GUILayout.Button(StringTable.Get(C.LoadFromGrassLoader)))
  20. {
  21. LoadDetailListFromGrassLoader();
  22. }
  23. }
  24. public override void DrawButtonBackground(int detailIndex, Rect buttonRect)
  25. {
  26. var detail = this.detailList[detailIndex] as GrassDetail;
  27. var rect = buttonRect;
  28. //draw preview texture
  29. if (!MTEStyles.grassPrototypeQuadPreviewTexture || !MTEStyles.grassPrototypeStarPreviewTexture)
  30. {
  31. MTEStyles.InitPreview();
  32. }
  33. var grassType = detail.GrassType;
  34. var grassMeshPreviewTexture = grassType == GrassType.OneQuad
  35. ? MTEStyles.grassPrototypeQuadPreviewTexture
  36. : MTEStyles.grassPrototypeStarPreviewTexture;
  37. rect.min += new Vector2(4,4);
  38. rect.size = new Vector2(64,64);
  39. GUI.DrawTexture(rect, grassMeshPreviewTexture);
  40. //draw texture
  41. var material = detail.Material;
  42. var texture = material.GetTexture("_MainTex");
  43. rect.min += new Vector2(32, 32);
  44. rect.size = new Vector2(32, 32);
  45. GUI.DrawTexture(rect, texture);
  46. }
  47. protected override void SaveDetailList()
  48. {
  49. var path = Res.DetailDir + "SavedGrassDetailList.asset";
  50. var relativePath = Utility.GetUnityPath(path);
  51. GrassDetailList obj = ScriptableObject.CreateInstance<GrassDetailList>();
  52. obj.grassDetailList = (List<GrassDetail>) this.detailList;
  53. AssetDatabase.CreateAsset(obj, relativePath);
  54. AssetDatabase.LoadAssetAtPath<GrassDetailList>(relativePath);
  55. MTEDebug.LogFormat("GrassDetailList saved to {0}", path);
  56. }
  57. protected override C DetailType { get; } = C.Grass;
  58. protected override void AddCallback()
  59. {
  60. GrassEditorUtilityWindow window = ScriptableObject.CreateInstance<GrassEditorUtilityWindow>();
  61. window.titleContent = new GUIContent($"{StringTable.Get(C.Add)} {StringTable.Get(C.Grass)}");
  62. window.detailList = this.detailList;
  63. window.IsAdding = true;
  64. window.OnSave = this.SaveDetailList;
  65. window.ShowUtility();
  66. }
  67. protected override void EditCallback()
  68. {
  69. GrassEditorUtilityWindow window = ScriptableObject.CreateInstance<GrassEditorUtilityWindow>();
  70. window.titleContent = new GUIContent($"{StringTable.Get(C.Edit)} {StringTable.Get(C.Grass)}");
  71. window.detailList = this.detailList;
  72. window.editingIndex = selectedIndex;
  73. window.IsAdding = false;
  74. window.OnSave = this.SaveDetailList;
  75. window.ShowUtility();
  76. }
  77. public void LoadDetailListFromAFile(string path)
  78. {
  79. MTEDebug.LogFormat("Loading grass detail list from <{0}>", path);
  80. var relativePath = Utility.GetUnityPath(path);
  81. var obj = AssetDatabase.LoadAssetAtPath<GrassDetailList>(relativePath);
  82. if (obj != null)
  83. {
  84. this.detailList = obj.grassDetailList;
  85. MTEDebug.LogFormat("Detail list loaded from {0}", path);
  86. if (this.detailList.Count == 0)
  87. {
  88. MTEDebug.Log("No detail found in the detail list.");
  89. }
  90. }
  91. else
  92. {
  93. this.detailList = new List<GrassDetail>();
  94. MTEDebug.LogFormat("No detail list found in {0}.", path);
  95. }
  96. }
  97. public void LoadDetailListFromGrassLoader()
  98. {
  99. MTEDebug.Log("Loading details(three quad) from existing GrassInstanceList on the GrassLoader...");
  100. MTEDebug.Log("The min/max width/height of loaded details will use default values because MTE cannot determine them from the grass instances.");
  101. var grassLoader = MTEContext.TheGrassLoader;
  102. if (grassLoader == null)
  103. {
  104. Debug.LogWarning("No grass loader loaded. Assign it first.");
  105. return;
  106. }
  107. MTEDebug.Log("Remove existing details.");
  108. this.detailList = new List<GrassDetail>();
  109. var instanceList = grassLoader.grassInstanceList;
  110. if (instanceList.grasses != null && instanceList.grasses.Count != 0)
  111. {
  112. MTEDebug.Log("Loading details(three quads) from existing GrassInstanceList...");
  113. foreach (var grassStar in instanceList.grasses)
  114. {
  115. bool found = false;
  116. foreach (var d in this.detailList)
  117. {
  118. var gd = d as GrassDetail;
  119. if (gd.Material == grassStar.Material)
  120. {
  121. found = true;
  122. break;
  123. }
  124. }
  125. if (found)
  126. {
  127. continue;
  128. }
  129. var grassDetail = new GrassDetail
  130. {
  131. Material = grassStar.Material,
  132. MinWidth = GrassDetail.DefaultMinWidth,
  133. MaxWidth = GrassDetail.DefaultMaxWidth,
  134. MinHeight = GrassDetail.DefaultMinHeight,
  135. MaxHeight = GrassDetail.DefaultMaxHeight,
  136. GrassType = GrassType.ThreeQuad
  137. };
  138. this.detailList.Add(grassDetail);
  139. }
  140. MTEDebug.LogFormat("{0} detail(s)(three quads) Loaded.", this.detailList.Count);
  141. }
  142. if (instanceList.quads != null && instanceList.quads.Count != 0)
  143. {
  144. MTEDebug.Log("Loading details(one quad) from existing GrassInstanceList...");
  145. var oldCount = this.detailList.Count;
  146. foreach (var quad in instanceList.quads)
  147. {
  148. bool found = false;
  149. foreach (var detail in this.detailList)
  150. {
  151. if (detail.Material == quad.Material)
  152. {
  153. found = true;
  154. break;
  155. }
  156. }
  157. if (found)
  158. {
  159. continue;
  160. }
  161. var grassDetail = new GrassDetail
  162. {
  163. Material = quad.Material,
  164. MinWidth = GrassDetail.DefaultMinWidth,
  165. MaxWidth = GrassDetail.DefaultMaxWidth,
  166. MinHeight = GrassDetail.DefaultMinHeight,
  167. MaxHeight = GrassDetail.DefaultMaxHeight,
  168. GrassType = GrassType.OneQuad
  169. };
  170. this.detailList.Add(grassDetail);
  171. }
  172. MTEDebug.LogFormat("{0} detail(s)(one quad) Loaded.", this.detailList.Count - oldCount);
  173. }
  174. //save details to default detail list file
  175. SaveDetailList();
  176. GrassPainter.Instance.LoadGrassDetailList();
  177. }
  178. private static readonly string[] s_assetFileFilter = {"detail list", "asset"};
  179. }
  180. }