VoxelChunksObjectChunkExplosionEditor.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. using UnityEngine;
  2. using UnityEngine.Assertions;
  3. using UnityEditor;
  4. using UnityEditorInternal;
  5. using System;
  6. using System.IO;
  7. using System.Collections;
  8. using System.Collections.Generic;
  9. #if UNITY_2018_3_OR_NEWER
  10. using UnityEditor.Experimental.SceneManagement;
  11. #endif
  12. namespace VoxelImporter
  13. {
  14. [CustomEditor(typeof(VoxelChunksObjectChunkExplosion))]
  15. public class VoxelChunksObjectChunkExplosionEditor : EditorCommon
  16. {
  17. public VoxelChunksObjectChunkExplosion explosionObject { get; protected set; }
  18. public VoxelChunksObjectChunkExplosionCore explosionObjectCore { get; protected set; }
  19. public VoxelChunksObjectChunk chunkObject { get; protected set; }
  20. public VoxelChunksObjectChunkCore chunkCore { get; protected set; }
  21. public VoxelChunksObject voxelObject { get; protected set; }
  22. public VoxelChunksObjectExplosion voxelExplosionObject { get; protected set; }
  23. public VoxelChunksObjectExplosionCore voxelExplosionCore { get; protected set; }
  24. #region GuiStyle
  25. private GUIStyle guiStyleMagentaBold;
  26. private GUIStyle guiStyleRedBold;
  27. private GUIStyle guiStyleFoldoutBold;
  28. #endregion
  29. #region Prefab
  30. #if UNITY_2018_3_OR_NEWER
  31. protected PrefabAssetType prefabType { get { return PrefabUtility.GetPrefabAssetType(explosionObject.gameObject); } }
  32. protected bool prefabEnable { get { return prefabType == PrefabAssetType.Regular || isPrefabEditMode; } }
  33. protected bool isPrefab { get { return false; } }
  34. protected bool isPrefabEditMode { get { return PrefabStageUtility.GetCurrentPrefabStage() != null && PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot != null; } }
  35. #else
  36. protected PrefabType prefabType { get { return PrefabUtility.GetPrefabType(explosionObject.gameObject); } }
  37. protected bool prefabEnable { get { var type = prefabType; return type == PrefabType.Prefab || type == PrefabType.PrefabInstance || type == PrefabType.DisconnectedPrefabInstance; } }
  38. protected bool isPrefab { get { return prefabType == PrefabType.Prefab; } }
  39. #endif
  40. #endregion
  41. protected void OnEnable()
  42. {
  43. explosionObject = target as VoxelChunksObjectChunkExplosion;
  44. if (explosionObject == null) return;
  45. explosionObjectCore = new VoxelChunksObjectChunkExplosionCore(explosionObject);
  46. chunkObject = explosionObject.GetComponent<VoxelChunksObjectChunk>();
  47. if (chunkObject == null) return;
  48. chunkCore = new VoxelChunksObjectChunkCore(chunkObject);
  49. if (explosionObject.transform.parent == null) return;
  50. voxelObject = explosionObject.transform.parent.GetComponent<VoxelChunksObject>();
  51. if (voxelObject == null) return;
  52. voxelExplosionObject = voxelObject.GetComponent<VoxelChunksObjectExplosion>();
  53. if (voxelExplosionObject == null) return;
  54. voxelExplosionCore = new VoxelChunksObjectExplosionCore(voxelExplosionObject);
  55. }
  56. protected void OnDisable()
  57. {
  58. if (explosionObject == null || chunkObject == null || voxelObject == null) return;
  59. }
  60. public override void OnInspectorGUI()
  61. {
  62. if (explosionObject == null || chunkObject == null || voxelObject == null)
  63. {
  64. DrawDefaultInspector();
  65. return;
  66. }
  67. #if UNITY_2018_3_OR_NEWER
  68. {
  69. if (prefabType == PrefabAssetType.Regular && !isPrefabEditMode)
  70. {
  71. EditorGUILayout.HelpBox("Prefab can only be edited in Prefab mode.", MessageType.Info);
  72. EditorGUI.BeginDisabledGroup(true);
  73. }
  74. }
  75. #endif
  76. #region GuiStyle
  77. if (guiStyleMagentaBold == null)
  78. guiStyleMagentaBold = new GUIStyle(EditorStyles.boldLabel);
  79. guiStyleMagentaBold.normal.textColor = Color.magenta;
  80. if (guiStyleRedBold == null)
  81. guiStyleRedBold = new GUIStyle(EditorStyles.boldLabel);
  82. guiStyleRedBold.normal.textColor = Color.red;
  83. if (guiStyleFoldoutBold == null)
  84. guiStyleFoldoutBold = new GUIStyle(EditorStyles.foldout);
  85. guiStyleFoldoutBold.fontStyle = FontStyle.Bold;
  86. #endregion
  87. serializedObject.Update();
  88. InspectorGUI();
  89. serializedObject.ApplyModifiedProperties();
  90. #if UNITY_2018_3_OR_NEWER
  91. {
  92. if (prefabType == PrefabAssetType.Regular && !isPrefabEditMode)
  93. {
  94. EditorGUI.EndDisabledGroup();
  95. }
  96. }
  97. #endif
  98. }
  99. protected void InspectorGUI()
  100. {
  101. #region Object
  102. {
  103. explosionObject.edit_objectFoldout = EditorGUILayout.Foldout(explosionObject.edit_objectFoldout, "Object", guiStyleFoldoutBold);
  104. if (explosionObject.edit_objectFoldout)
  105. {
  106. EditorGUILayout.BeginVertical(GUI.skin.box);
  107. #region Mesh
  108. {
  109. #region Title
  110. {
  111. if (explosionObject.meshes == null || explosionObject.meshes.Count == 0)
  112. EditorGUILayout.LabelField("Mesh", guiStyleMagentaBold);
  113. else if (prefabEnable)
  114. {
  115. bool contains = true;
  116. for (int i = 0; i < explosionObject.meshes.Count; i++)
  117. {
  118. if (explosionObject.meshes[i] == null || explosionObject.meshes[i].mesh == null || !AssetDatabase.Contains(explosionObject.meshes[i].mesh))
  119. {
  120. contains = false;
  121. break;
  122. }
  123. }
  124. EditorGUILayout.LabelField("Mesh", contains ? EditorStyles.boldLabel : guiStyleRedBold);
  125. }
  126. else
  127. EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
  128. }
  129. #endregion
  130. EditorGUI.indentLevel++;
  131. #region Mesh
  132. if (explosionObject.meshes != null)
  133. {
  134. for (int i = 0; i < explosionObject.meshes.Count; i++)
  135. {
  136. EditorGUILayout.BeginHorizontal();
  137. {
  138. EditorGUI.BeginDisabledGroup(true);
  139. EditorGUILayout.ObjectField(explosionObject.meshes[i].mesh, typeof(Mesh), false);
  140. EditorGUI.EndDisabledGroup();
  141. }
  142. if (explosionObject.meshes[i].mesh != null)
  143. {
  144. if (!IsMainAsset(explosionObject.meshes[i].mesh))
  145. {
  146. if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
  147. {
  148. #region Create Mesh
  149. string path = EditorUtility.SaveFilePanel("Save mesh", chunkCore.GetDefaultPath(), string.Format("{0}_{1}_explosion_mesh{2}.asset", voxelObject.gameObject.name, chunkObject.chunkName, i), "asset");
  150. if (!string.IsNullOrEmpty(path))
  151. {
  152. if (path.IndexOf(Application.dataPath) < 0)
  153. {
  154. SaveInsideAssetsFolderDisplayDialog();
  155. }
  156. else
  157. {
  158. Undo.RecordObject(explosionObject, "Save Mesh");
  159. path = path.Replace(Application.dataPath, "Assets");
  160. AssetDatabase.CreateAsset(Mesh.Instantiate(explosionObject.meshes[i].mesh), path);
  161. explosionObject.meshes[i].mesh = AssetDatabase.LoadAssetAtPath<Mesh>(path);
  162. voxelExplosionCore.Generate();
  163. }
  164. }
  165. #endregion
  166. }
  167. }
  168. {
  169. if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
  170. {
  171. #region Reset Mesh
  172. Undo.RecordObject(voxelExplosionObject, "Reset Mesh");
  173. Undo.RecordObjects(voxelExplosionObject.chunksExplosion, "Reset Mesh");
  174. explosionObject.meshes[i].mesh = null;
  175. voxelExplosionCore.Generate();
  176. #endregion
  177. }
  178. }
  179. }
  180. EditorGUILayout.EndHorizontal();
  181. }
  182. }
  183. #endregion
  184. EditorGUI.indentLevel--;
  185. }
  186. #endregion
  187. #region Material
  188. if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
  189. {
  190. {
  191. if (explosionObject.materials == null || explosionObject.materials.Count == 0)
  192. EditorGUILayout.LabelField("Material", guiStyleMagentaBold);
  193. else if (prefabEnable)
  194. {
  195. bool contains = true;
  196. for (int i = 0; i < explosionObject.materials.Count; i++)
  197. {
  198. if (!AssetDatabase.Contains(explosionObject.materials[i]))
  199. {
  200. contains = false;
  201. break;
  202. }
  203. }
  204. EditorGUILayout.LabelField("Material", contains ? EditorStyles.boldLabel : guiStyleRedBold);
  205. }
  206. else
  207. EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
  208. }
  209. EditorGUI.indentLevel++;
  210. #region Material
  211. for (int i = 0; i < explosionObject.materials.Count; i++)
  212. {
  213. EditorGUILayout.BeginHorizontal();
  214. {
  215. EditorGUI.BeginDisabledGroup(true);
  216. EditorGUILayout.ObjectField(explosionObject.materials[i], typeof(Material), false);
  217. EditorGUI.EndDisabledGroup();
  218. }
  219. if (explosionObject.materials[i] != null)
  220. {
  221. if (!IsMainAsset(explosionObject.materials[i]))
  222. {
  223. if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
  224. {
  225. #region Create Material
  226. string defaultName = string.Format("{0}_{1}_explosion_mat{2}.mat", voxelObject.gameObject.name, chunkObject.chunkName, i);
  227. string path = EditorUtility.SaveFilePanel("Save material", chunkCore.GetDefaultPath(), defaultName, "mat");
  228. if (!string.IsNullOrEmpty(path))
  229. {
  230. if (path.IndexOf(Application.dataPath) < 0)
  231. {
  232. SaveInsideAssetsFolderDisplayDialog();
  233. }
  234. else
  235. {
  236. Undo.RecordObject(explosionObject, "Save Material");
  237. path = path.Replace(Application.dataPath, "Assets");
  238. AssetDatabase.CreateAsset(Material.Instantiate(explosionObject.materials[i]), path);
  239. explosionObject.materials[i] = AssetDatabase.LoadAssetAtPath<Material>(path);
  240. voxelExplosionCore.Generate();
  241. }
  242. }
  243. #endregion
  244. }
  245. }
  246. {
  247. if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
  248. {
  249. #region Reset Material
  250. Undo.RecordObject(voxelExplosionObject, "Reset Material");
  251. Undo.RecordObjects(voxelExplosionObject.chunksExplosion, "Reset Material");
  252. if (!IsMainAsset(explosionObject.materials[i]))
  253. explosionObject.materials[i] = null;
  254. else
  255. explosionObject.materials[i] = Instantiate<Material>(explosionObject.materials[i]);
  256. voxelExplosionCore.Generate();
  257. #endregion
  258. }
  259. }
  260. }
  261. EditorGUILayout.EndHorizontal();
  262. }
  263. #endregion
  264. EditorGUI.indentLevel--;
  265. }
  266. #endregion
  267. EditorGUILayout.EndVertical();
  268. }
  269. }
  270. #endregion
  271. #region Generate
  272. {
  273. if (GUILayout.Button("Generate"))
  274. {
  275. Undo.RecordObject(voxelExplosionObject, "Generate Voxel Explosion");
  276. Undo.RecordObjects(voxelExplosionObject.chunksExplosion, "Generate Voxel Explosion");
  277. voxelExplosionCore.Generate();
  278. }
  279. }
  280. #endregion
  281. }
  282. }
  283. }