VoxelBaseEditor.cs 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119
  1. using UnityEngine;
  2. using UnityEngine.Assertions;
  3. using UnityEditor;
  4. using UnityEditorInternal;
  5. using System;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Collections;
  9. using System.Collections.Generic;
  10. #if UNITY_2018_3_OR_NEWER
  11. using UnityEditor.Experimental.SceneManagement;
  12. #endif
  13. namespace VoxelImporter
  14. {
  15. public abstract class VoxelBaseEditor : EditorCommon
  16. {
  17. public VoxelBase baseTarget { get; protected set; }
  18. public VoxelBaseCore baseCore { get; protected set; }
  19. protected ReorderableList materialList;
  20. protected VoxelEditorCommon editorCommon;
  21. protected bool drawEditorMesh = true;
  22. protected DataTable3<VoxelBase.Face> editVoxelList = new DataTable3<VoxelBase.Face>();
  23. protected VoxelData voxleDataBefore = null;
  24. protected static Rect editorConfigureEditorWindowRect = new Rect(8, 17 + 8, 0, 0);
  25. #region GUIStyle
  26. protected GUIStyle guiStyleMagentaBold;
  27. protected GUIStyle guiStyleRedBold;
  28. protected GUIStyle guiStyleFoldoutBold;
  29. protected GUIStyle guiStyleBoldActiveButton;
  30. protected GUIStyle guiStyleDropDown;
  31. protected GUIStyle guiStyleLabelMiddleLeftItalic;
  32. protected GUIStyle guiStyleTextFieldMiddleLeft;
  33. protected GUIStyle guiStyleEditorWindow;
  34. #endregion
  35. #region strings
  36. public static readonly string[] Edit_ConfigureMaterialMainModeString =
  37. {
  38. VoxelBase.Edit_ConfigureMaterialMainMode.Add.ToString(),
  39. VoxelBase.Edit_ConfigureMaterialMainMode.Remove.ToString(),
  40. };
  41. public static readonly string[] Edit_ConfigureMaterialSubModeString =
  42. {
  43. VoxelBase.Edit_ConfigureMaterialSubMode.Voxel.ToString(),
  44. VoxelBase.Edit_ConfigureMaterialSubMode.Fill.ToString(),
  45. VoxelBase.Edit_ConfigureMaterialSubMode.Rect.ToString(),
  46. };
  47. public static readonly string[] Edit_ConfigureDisableMainModeString =
  48. {
  49. VoxelBase.Edit_ConfigureDisableMainMode.Add.ToString(),
  50. VoxelBase.Edit_ConfigureDisableMainMode.Remove.ToString(),
  51. };
  52. public static readonly string[] Edit_ConfigureDisableSubModeString =
  53. {
  54. VoxelBase.Edit_ConfigureDisableSubMode.Face.ToString(),
  55. VoxelBase.Edit_ConfigureDisableSubMode.Fill.ToString(),
  56. VoxelBase.Edit_ConfigureDisableSubMode.Rect.ToString(),
  57. };
  58. public static readonly string[] Edit_AdvancedModeStrings =
  59. {
  60. "Simple",
  61. "Advanced",
  62. };
  63. #endregion
  64. #region Prefab
  65. #if UNITY_2018_3_OR_NEWER
  66. protected PrefabAssetType prefabType { get { return PrefabUtility.GetPrefabAssetType(baseTarget.gameObject); } }
  67. protected bool prefabEnable { get { return prefabType == PrefabAssetType.Regular || isPrefabEditMode; } }
  68. protected bool isPrefab { get { return false; } }
  69. protected bool isPrefabEditMode { get { return PrefabStageUtility.GetCurrentPrefabStage() != null && PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot != null; } }
  70. #else
  71. protected PrefabType prefabType { get { return PrefabUtility.GetPrefabType(baseTarget.gameObject); } }
  72. protected bool prefabEnable { get { var type = prefabType; return type == PrefabType.Prefab || type == PrefabType.PrefabInstance || type == PrefabType.DisconnectedPrefabInstance; } }
  73. protected bool isPrefab { get { return prefabType == PrefabType.Prefab; } }
  74. #endif
  75. #endregion
  76. protected virtual void OnEnable()
  77. {
  78. baseTarget = target as VoxelBase;
  79. if (baseTarget == null) return;
  80. PrefabUtility.prefabInstanceUpdated -= EditorPrefabInstanceUpdated;
  81. PrefabUtility.prefabInstanceUpdated += EditorPrefabInstanceUpdated;
  82. Undo.undoRedoPerformed -= EditorUndoRedoPerformed;
  83. Undo.undoRedoPerformed += EditorUndoRedoPerformed;
  84. }
  85. protected virtual void OnDisable()
  86. {
  87. if (baseTarget == null) return;
  88. AfterRefresh();
  89. EditEnableMeshDestroy();
  90. baseCore.SetSelectedWireframeHidden(false);
  91. #if !UNITY_2018_3_OR_NEWER
  92. if (isPrefab)
  93. {
  94. baseTarget.voxelData = null;
  95. }
  96. #endif
  97. PrefabUtility.prefabInstanceUpdated -= EditorPrefabInstanceUpdated;
  98. Undo.undoRedoPerformed -= EditorUndoRedoPerformed;
  99. }
  100. protected virtual void OnDestroy()
  101. {
  102. OnDisable();
  103. }
  104. protected virtual void OnEnableInitializeSet()
  105. {
  106. baseCore.Initialize();
  107. editorCommon = new VoxelEditorCommon(baseTarget, baseCore);
  108. UpdateMaterialList();
  109. UpdateConfigureEnableMesh();
  110. }
  111. protected virtual void GUIStyleReady()
  112. {
  113. //Styles
  114. if (guiStyleMagentaBold == null)
  115. guiStyleMagentaBold = new GUIStyle(EditorStyles.boldLabel);
  116. guiStyleMagentaBold.normal.textColor = Color.magenta;
  117. if (guiStyleRedBold == null)
  118. guiStyleRedBold = new GUIStyle(EditorStyles.boldLabel);
  119. guiStyleRedBold.normal.textColor = Color.red;
  120. if (guiStyleFoldoutBold == null)
  121. guiStyleFoldoutBold = new GUIStyle(EditorStyles.foldout);
  122. guiStyleFoldoutBold.fontStyle = FontStyle.Bold;
  123. if (guiStyleBoldActiveButton == null)
  124. guiStyleBoldActiveButton = new GUIStyle(GUI.skin.button);
  125. guiStyleBoldActiveButton.normal = guiStyleBoldActiveButton.active;
  126. if (guiStyleDropDown == null)
  127. guiStyleDropDown = new GUIStyle("DropDown");
  128. guiStyleDropDown.alignment = TextAnchor.MiddleCenter;
  129. if (guiStyleLabelMiddleLeftItalic == null)
  130. guiStyleLabelMiddleLeftItalic = new GUIStyle(EditorStyles.label);
  131. guiStyleLabelMiddleLeftItalic.alignment = TextAnchor.MiddleLeft;
  132. guiStyleLabelMiddleLeftItalic.fontStyle = FontStyle.Italic;
  133. if (guiStyleTextFieldMiddleLeft == null)
  134. guiStyleTextFieldMiddleLeft = new GUIStyle(EditorStyles.textField);
  135. guiStyleTextFieldMiddleLeft.alignment = TextAnchor.MiddleLeft;
  136. if (guiStyleEditorWindow == null)
  137. {
  138. guiStyleEditorWindow = new GUIStyle(EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).window);
  139. }
  140. }
  141. public override void OnInspectorGUI()
  142. {
  143. if (baseTarget == null || editorCommon == null)
  144. {
  145. DrawDefaultInspector();
  146. return;
  147. }
  148. baseCore.AutoSetSelectedWireframeHidden();
  149. serializedObject.Update();
  150. InspectorGUI();
  151. serializedObject.ApplyModifiedProperties();
  152. }
  153. protected virtual void InspectorGUI()
  154. {
  155. #if UNITY_2018_3_OR_NEWER
  156. {
  157. if (prefabType == PrefabAssetType.Regular && !isPrefabEditMode)
  158. {
  159. EditorGUILayout.HelpBox("Prefab can only be edited in Prefab mode.", MessageType.Info);
  160. }
  161. }
  162. #endif
  163. GUIStyleReady();
  164. editorCommon.GUIStyleReady();
  165. if (baseTarget.voxelData != voxleDataBefore)
  166. {
  167. UpdateMaterialList();
  168. voxleDataBefore = baseTarget.voxelData;
  169. }
  170. #region Simple
  171. {
  172. EditorGUI.BeginChangeCheck();
  173. var mode = GUILayout.Toolbar(baseTarget.advancedMode ? 1 : 0, Edit_AdvancedModeStrings);
  174. if (EditorGUI.EndChangeCheck())
  175. {
  176. baseTarget.advancedMode = mode != 0 ? true : false;
  177. }
  178. }
  179. #endregion
  180. }
  181. protected void InspectorGUI_Import()
  182. {
  183. Event e = Event.current;
  184. baseTarget.edit_importFoldout = EditorGUILayout.Foldout(baseTarget.edit_importFoldout, "Import", guiStyleFoldoutBold);
  185. if (baseTarget.edit_importFoldout)
  186. {
  187. EditorGUI.BeginDisabledGroup(isPrefab);
  188. EditorGUILayout.BeginHorizontal(GUI.skin.box);
  189. EditorGUILayout.BeginVertical();
  190. #region Voxel File
  191. {
  192. bool fileExists = baseCore.IsVoxelFileExists();
  193. {
  194. EditorGUILayout.BeginHorizontal();
  195. if (string.IsNullOrEmpty(baseTarget.voxelFilePath))
  196. EditorGUILayout.LabelField("Voxel File", guiStyleMagentaBold);
  197. else if (!fileExists)
  198. EditorGUILayout.LabelField("Voxel File", guiStyleRedBold);
  199. else
  200. EditorGUILayout.LabelField("Voxel File", EditorStyles.boldLabel);
  201. Action<string, UnityEngine.Object> OpenFile = (path, obj) =>
  202. {
  203. if (!baseCore.IsEnableFile(path))
  204. return;
  205. if (obj == null && path.Contains(Application.dataPath))
  206. {
  207. var assetPath = path.Replace(Application.dataPath, "Assets");
  208. obj = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
  209. }
  210. UndoRecordObject("Open Voxel File", true);
  211. baseCore.Reset(path, obj);
  212. baseCore.Create(path, obj);
  213. UpdateMaterialList();
  214. };
  215. var rect = GUILayoutUtility.GetRect(new GUIContent("Open"), guiStyleDropDown, GUILayout.Width(64));
  216. if (GUI.Button(rect, "Open", guiStyleDropDown))
  217. {
  218. InspectorGUI_ImportOpenBefore();
  219. GenericMenu menu = new GenericMenu();
  220. #region vox
  221. menu.AddItem(new GUIContent("MagicaVoxel (*.vox)"), false, () =>
  222. {
  223. var path = EditorUtility.OpenFilePanel("Open MagicaVoxel File", !string.IsNullOrEmpty(baseTarget.voxelFilePath) ? Path.GetDirectoryName(baseTarget.voxelFilePath) : "", "vox");
  224. if (!string.IsNullOrEmpty(path))
  225. {
  226. OpenFile(path, null);
  227. }
  228. });
  229. #endregion
  230. #region qb
  231. menu.AddItem(new GUIContent("Qubicle Binary (*.qb)"), false, () =>
  232. {
  233. var path = EditorUtility.OpenFilePanel("Open Qubicle Binary File", !string.IsNullOrEmpty(baseTarget.voxelFilePath) ? Path.GetDirectoryName(baseTarget.voxelFilePath) : "", "qb");
  234. if (!string.IsNullOrEmpty(path))
  235. {
  236. OpenFile(path, null);
  237. }
  238. });
  239. #endregion
  240. #region png
  241. menu.AddItem(new GUIContent("Pixel Art (*.png)"), false, () =>
  242. {
  243. var path = EditorUtility.OpenFilePanel("Open Pixel Art File", !string.IsNullOrEmpty(baseTarget.voxelFilePath) ? Path.GetDirectoryName(baseTarget.voxelFilePath) : "", "png");
  244. if (!string.IsNullOrEmpty(path))
  245. {
  246. OpenFile(path, null);
  247. }
  248. });
  249. #endregion
  250. menu.ShowAsContext();
  251. }
  252. #region Drag&Drop
  253. {
  254. switch (e.type)
  255. {
  256. case EventType.DragUpdated:
  257. case EventType.DragPerform:
  258. if (!rect.Contains(e.mousePosition)) break;
  259. if (DragAndDrop.paths.Length != 1) break;
  260. DragAndDrop.AcceptDrag();
  261. DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
  262. if (e.type == EventType.DragPerform)
  263. {
  264. string path = DragAndDrop.paths[0];
  265. if (Path.GetPathRoot(path) == "")
  266. path = Application.dataPath + DragAndDrop.paths[0].Remove(0, "Assets".Length);
  267. OpenFile(path, DragAndDrop.objectReferences.Length > 0 ? DragAndDrop.objectReferences[0] : null);
  268. e.Use();
  269. }
  270. break;
  271. }
  272. }
  273. #endregion
  274. EditorGUILayout.EndHorizontal();
  275. }
  276. EditorGUI.indentLevel++;
  277. {
  278. EditorGUILayout.BeginHorizontal();
  279. if (fileExists)
  280. {
  281. if (baseTarget.voxelFileObject == null)
  282. {
  283. EditorGUILayout.LabelField(Path.GetFileName(baseTarget.voxelFilePath));
  284. }
  285. else
  286. {
  287. EditorGUI.BeginChangeCheck();
  288. var obj = EditorGUILayout.ObjectField(baseTarget.voxelFileObject, typeof(UnityEngine.Object), false);
  289. if (EditorGUI.EndChangeCheck())
  290. {
  291. var path = Application.dataPath + AssetDatabase.GetAssetPath(obj).Remove(0, "Assets".Length);
  292. if (baseCore.IsEnableFile(path))
  293. {
  294. UndoRecordObject("Open Voxel File", true);
  295. baseCore.Reset(path, obj);
  296. baseCore.Create(path, obj);
  297. UpdateMaterialList();
  298. }
  299. }
  300. }
  301. if (baseTarget.advancedMode)
  302. {
  303. EditorGUILayout.LabelField(baseTarget.voxelData != null ? "Loaded" : "Unloaded", GUILayout.Width(80));
  304. if (baseTarget.voxelData == null)
  305. {
  306. if (GUILayout.Button("Load", GUILayout.Width(54), GUILayout.Height(16)))
  307. {
  308. baseCore.ReadyVoxelData();
  309. }
  310. }
  311. else
  312. {
  313. if (GUILayout.Button("UnLoad", GUILayout.Width(54), GUILayout.Height(16)))
  314. {
  315. baseTarget.voxelData = null;
  316. }
  317. }
  318. }
  319. }
  320. else
  321. {
  322. EditorGUILayout.HelpBox("Voxel file not found. Please open file.", MessageType.Error);
  323. }
  324. EditorGUILayout.EndHorizontal();
  325. }
  326. EditorGUI.indentLevel--;
  327. }
  328. #endregion
  329. #region Settings
  330. {
  331. EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
  332. EditorGUI.indentLevel++;
  333. {
  334. if (baseTarget.advancedMode)
  335. {
  336. #region LegacyVoxImport
  337. if (baseTarget.fileType == VoxelBase.FileType.vox)
  338. {
  339. EditorGUI.BeginChangeCheck();
  340. var legacyVoxImport = EditorGUILayout.Toggle(new GUIContent("Legacy Vox Import", "Import with legacy behavior up to Version 1.1.2.\nMultiple objects do not correspond.\nIt is deprecated for future use.\nThis is left for compatibility."), baseTarget.legacyVoxImport);
  341. if (EditorGUI.EndChangeCheck())
  342. {
  343. UndoRecordObject("Inspector", true);
  344. baseTarget.legacyVoxImport = legacyVoxImport;
  345. baseCore.ReadyVoxelData(true);
  346. Refresh();
  347. }
  348. }
  349. #endregion
  350. #region Import Mode
  351. {
  352. EditorGUI.BeginChangeCheck();
  353. var importMode = (VoxelObject.ImportMode)EditorGUILayout.EnumPopup("Import Mode", baseTarget.importMode);
  354. if (EditorGUI.EndChangeCheck())
  355. {
  356. UndoRecordObject("Inspector");
  357. baseTarget.importMode = importMode;
  358. Refresh();
  359. }
  360. }
  361. #endregion
  362. #region Import Flag
  363. {
  364. EditorGUI.BeginChangeCheck();
  365. #if UNITY_2017_3_OR_NEWER
  366. var importFlags = (VoxelObject.ImportFlag)EditorGUILayout.EnumFlagsField("Import Flag", baseTarget.importFlags);
  367. #else
  368. var importFlags = (VoxelObject.ImportFlag)EditorGUILayout.EnumMaskField("Import Flag", baseTarget.importFlags);
  369. #endif
  370. if (EditorGUI.EndChangeCheck())
  371. {
  372. UndoRecordObject("Inspector", true);
  373. baseTarget.importFlags = importFlags;
  374. baseCore.ReadyVoxelData(true);
  375. Refresh();
  376. }
  377. }
  378. #endregion
  379. }
  380. #region Import Scale
  381. {
  382. InspectorGUI_ImportSettingsImportScale();
  383. }
  384. #endregion
  385. #region Import Offset
  386. {
  387. EditorGUILayout.BeginHorizontal();
  388. {
  389. InspectorGUI_ImportSettingsImportOffset();
  390. }
  391. {
  392. if (GUILayout.Button("Set", guiStyleDropDown, GUILayout.Width(40), GUILayout.Height(14)))
  393. {
  394. GenericMenu menu = new GenericMenu();
  395. #region Reset
  396. menu.AddItem(new GUIContent("Reset"), false, () =>
  397. {
  398. UndoRecordObject("Inspector", true);
  399. baseTarget.importOffset = Vector3.zero;
  400. Refresh();
  401. });
  402. #endregion
  403. #region Center
  404. menu.AddItem(new GUIContent("Center"), false, () =>
  405. {
  406. UndoRecordObject("Inspector", true);
  407. baseTarget.importOffset = Vector3.zero;
  408. baseTarget.importOffset = -baseCore.GetVoxelsCenter();
  409. Refresh();
  410. });
  411. #endregion
  412. InspectorGUI_ImportOffsetSetExtra(menu);
  413. menu.ShowAsContext();
  414. }
  415. }
  416. EditorGUILayout.EndHorizontal();
  417. }
  418. #endregion
  419. if (baseTarget.advancedMode)
  420. {
  421. InspectorGUI_ConfigureDisable();
  422. }
  423. InspectorGUI_ImportSettingsExtra();
  424. }
  425. EditorGUI.indentLevel--;
  426. }
  427. #endregion
  428. #region Optimize
  429. if (baseTarget.advancedMode)
  430. {
  431. EditorGUILayout.LabelField("Optimize", EditorStyles.boldLabel);
  432. EditorGUI.indentLevel++;
  433. {
  434. #region combineFaces
  435. {
  436. EditorGUI.BeginChangeCheck();
  437. var combineFaces = EditorGUILayout.Toggle("Combine Voxel Faces", baseTarget.combineFaces);
  438. if (EditorGUI.EndChangeCheck())
  439. {
  440. UndoRecordObject("Inspector");
  441. baseTarget.combineFaces = combineFaces;
  442. Refresh();
  443. }
  444. }
  445. #endregion
  446. #region Ignore the cavity
  447. {
  448. EditorGUI.BeginChangeCheck();
  449. var ignoreCavity = EditorGUILayout.Toggle("Ignore Cavity", baseTarget.ignoreCavity);
  450. if (EditorGUI.EndChangeCheck())
  451. {
  452. UndoRecordObject("Inspector");
  453. baseTarget.ignoreCavity = ignoreCavity;
  454. Refresh();
  455. }
  456. }
  457. #endregion
  458. }
  459. EditorGUI.indentLevel--;
  460. }
  461. #endregion
  462. #region Output
  463. if (baseTarget.advancedMode)
  464. {
  465. EditorGUILayout.LabelField("Output", EditorStyles.boldLabel);
  466. EditorGUI.indentLevel++;
  467. {
  468. EditorGUILayout.BeginHorizontal();
  469. EditorGUI.BeginDisabledGroup(true);
  470. EditorGUILayout.ObjectField(new GUIContent("Voxel Structure", "Save the structure information."), baseTarget.voxelStructure, typeof(VoxelStructure), false);
  471. EditorGUI.EndDisabledGroup();
  472. if (baseTarget.voxelStructure == null)
  473. {
  474. if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
  475. {
  476. #region Save
  477. UndoRecordObject("Inspector");
  478. string path = EditorUtility.SaveFilePanel("Save as", baseCore.GetDefaultPath(), string.Format("{0}.asset", Path.GetFileNameWithoutExtension(baseTarget.voxelFilePath)), "asset");
  479. if (!string.IsNullOrEmpty(path))
  480. {
  481. if (path.IndexOf(Application.dataPath) < 0)
  482. {
  483. SaveInsideAssetsFolderDisplayDialog();
  484. }
  485. else
  486. {
  487. path = path.Replace(Application.dataPath, "Assets");
  488. baseTarget.voxelStructure = ScriptableObject.CreateInstance<VoxelStructure>();
  489. baseTarget.voxelStructure.Set(baseCore.voxelData);
  490. AssetDatabase.CreateAsset(baseTarget.voxelStructure, path);
  491. }
  492. }
  493. #endregion
  494. }
  495. }
  496. else
  497. {
  498. if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
  499. {
  500. #region Reset
  501. UndoRecordObject("Inspector");
  502. baseTarget.voxelStructure = null;
  503. #endregion
  504. }
  505. }
  506. EditorGUILayout.EndHorizontal();
  507. }
  508. EditorGUI.indentLevel--;
  509. }
  510. #endregion
  511. EditorGUILayout.EndVertical();
  512. EditorGUILayout.EndHorizontal();
  513. EditorGUI.EndDisabledGroup();
  514. }
  515. }
  516. protected virtual void UndoRecordObject(string text, bool reset = false)
  517. {
  518. if (baseTarget != null)
  519. Undo.RecordObject(baseTarget, text);
  520. }
  521. protected virtual void InspectorGUI_ImportOpenBefore() { }
  522. protected void InspectorGUI_ImportSettingsImportScale()
  523. {
  524. EditorGUILayout.BeginHorizontal();
  525. InspectorGUI_ImportSettingsImportScaleVector();
  526. if (GUILayout.Button("Set", guiStyleDropDown, GUILayout.Width(40), GUILayout.Height(14)))
  527. {
  528. GenericMenu menu = new GenericMenu();
  529. #region Division
  530. {
  531. int[] ScaleTemplate =
  532. {
  533. 1,
  534. 2,
  535. 4,
  536. 8,
  537. 16,
  538. 32,
  539. 64,
  540. 128,
  541. 256,
  542. 512,
  543. 1024,
  544. 2048,
  545. };
  546. foreach (var value in ScaleTemplate)
  547. {
  548. menu.AddItem(new GUIContent(string.Format("Division/{0}", value)), false, () =>
  549. {
  550. var tmp = 1f / (float)value;
  551. InspectorGUI_ImportSettingsImportScale_Set(new Vector3(tmp, tmp, tmp));
  552. });
  553. }
  554. }
  555. #endregion
  556. #region Template
  557. {
  558. float[] ScaleTemplate =
  559. {
  560. 1f,
  561. 0.75f,
  562. 0.5f,
  563. 0.25f,
  564. 0.1f,
  565. 0.075f,
  566. 0.05f,
  567. 0.025f,
  568. 0.001f,
  569. 0.0075f,
  570. 0.005f,
  571. 0.0025f,
  572. 0.0001f,
  573. };
  574. foreach (var value in ScaleTemplate)
  575. {
  576. menu.AddItem(new GUIContent(string.Format("Template/{0}", value)), false, () =>
  577. {
  578. InspectorGUI_ImportSettingsImportScale_Set(new Vector3(value, value, value));
  579. });
  580. }
  581. }
  582. #endregion
  583. menu.AddSeparator("");
  584. #region Default value
  585. {
  586. menu.AddItem(new GUIContent("Default value/Save to default value"), false, () =>
  587. {
  588. EditorPrefs.SetFloat("VoxelImporter_DefaultScaleX", baseTarget.importScale.x);
  589. EditorPrefs.SetFloat("VoxelImporter_DefaultScaleY", baseTarget.importScale.y);
  590. EditorPrefs.SetFloat("VoxelImporter_DefaultScaleZ", baseTarget.importScale.z);
  591. });
  592. menu.AddItem(new GUIContent("Default value/Load from default value"), false, () =>
  593. {
  594. var x = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleX", 1f);
  595. var y = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleY", 1f);
  596. var z = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleZ", 1f);
  597. InspectorGUI_ImportSettingsImportScale_Set(new Vector3(x, y, z));
  598. });
  599. }
  600. #endregion
  601. menu.ShowAsContext();
  602. }
  603. EditorGUILayout.EndHorizontal();
  604. }
  605. protected virtual void InspectorGUI_ImportSettingsImportScaleVector()
  606. {
  607. EditorGUI.BeginChangeCheck();
  608. var importScale = EditorGUILayout.Vector3Field("Import Scale", baseTarget.importScale);
  609. if (EditorGUI.EndChangeCheck())
  610. {
  611. InspectorGUI_ImportSettingsImportScale_Set(importScale);
  612. }
  613. }
  614. protected virtual void InspectorGUI_ImportSettingsImportScale_Set(Vector3 scale)
  615. {
  616. UndoRecordObject("Inspector", true);
  617. baseTarget.importScale = scale;
  618. Refresh();
  619. }
  620. protected virtual void InspectorGUI_ImportSettingsImportOffset()
  621. {
  622. EditorGUI.BeginChangeCheck();
  623. var importOffset = EditorGUILayout.Vector3Field("Import Offset", baseTarget.importOffset);
  624. if (EditorGUI.EndChangeCheck())
  625. {
  626. UndoRecordObject("Inspector", true);
  627. baseTarget.importOffset = importOffset;
  628. Refresh();
  629. }
  630. }
  631. protected virtual void InspectorGUI_ImportSettingsExtra() { }
  632. protected virtual void InspectorGUI_ImportOffsetSetExtra(GenericMenu menu) { }
  633. protected virtual void InspectorGUI_Object_Mesh_Settings()
  634. {
  635. #region Generate Lightmap UVs
  636. {
  637. EditorGUI.BeginChangeCheck();
  638. var generateLightmapUVs = EditorGUILayout.Toggle(new GUIContent("Generate Lightmap UVs", "Generate lightmap UVs into UV2."), baseTarget.generateLightmapUVs);
  639. if (EditorGUI.EndChangeCheck())
  640. {
  641. UndoRecordObject("Inspector");
  642. baseTarget.generateLightmapUVs = generateLightmapUVs;
  643. Refresh();
  644. }
  645. if (baseTarget.generateLightmapUVs)
  646. {
  647. EditorGUI.indentLevel++;
  648. baseTarget.edit_generateLightmapUVsAdvancedFoldout = EditorGUILayout.Foldout(baseTarget.edit_generateLightmapUVsAdvancedFoldout, new GUIContent("Advanced"));
  649. if (baseTarget.edit_generateLightmapUVsAdvancedFoldout)
  650. {
  651. {
  652. EditorGUI.BeginChangeCheck();
  653. var hardAngle = EditorGUILayout.Slider(new GUIContent("Hard Angle", "Angle between neighbor triangles that will generate seam."), baseTarget.generateLightmapUVsHardAngle, 0f, 180f);
  654. if (EditorGUI.EndChangeCheck())
  655. {
  656. UndoRecordObject("Inspector");
  657. baseTarget.generateLightmapUVsHardAngle = Mathf.Round(hardAngle);
  658. Refresh();
  659. }
  660. }
  661. {
  662. EditorGUI.BeginChangeCheck();
  663. var packMargin = EditorGUILayout.Slider(new GUIContent("Pack Margin", "Measured in pixels, assuming mesh will cover an entire 1024x1024 lightmap."), baseTarget.generateLightmapUVsPackMargin, 1f, 64f);
  664. if (EditorGUI.EndChangeCheck())
  665. {
  666. UndoRecordObject("Inspector");
  667. baseTarget.generateLightmapUVsPackMargin = Mathf.Round(packMargin);
  668. Refresh();
  669. }
  670. }
  671. {
  672. EditorGUI.BeginChangeCheck();
  673. var angleError = EditorGUILayout.Slider(new GUIContent("Angle Error", "Measured in percents. Angle error measures deviation of UV angles from geometry angles. Area error measures deviation of UV triangles area from geometry triangles if they were uniformly scaled."),
  674. baseTarget.generateLightmapUVsAngleError, 1f, 75f);
  675. if (EditorGUI.EndChangeCheck())
  676. {
  677. UndoRecordObject("Inspector");
  678. baseTarget.generateLightmapUVsAngleError = Mathf.Round(angleError);
  679. Refresh();
  680. }
  681. }
  682. {
  683. EditorGUI.BeginChangeCheck();
  684. var areaError = EditorGUILayout.Slider(new GUIContent("Area Error"), baseTarget.generateLightmapUVsAreaError, 1f, 75f);
  685. if (EditorGUI.EndChangeCheck())
  686. {
  687. UndoRecordObject("Inspector");
  688. baseTarget.generateLightmapUVsAreaError = Mathf.Round(areaError);
  689. Refresh();
  690. }
  691. }
  692. }
  693. EditorGUI.indentLevel--;
  694. }
  695. }
  696. #endregion
  697. #region Generate Tangents
  698. {
  699. EditorGUI.BeginChangeCheck();
  700. var generateTangents = EditorGUILayout.Toggle(new GUIContent("Generate Tangents", "Generate Tangents."), baseTarget.generateTangents);
  701. if (EditorGUI.EndChangeCheck())
  702. {
  703. UndoRecordObject("Inspector");
  704. baseTarget.generateTangents = generateTangents;
  705. Refresh();
  706. }
  707. }
  708. #endregion
  709. #region meshFaceVertexOffset
  710. {
  711. EditorGUI.BeginChangeCheck();
  712. var value = EditorGUILayout.Slider(new GUIContent("Vertex Offset", "Increase this value if flickering of polygon gaps occurs at low resolution."), baseTarget.meshFaceVertexOffset, 0f, 0.01f);
  713. if (EditorGUI.EndChangeCheck())
  714. {
  715. UndoRecordObject("Inspector");
  716. baseTarget.meshFaceVertexOffset = value;
  717. Refresh();
  718. }
  719. }
  720. #endregion
  721. }
  722. protected virtual void InspectorGUI_Refresh()
  723. {
  724. if (GUILayout.Button("Refresh"))
  725. {
  726. UndoRecordObject("Inspector");
  727. Refresh();
  728. }
  729. }
  730. protected void InspectorGUI_ConfigureDisable()
  731. {
  732. if (baseTarget.disableData != null)
  733. {
  734. EditorGUI.BeginDisabledGroup(isPrefab);
  735. EditorGUILayout.BeginHorizontal();
  736. EditorGUILayout.Space();
  737. if (GUILayout.Button("Configure Disable Face", baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable ? guiStyleBoldActiveButton : GUI.skin.button))
  738. {
  739. UndoRecordObject("Configure Disable Face");
  740. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  741. {
  742. baseTarget.edit_configureMode = VoxelBase.Edit_ConfigureMode.None;
  743. AfterRefresh();
  744. }
  745. else
  746. {
  747. baseTarget.edit_configureMode = VoxelBase.Edit_ConfigureMode.Disable;
  748. UpdateConfigureEnableMesh();
  749. editorConfigureEditorWindowRect.width = editorConfigureEditorWindowRect.height = 0;
  750. }
  751. InternalEditorUtility.RepaintAllViews();
  752. }
  753. EditorGUILayout.Space();
  754. EditorGUILayout.EndHorizontal();
  755. EditorGUI.EndDisabledGroup();
  756. EditorGUILayout.Space();
  757. }
  758. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  759. {
  760. baseTarget.edit_configureMode = VoxelBase.Edit_ConfigureMode.None;
  761. AfterRefresh();
  762. }
  763. }
  764. protected void InspectorGUI_ConfigureMaterial()
  765. {
  766. if (baseTarget.materialData != null && baseTarget.materialData.Count > 1 && !baseTarget.loadFromVoxelFile)
  767. {
  768. EditorGUI.BeginDisabledGroup(isPrefab);
  769. EditorGUILayout.BeginHorizontal();
  770. EditorGUILayout.Space();
  771. if (GUILayout.Button("Configure Material", baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material ? guiStyleBoldActiveButton : GUI.skin.button))
  772. {
  773. UndoRecordObject("Configure Material");
  774. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  775. {
  776. baseTarget.edit_configureMode = VoxelBase.Edit_ConfigureMode.None;
  777. AfterRefresh();
  778. }
  779. else
  780. {
  781. baseTarget.edit_configureMode = VoxelBase.Edit_ConfigureMode.Material;
  782. UpdateConfigureEnableMesh();
  783. editorConfigureEditorWindowRect.width = editorConfigureEditorWindowRect.height = 0;
  784. }
  785. InternalEditorUtility.RepaintAllViews();
  786. }
  787. EditorGUILayout.Space();
  788. EditorGUILayout.EndHorizontal();
  789. EditorGUI.EndDisabledGroup();
  790. EditorGUILayout.Space();
  791. }
  792. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  793. {
  794. baseTarget.edit_configureMode = VoxelBase.Edit_ConfigureMode.None;
  795. AfterRefresh();
  796. }
  797. }
  798. protected virtual void OnSceneGUI()
  799. {
  800. if (baseTarget == null || editorCommon == null) return;
  801. GUIStyleReady();
  802. editorCommon.GUIStyleReady();
  803. Event e = Event.current;
  804. bool repaint = false;
  805. #region Configure Material
  806. if (baseTarget.edit_configureMode != VoxelBase.Edit_ConfigureMode.None)
  807. {
  808. if (SceneView.currentDrawingSceneView == SceneView.lastActiveSceneView)
  809. {
  810. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  811. {
  812. #region Material Editor
  813. if (baseTarget.materialData != null && materialList != null &&
  814. baseTarget.edit_configureMaterialIndex > 0 && baseTarget.edit_configureMaterialIndex < baseTarget.materialData.Count)
  815. {
  816. editorConfigureEditorWindowRect = GUILayout.Window(EditorGUIUtility.GetControlID(FocusType.Passive, editorConfigureEditorWindowRect), editorConfigureEditorWindowRect, (id) =>
  817. {
  818. #region MainMode
  819. {
  820. EditorGUI.BeginChangeCheck();
  821. var edit_configureMaterialMainMode = (VoxelBase.Edit_ConfigureMaterialMainMode)GUILayout.Toolbar((int)baseTarget.edit_configureMaterialMainMode, Edit_ConfigureMaterialMainModeString);
  822. if (EditorGUI.EndChangeCheck())
  823. {
  824. Undo.RecordObject(baseTarget, "Main Mode");
  825. baseTarget.edit_configureMaterialMainMode = edit_configureMaterialMainMode;
  826. ShowNotification();
  827. }
  828. }
  829. #endregion
  830. #region SubMode
  831. {
  832. EditorGUI.BeginChangeCheck();
  833. var edit_configureMaterialSubMode = (VoxelBase.Edit_ConfigureMaterialSubMode)GUILayout.Toolbar((int)baseTarget.edit_configureMaterialSubMode, Edit_ConfigureMaterialSubModeString);
  834. if (EditorGUI.EndChangeCheck())
  835. {
  836. Undo.RecordObject(baseTarget, "Sub Mode");
  837. baseTarget.edit_configureMaterialSubMode = edit_configureMaterialSubMode;
  838. ShowNotification();
  839. }
  840. }
  841. #endregion
  842. #region Transparent
  843. {
  844. EditorGUI.BeginChangeCheck();
  845. var transparent = EditorGUILayout.Toggle("Transparent", baseTarget.materialData[baseTarget.edit_configureMaterialIndex].transparent);
  846. if (EditorGUI.EndChangeCheck())
  847. {
  848. Undo.RecordObject(baseTarget, "Transparent");
  849. baseTarget.materialData[baseTarget.edit_configureMaterialIndex].transparent = transparent;
  850. baseTarget.edit_afterRefresh = true;
  851. }
  852. }
  853. #endregion
  854. #region Clear
  855. {
  856. if (GUILayout.Button("Clear"))
  857. {
  858. Undo.RecordObject(baseTarget, "Clear");
  859. baseTarget.materialData[baseTarget.edit_configureMaterialIndex].ClearMaterial();
  860. UpdateConfigureEnableMesh();
  861. baseTarget.edit_afterRefresh = true;
  862. }
  863. }
  864. #endregion
  865. #region PreviewMode
  866. {
  867. EditorGUI.BeginChangeCheck();
  868. var edit_ConfigurePreviewMode = (VoxelBase.Edit_ConfigurePreviewMode)EditorGUILayout.EnumPopup("Preview", baseTarget.edit_ConfigurePreviewMode);
  869. if (EditorGUI.EndChangeCheck())
  870. {
  871. Undo.RecordObject(baseTarget, "Preview Mode");
  872. baseTarget.edit_ConfigurePreviewMode = edit_ConfigurePreviewMode;
  873. }
  874. }
  875. #endregion
  876. #region Help
  877. if (!baseTarget.edit_helpEnable)
  878. {
  879. #region "?"
  880. {
  881. EditorGUILayout.BeginHorizontal();
  882. EditorGUILayout.Space();
  883. if (GUILayout.Button("?", baseTarget.edit_helpEnable ? editorCommon.guiStyleActiveButton : GUI.skin.button, GUILayout.Width(16)))
  884. {
  885. Undo.RecordObject(baseTarget, "Help Enable");
  886. baseTarget.edit_helpEnable = !baseTarget.edit_helpEnable;
  887. }
  888. EditorGUILayout.EndHorizontal();
  889. }
  890. #endregion
  891. }
  892. else
  893. {
  894. EditorGUI.BeginChangeCheck();
  895. baseTarget.edit_helpEnable = EditorGUILayout.Foldout(baseTarget.edit_helpEnable, "Help");
  896. if (EditorGUI.EndChangeCheck())
  897. {
  898. editorConfigureEditorWindowRect.width = editorConfigureEditorWindowRect.height = 0;
  899. }
  900. EditorGUILayout.BeginVertical(GUI.skin.box);
  901. EditorGUILayout.LabelField("F5 Key - Refresh");
  902. EditorGUILayout.LabelField("Press Space Key - Hide Preview");
  903. EditorGUILayout.EndVertical();
  904. }
  905. #endregion
  906. GUI.DragWindow();
  907. }, "Material Editor", guiStyleEditorWindow);
  908. editorConfigureEditorWindowRect = editorCommon.ResizeSceneViewRect(editorConfigureEditorWindowRect);
  909. }
  910. #endregion
  911. }
  912. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  913. {
  914. #region Disable Editor
  915. if (baseTarget.disableData != null)
  916. {
  917. editorConfigureEditorWindowRect = GUILayout.Window(EditorGUIUtility.GetControlID(FocusType.Passive, editorConfigureEditorWindowRect), editorConfigureEditorWindowRect, (id) =>
  918. {
  919. #region MainMode
  920. {
  921. EditorGUI.BeginChangeCheck();
  922. var edit_configureDisableMainMode = (VoxelBase.Edit_ConfigureDisableMainMode)GUILayout.Toolbar((int)baseTarget.edit_configureDisableMainMode, Edit_ConfigureDisableMainModeString);
  923. if (EditorGUI.EndChangeCheck())
  924. {
  925. Undo.RecordObject(baseTarget, "Main Mode");
  926. baseTarget.edit_configureDisableMainMode = edit_configureDisableMainMode;
  927. ShowNotification();
  928. }
  929. }
  930. #endregion
  931. #region SubMode
  932. {
  933. EditorGUI.BeginChangeCheck();
  934. var edit_configureDisableSubMode = (VoxelBase.Edit_ConfigureDisableSubMode)GUILayout.Toolbar((int)baseTarget.edit_configureDisableSubMode, Edit_ConfigureDisableSubModeString);
  935. if (EditorGUI.EndChangeCheck())
  936. {
  937. Undo.RecordObject(baseTarget, "Sub Mode");
  938. baseTarget.edit_configureDisableSubMode = edit_configureDisableSubMode;
  939. ShowNotification();
  940. }
  941. }
  942. #endregion
  943. #region Set
  944. EditorGUILayout.BeginVertical(GUI.skin.box);
  945. {
  946. #region All
  947. {
  948. EditorGUILayout.BeginHorizontal();
  949. EditorGUILayout.PrefixLabel("All");
  950. if (GUILayout.Button("Add"))
  951. {
  952. Undo.RecordObject(baseTarget, "Add");
  953. foreach (var voxel in baseTarget.voxelData.voxels)
  954. {
  955. var visible = voxel.visible & VoxelBase.FaceAllFlags;
  956. if (visible == 0) continue;
  957. baseTarget.disableData.SetDisable(voxel.position, visible);
  958. }
  959. UpdateConfigureEnableMesh();
  960. baseTarget.edit_afterRefresh = true;
  961. }
  962. if (GUILayout.Button("Remove"))
  963. {
  964. Undo.RecordObject(baseTarget, "Remove");
  965. baseTarget.disableData.ClearDisable();
  966. UpdateConfigureEnableMesh();
  967. baseTarget.edit_afterRefresh = true;
  968. }
  969. EditorGUILayout.EndHorizontal();
  970. }
  971. #endregion
  972. #region Faces
  973. Action<string, VoxelBase.Face> FaceAction = (label, flag) =>
  974. {
  975. EditorGUILayout.BeginHorizontal();
  976. EditorGUILayout.PrefixLabel(label);
  977. if (GUILayout.Button("Add"))
  978. {
  979. Undo.RecordObject(baseTarget, "Add");
  980. foreach (var voxel in baseTarget.voxelData.voxels)
  981. {
  982. var visible = voxel.visible & flag;
  983. if (visible == 0) continue;
  984. var face = baseTarget.disableData.GetDisable(voxel.position);
  985. baseTarget.disableData.SetDisable(voxel.position, face | flag);
  986. }
  987. UpdateConfigureEnableMesh();
  988. baseTarget.edit_afterRefresh = true;
  989. }
  990. if (GUILayout.Button("Remove"))
  991. {
  992. Undo.RecordObject(baseTarget, "Remove");
  993. baseTarget.disableData.AllAction((pos, face) =>
  994. {
  995. baseTarget.disableData.SetDisable(pos, face & ~flag);
  996. });
  997. UpdateConfigureEnableMesh();
  998. baseTarget.edit_afterRefresh = true;
  999. }
  1000. EditorGUILayout.EndHorizontal();
  1001. };
  1002. FaceAction("Right", VoxelBase.Face.right);
  1003. FaceAction("Left", VoxelBase.Face.left);
  1004. FaceAction("Up", VoxelBase.Face.up);
  1005. FaceAction("Down", VoxelBase.Face.down);
  1006. FaceAction("Forward", VoxelBase.Face.forward);
  1007. FaceAction("Back", VoxelBase.Face.back);
  1008. #endregion
  1009. }
  1010. EditorGUILayout.EndVertical();
  1011. #endregion
  1012. #region PreviewMode
  1013. {
  1014. EditorGUI.BeginChangeCheck();
  1015. var edit_ConfigurePreviewMode = (VoxelBase.Edit_ConfigurePreviewMode)EditorGUILayout.EnumPopup("Preview", baseTarget.edit_ConfigurePreviewMode);
  1016. if (EditorGUI.EndChangeCheck())
  1017. {
  1018. Undo.RecordObject(baseTarget, "Preview Mode");
  1019. baseTarget.edit_ConfigurePreviewMode = edit_ConfigurePreviewMode;
  1020. }
  1021. }
  1022. #endregion
  1023. #region Help
  1024. if (!baseTarget.edit_helpEnable)
  1025. {
  1026. #region "?"
  1027. {
  1028. EditorGUILayout.BeginHorizontal();
  1029. EditorGUILayout.Space();
  1030. if (GUILayout.Button("?", baseTarget.edit_helpEnable ? editorCommon.guiStyleActiveButton : GUI.skin.button, GUILayout.Width(16)))
  1031. {
  1032. Undo.RecordObject(baseTarget, "Help Enable");
  1033. baseTarget.edit_helpEnable = !baseTarget.edit_helpEnable;
  1034. }
  1035. EditorGUILayout.EndHorizontal();
  1036. }
  1037. #endregion
  1038. }
  1039. else
  1040. {
  1041. EditorGUI.BeginChangeCheck();
  1042. baseTarget.edit_helpEnable = EditorGUILayout.Foldout(baseTarget.edit_helpEnable, "Help");
  1043. if (EditorGUI.EndChangeCheck())
  1044. {
  1045. editorConfigureEditorWindowRect.width = editorConfigureEditorWindowRect.height = 0;
  1046. }
  1047. EditorGUILayout.BeginVertical(GUI.skin.box);
  1048. EditorGUILayout.LabelField("F5 Key - Refresh");
  1049. EditorGUILayout.LabelField("Press Space Key - Hide Preview");
  1050. EditorGUILayout.EndVertical();
  1051. }
  1052. #endregion
  1053. GUI.DragWindow();
  1054. }, "Disable Face Editor", guiStyleEditorWindow);
  1055. editorConfigureEditorWindowRect = editorCommon.ResizeSceneViewRect(editorConfigureEditorWindowRect);
  1056. }
  1057. #endregion
  1058. }
  1059. }
  1060. #region Event
  1061. {
  1062. var controlID = GUIUtility.GetControlID(FocusType.Passive);
  1063. Tools.current = Tool.None;
  1064. switch (e.type)
  1065. {
  1066. case EventType.MouseMove:
  1067. editVoxelList.Clear();
  1068. editorCommon.selectionRect.Reset();
  1069. editorCommon.ClearPreviewMesh();
  1070. UpdateCursorMesh();
  1071. break;
  1072. case EventType.MouseDown:
  1073. if (editorCommon.CheckMousePositionEditorRects())
  1074. {
  1075. if (!e.alt && e.button == 0)
  1076. {
  1077. editorCommon.ClearCursorMesh();
  1078. EventMouseDrag(true);
  1079. }
  1080. else if (!e.alt && e.button == 1)
  1081. {
  1082. ClearMakeAddData();
  1083. }
  1084. }
  1085. break;
  1086. case EventType.MouseDrag:
  1087. {
  1088. if (!e.alt && e.button == 0)
  1089. {
  1090. EventMouseDrag(false);
  1091. }
  1092. }
  1093. break;
  1094. case EventType.MouseUp:
  1095. if (!e.alt && e.button == 0)
  1096. {
  1097. EventMouseApply();
  1098. }
  1099. ClearMakeAddData();
  1100. UpdateCursorMesh();
  1101. repaint = true;
  1102. break;
  1103. case EventType.Layout:
  1104. HandleUtility.AddDefaultControl(controlID);
  1105. break;
  1106. }
  1107. switch (e.type)
  1108. {
  1109. case EventType.KeyDown:
  1110. if (!e.alt)
  1111. {
  1112. if (e.keyCode == KeyCode.F5)
  1113. {
  1114. Refresh();
  1115. }
  1116. else if (e.keyCode == KeyCode.Space)
  1117. {
  1118. drawEditorMesh = false;
  1119. }
  1120. }
  1121. break;
  1122. case EventType.KeyUp:
  1123. {
  1124. if (e.keyCode == KeyCode.Space)
  1125. {
  1126. drawEditorMesh = true;
  1127. }
  1128. }
  1129. break;
  1130. }
  1131. }
  1132. #endregion
  1133. if (drawEditorMesh)
  1134. {
  1135. #region SilhouetteMesh
  1136. if (editorCommon.silhouetteMesh != null)
  1137. {
  1138. for (int i = 0; i < editorCommon.silhouetteMesh.Length; i++)
  1139. {
  1140. if (editorCommon.silhouetteMesh[i] == null) continue;
  1141. editorCommon.unlitColorMaterial.color = new Color(0, 0, 0, 1f);
  1142. editorCommon.unlitColorMaterial.SetPass(0);
  1143. Graphics.DrawMeshNow(editorCommon.silhouetteMesh[i], baseTarget.transform.localToWorldMatrix);
  1144. }
  1145. }
  1146. #endregion
  1147. #region EnableMesh
  1148. if (baseTarget.edit_enableMesh != null)
  1149. {
  1150. for (int i = 0; i < baseTarget.edit_enableMesh.Length; i++)
  1151. {
  1152. if (baseTarget.edit_enableMesh[i] == null) continue;
  1153. if (baseTarget.edit_ConfigurePreviewMode == VoxelBase.Edit_ConfigurePreviewMode.Transparent)
  1154. {
  1155. editorCommon.vertexColorTransparentMaterial.color = new Color(1, 0, 0, 0.75f);
  1156. editorCommon.vertexColorTransparentMaterial.SetPass(0);
  1157. }
  1158. else
  1159. {
  1160. editorCommon.vertexColorMaterial.color = new Color(1, 0, 0, 1);
  1161. editorCommon.vertexColorMaterial.SetPass(0);
  1162. }
  1163. Graphics.DrawMeshNow(baseTarget.edit_enableMesh[i], baseTarget.transform.localToWorldMatrix);
  1164. }
  1165. }
  1166. #endregion
  1167. }
  1168. if (SceneView.currentDrawingSceneView == SceneView.lastActiveSceneView)
  1169. {
  1170. #region Preview Mesh
  1171. if (editorCommon.previewMesh != null)
  1172. {
  1173. Color color = Color.white;
  1174. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1175. {
  1176. if (baseTarget.edit_configureMaterialMainMode == VoxelBase.Edit_ConfigureMaterialMainMode.Add)
  1177. color = new Color(1, 0, 0, 1);
  1178. else if (baseTarget.edit_configureMaterialMainMode == VoxelBase.Edit_ConfigureMaterialMainMode.Remove)
  1179. color = new Color(0, 0, 1, 1);
  1180. }
  1181. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1182. {
  1183. if (baseTarget.edit_configureDisableMainMode == VoxelBase.Edit_ConfigureDisableMainMode.Add)
  1184. color = new Color(1, 0, 0, 1);
  1185. else if (baseTarget.edit_configureDisableMainMode == VoxelBase.Edit_ConfigureDisableMainMode.Remove)
  1186. color = new Color(0, 0, 1, 1);
  1187. }
  1188. else
  1189. {
  1190. Assert.IsTrue(false);
  1191. }
  1192. color.a = 0.5f + 0.5f * (1f - editorCommon.AnimationPower);
  1193. for (int i = 0; i < editorCommon.previewMesh.Length; i++)
  1194. {
  1195. if (editorCommon.previewMesh[i] == null) continue;
  1196. editorCommon.vertexColorTransparentMaterial.color = color;
  1197. editorCommon.vertexColorTransparentMaterial.SetPass(0);
  1198. Graphics.DrawMeshNow(editorCommon.previewMesh[i], baseTarget.transform.localToWorldMatrix);
  1199. }
  1200. repaint = true;
  1201. }
  1202. #endregion
  1203. #region CursorMesh
  1204. {
  1205. float color = 0.2f + 0.4f * (1f - editorCommon.AnimationPower);
  1206. if (editorCommon.cursorMesh != null)
  1207. {
  1208. for (int i = 0; i < editorCommon.cursorMesh.Length; i++)
  1209. {
  1210. if (editorCommon.cursorMesh[i] == null) continue;
  1211. editorCommon.vertexColorTransparentMaterial.color = new Color(1, 1, 1, color);
  1212. editorCommon.vertexColorTransparentMaterial.SetPass(0);
  1213. Graphics.DrawMeshNow(editorCommon.cursorMesh[i], baseTarget.transform.localToWorldMatrix);
  1214. }
  1215. }
  1216. repaint = true;
  1217. }
  1218. #endregion
  1219. #region Selection Rect
  1220. if (editorCommon.selectionRect.Enable)
  1221. {
  1222. bool enable = false;
  1223. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1224. {
  1225. if (baseTarget.edit_configureMaterialSubMode == VoxelBase.Edit_ConfigureMaterialSubMode.Rect)
  1226. enable = true;
  1227. }
  1228. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1229. {
  1230. if (baseTarget.edit_configureDisableSubMode == VoxelBase.Edit_ConfigureDisableSubMode.Rect)
  1231. enable = true;
  1232. }
  1233. else
  1234. {
  1235. Assert.IsTrue(false);
  1236. }
  1237. if (enable)
  1238. {
  1239. Handles.BeginGUI();
  1240. GUI.Box(editorCommon.selectionRect.rect, "", "SelectionRect");
  1241. Handles.EndGUI();
  1242. repaint = true;
  1243. }
  1244. }
  1245. #endregion
  1246. }
  1247. }
  1248. #endregion
  1249. if (repaint)
  1250. {
  1251. SceneView.currentDrawingSceneView.Repaint();
  1252. }
  1253. }
  1254. protected void UpdateSilhouetteMeshMesh()
  1255. {
  1256. editorCommon.ClearSilhouetteMeshMesh();
  1257. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material ||
  1258. baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1259. {
  1260. List<VoxelData.Voxel> voxels = new List<VoxelData.Voxel>(baseCore.voxelData.voxels.Length);
  1261. for (int i = 0; i < baseCore.voxelData.voxels.Length; i++)
  1262. {
  1263. var voxel = baseCore.voxelData.voxels[i];
  1264. voxel.palette = -1;
  1265. voxels.Add(voxel);
  1266. }
  1267. if (voxels.Count > 0)
  1268. {
  1269. editorCommon.silhouetteMesh = baseCore.Edit_CreateMesh(voxels, null, true);
  1270. }
  1271. }
  1272. }
  1273. protected void UpdatePreviewMesh()
  1274. {
  1275. editorCommon.ClearPreviewMesh();
  1276. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1277. {
  1278. if (baseTarget.edit_configureMaterialIndex > 0 && baseTarget.edit_configureMaterialIndex < baseTarget.materialData.Count)
  1279. {
  1280. List<VoxelData.Voxel> voxels = new List<VoxelData.Voxel>();
  1281. editVoxelList.AllAction((x, y, z, face) =>
  1282. {
  1283. var index = baseCore.voxelData.VoxelTableContains(x, y, z);
  1284. if (index < 0) return;
  1285. var voxel = baseCore.voxelData.voxels[index];
  1286. voxel.palette = -1;
  1287. voxels.Add(voxel);
  1288. });
  1289. if (voxels.Count > 0)
  1290. {
  1291. editorCommon.previewMesh = baseCore.Edit_CreateMesh(voxels, null, false);
  1292. }
  1293. }
  1294. }
  1295. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1296. {
  1297. List<VoxelData.Voxel> voxels = new List<VoxelData.Voxel>();
  1298. editVoxelList.AllAction((x, y, z, face) =>
  1299. {
  1300. var index = baseCore.voxelData.VoxelTableContains(x, y, z);
  1301. if (index < 0) return;
  1302. var voxel = baseCore.voxelData.voxels[index];
  1303. voxel.palette = -1;
  1304. voxel.visible = face;
  1305. voxels.Add(voxel);
  1306. });
  1307. if (voxels.Count > 0)
  1308. {
  1309. editorCommon.previewMesh = baseCore.Edit_CreateMesh(voxels, null, false);
  1310. }
  1311. }
  1312. }
  1313. protected void UpdateCursorMesh()
  1314. {
  1315. editorCommon.ClearCursorMesh();
  1316. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1317. {
  1318. if (baseTarget.edit_configureMaterialIndex > 0 && baseTarget.edit_configureMaterialIndex < baseTarget.materialData.Count)
  1319. {
  1320. switch (baseTarget.edit_configureMaterialSubMode)
  1321. {
  1322. case VoxelBase.Edit_ConfigureMaterialSubMode.Voxel:
  1323. {
  1324. var result = editorCommon.GetMousePositionVoxel();
  1325. if (result.HasValue)
  1326. {
  1327. editorCommon.cursorMesh = baseCore.Edit_CreateMesh(new List<VoxelData.Voxel>() { new VoxelData.Voxel(result.Value.x, result.Value.y, result.Value.z, -1) });
  1328. }
  1329. }
  1330. break;
  1331. case VoxelBase.Edit_ConfigureMaterialSubMode.Fill:
  1332. {
  1333. var pos = editorCommon.GetMousePositionVoxel();
  1334. if (pos.HasValue)
  1335. {
  1336. var faceAreaTable = editorCommon.GetFillVoxelFaceAreaTable(pos.Value);
  1337. if (faceAreaTable != null)
  1338. editorCommon.cursorMesh = new Mesh[1] { baseCore.Edit_CreateMeshOnly_Mesh(faceAreaTable, null, null) };
  1339. }
  1340. }
  1341. break;
  1342. }
  1343. }
  1344. }
  1345. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1346. {
  1347. switch (baseTarget.edit_configureDisableSubMode)
  1348. {
  1349. case VoxelBase.Edit_ConfigureDisableSubMode.Face:
  1350. {
  1351. IntVector3 pos;
  1352. VoxelBase.Face face;
  1353. if (editorCommon.GetMousePositionVoxelFace(out pos, out face))
  1354. {
  1355. editorCommon.cursorMesh = baseCore.Edit_CreateMesh(new List<VoxelData.Voxel>() { new VoxelData.Voxel(pos.x, pos.y, pos.z, -1, face) });
  1356. }
  1357. }
  1358. break;
  1359. case VoxelBase.Edit_ConfigureDisableSubMode.Fill:
  1360. {
  1361. IntVector3 pos;
  1362. VoxelBase.Face face;
  1363. if (editorCommon.GetMousePositionVoxelFace(out pos, out face))
  1364. {
  1365. var faceAreaTable = editorCommon.GetFillVoxelFaceFaceAreaTable(pos, face);
  1366. if (faceAreaTable != null)
  1367. editorCommon.cursorMesh = new Mesh[1] { baseCore.Edit_CreateMeshOnly_Mesh(faceAreaTable, null, null) };
  1368. }
  1369. }
  1370. break;
  1371. }
  1372. }
  1373. }
  1374. protected void ClearMakeAddData()
  1375. {
  1376. editVoxelList.Clear();
  1377. editorCommon.selectionRect.Reset();
  1378. editorCommon.ClearPreviewMesh();
  1379. editorCommon.ClearCursorMesh();
  1380. }
  1381. private void EventMouseDrag(bool first)
  1382. {
  1383. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1384. {
  1385. UpdateCursorMesh();
  1386. switch (baseTarget.edit_configureMaterialSubMode)
  1387. {
  1388. case VoxelBase.Edit_ConfigureMaterialSubMode.Voxel:
  1389. {
  1390. var result = editorCommon.GetMousePositionVoxel();
  1391. if (result.HasValue)
  1392. {
  1393. editVoxelList.Set(result.Value, VoxelBase.FaceAllFlags);
  1394. UpdatePreviewMesh();
  1395. }
  1396. }
  1397. break;
  1398. case VoxelBase.Edit_ConfigureMaterialSubMode.Fill:
  1399. {
  1400. var pos = editorCommon.GetMousePositionVoxel();
  1401. if (pos.HasValue)
  1402. {
  1403. var result = editorCommon.GetFillVoxel(pos.Value);
  1404. if (result != null)
  1405. {
  1406. for (int i = 0; i < result.Count; i++)
  1407. editVoxelList.Set(result[i], VoxelBase.FaceAllFlags);
  1408. UpdatePreviewMesh();
  1409. }
  1410. }
  1411. }
  1412. break;
  1413. case VoxelBase.Edit_ConfigureMaterialSubMode.Rect:
  1414. {
  1415. var pos = new IntVector2((int)Event.current.mousePosition.x, (int)Event.current.mousePosition.y);
  1416. if (first) { editorCommon.selectionRect.Reset(); editorCommon.selectionRect.SetStart(pos); }
  1417. else editorCommon.selectionRect.SetEnd(pos);
  1418. //
  1419. editVoxelList.Clear();
  1420. {
  1421. var list = editorCommon.GetSelectionRectVoxel();
  1422. for (int i = 0; i < list.Count; i++)
  1423. editVoxelList.Set(list[i], VoxelBase.FaceAllFlags);
  1424. }
  1425. UpdatePreviewMesh();
  1426. }
  1427. break;
  1428. }
  1429. }
  1430. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1431. {
  1432. UpdateCursorMesh();
  1433. switch (baseTarget.edit_configureDisableSubMode)
  1434. {
  1435. case VoxelBase.Edit_ConfigureDisableSubMode.Face:
  1436. {
  1437. IntVector3 pos;
  1438. VoxelBase.Face face;
  1439. if (editorCommon.GetMousePositionVoxelFace(out pos, out face))
  1440. {
  1441. var combineFace = editVoxelList.Get(pos);
  1442. combineFace |= face;
  1443. editVoxelList.Set(pos, combineFace);
  1444. UpdatePreviewMesh();
  1445. }
  1446. }
  1447. break;
  1448. case VoxelBase.Edit_ConfigureDisableSubMode.Fill:
  1449. {
  1450. IntVector3 pos;
  1451. VoxelBase.Face face;
  1452. if (editorCommon.GetMousePositionVoxelFace(out pos, out face))
  1453. {
  1454. var result = editorCommon.GetFillVoxelFace(pos, face);
  1455. if (result != null)
  1456. {
  1457. for (int i = 0; i < result.Count; i++)
  1458. {
  1459. var combineFace = editVoxelList.Get(result[i]);
  1460. combineFace |= face;
  1461. editVoxelList.Set(result[i], combineFace);
  1462. }
  1463. UpdatePreviewMesh();
  1464. }
  1465. }
  1466. }
  1467. break;
  1468. case VoxelBase.Edit_ConfigureDisableSubMode.Rect:
  1469. {
  1470. var pos = new IntVector2((int)Event.current.mousePosition.x, (int)Event.current.mousePosition.y);
  1471. if (first) { editorCommon.selectionRect.Reset(); editorCommon.selectionRect.SetStart(pos); }
  1472. else editorCommon.selectionRect.SetEnd(pos);
  1473. //
  1474. editVoxelList.Clear();
  1475. {
  1476. var list = editorCommon.GetSelectionRectVoxelFace();
  1477. foreach (var pair in list)
  1478. {
  1479. var combineFace = editVoxelList.Get(pair.Key);
  1480. combineFace |= pair.Value;
  1481. editVoxelList.Set(pair.Key, combineFace);
  1482. }
  1483. }
  1484. UpdatePreviewMesh();
  1485. }
  1486. break;
  1487. }
  1488. }
  1489. }
  1490. private void EventMouseApply()
  1491. {
  1492. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1493. {
  1494. Undo.RecordObject(baseTarget, "Material");
  1495. bool update = false;
  1496. if (baseTarget.edit_configureMaterialMainMode == VoxelBase.Edit_ConfigureMaterialMainMode.Add)
  1497. {
  1498. editVoxelList.AllAction((x, y, z, face) =>
  1499. {
  1500. if (!update)
  1501. DisconnectPrefabInstance();
  1502. for (int i = 0; i < baseTarget.materialData.Count; i++)
  1503. {
  1504. if (i == baseTarget.edit_configureMaterialIndex) continue;
  1505. if (baseTarget.materialData[i].GetMaterial(new IntVector3(x, y, z)))
  1506. {
  1507. baseTarget.materialData[i].RemoveMaterial(new IntVector3(x, y, z));
  1508. }
  1509. }
  1510. baseTarget.materialData[baseTarget.edit_configureMaterialIndex].SetMaterial(new IntVector3(x, y, z));
  1511. update = true;
  1512. });
  1513. }
  1514. else if (baseTarget.edit_configureMaterialMainMode == VoxelBase.Edit_ConfigureMaterialMainMode.Remove)
  1515. {
  1516. editVoxelList.AllAction((x, y, z, face) =>
  1517. {
  1518. if (baseTarget.materialData[baseTarget.edit_configureMaterialIndex].GetMaterial(new IntVector3(x, y, z)))
  1519. {
  1520. if (!update)
  1521. DisconnectPrefabInstance();
  1522. baseTarget.materialData[baseTarget.edit_configureMaterialIndex].RemoveMaterial(new IntVector3(x, y, z));
  1523. update = true;
  1524. }
  1525. });
  1526. }
  1527. else
  1528. {
  1529. Assert.IsTrue(false);
  1530. }
  1531. if (update)
  1532. {
  1533. UpdateConfigureEnableMesh();
  1534. baseTarget.edit_afterRefresh = true;
  1535. }
  1536. editVoxelList.Clear();
  1537. }
  1538. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1539. {
  1540. Undo.RecordObject(baseTarget, "Disable Face");
  1541. if (baseTarget.edit_configureDisableMainMode == VoxelBase.Edit_ConfigureDisableMainMode.Add)
  1542. {
  1543. bool update = false;
  1544. editVoxelList.AllAction((x, y, z, face) =>
  1545. {
  1546. if (!update)
  1547. DisconnectPrefabInstance();
  1548. var pos = new IntVector3(x, y, z);
  1549. var combineFace = baseTarget.disableData.GetDisable(pos);
  1550. combineFace |= face;
  1551. if ((combineFace & VoxelBase.FaceAllFlags) != 0)
  1552. baseTarget.disableData.SetDisable(pos, combineFace);
  1553. else
  1554. baseTarget.disableData.RemoveDisable(pos);
  1555. update = true;
  1556. });
  1557. if (update)
  1558. {
  1559. UpdateConfigureEnableMesh();
  1560. baseTarget.edit_afterRefresh = true;
  1561. }
  1562. }
  1563. else if (baseTarget.edit_configureDisableMainMode == VoxelBase.Edit_ConfigureDisableMainMode.Remove)
  1564. {
  1565. bool update = false;
  1566. editVoxelList.AllAction((x, y, z, face) =>
  1567. {
  1568. if (!update)
  1569. DisconnectPrefabInstance();
  1570. var pos = new IntVector3(x, y, z);
  1571. var combineFace = baseTarget.disableData.GetDisable(pos);
  1572. combineFace &= ~face;
  1573. if ((combineFace & VoxelBase.FaceAllFlags) != 0)
  1574. baseTarget.disableData.SetDisable(pos, combineFace);
  1575. else
  1576. baseTarget.disableData.RemoveDisable(pos);
  1577. update = true;
  1578. });
  1579. if (update)
  1580. {
  1581. UpdateConfigureEnableMesh();
  1582. baseTarget.edit_afterRefresh = true;
  1583. }
  1584. }
  1585. else
  1586. {
  1587. Assert.IsTrue(false);
  1588. }
  1589. editVoxelList.Clear();
  1590. }
  1591. }
  1592. private void ShowNotification()
  1593. {
  1594. SceneView.currentDrawingSceneView.ShowNotification(new GUIContent(string.Format("{0} - {1}", baseTarget.edit_configureMaterialMainMode, baseTarget.edit_configureMaterialSubMode)));
  1595. }
  1596. protected abstract List<Material> GetMaterialListMaterials();
  1597. protected virtual void AddMaterialData(string name)
  1598. {
  1599. baseTarget.materialData.Add(new MaterialData() { name = name });
  1600. }
  1601. protected virtual void RemoveMaterialData(int index)
  1602. {
  1603. baseTarget.materialData.RemoveAt(index);
  1604. }
  1605. protected void UpdateMaterialList()
  1606. {
  1607. materialList = null;
  1608. if (baseTarget.materialData == null) return;
  1609. materialList = new ReorderableList(
  1610. serializedObject,
  1611. serializedObject.FindProperty("materialData"),
  1612. false, true,
  1613. !baseTarget.loadFromVoxelFile,
  1614. !baseTarget.loadFromVoxelFile
  1615. );
  1616. materialList.elementHeight = 20;
  1617. materialList.drawHeaderCallback = (rect) =>
  1618. {
  1619. Rect r = rect;
  1620. EditorGUI.LabelField(r, "Name", EditorStyles.boldLabel);
  1621. r.x = 182;
  1622. var materials = GetMaterialListMaterials();
  1623. if (materials != null)
  1624. EditorGUI.LabelField(r, "Material", EditorStyles.boldLabel);
  1625. #region LoadFormVoxelFile
  1626. r.x = r.width - 128;
  1627. {
  1628. EditorGUI.BeginDisabledGroup(baseTarget.voxelData != null && baseTarget.voxelData.materials == null);
  1629. EditorGUI.BeginChangeCheck();
  1630. string tooltip = null;
  1631. if (baseTarget.voxelData == null)
  1632. tooltip = "Voxel data is not loaded.";
  1633. else if (baseTarget.voxelData.materials == null)
  1634. tooltip = "Material is not included in the voxel data.";
  1635. var loadFromVoxelFile = EditorGUI.ToggleLeft(r, new GUIContent("Load From Voxel File", tooltip), baseTarget.loadFromVoxelFile);
  1636. if (EditorGUI.EndChangeCheck())
  1637. {
  1638. UndoRecordObject("Inspector");
  1639. baseTarget.loadFromVoxelFile = loadFromVoxelFile;
  1640. EditorApplication.delayCall += () =>
  1641. {
  1642. if (baseTarget.loadFromVoxelFile)
  1643. {
  1644. baseTarget.voxelData = null;
  1645. baseTarget.voxelDataCreatedVoxelFileTimeTicks = 0;
  1646. Refresh();
  1647. }
  1648. else
  1649. {
  1650. UpdateMaterialList();
  1651. }
  1652. };
  1653. }
  1654. EditorGUI.EndDisabledGroup();
  1655. }
  1656. #endregion
  1657. };
  1658. materialList.drawElementCallback = (rect, index, isActive, isFocused) =>
  1659. {
  1660. rect.yMin += 2;
  1661. rect.yMax -= 2;
  1662. if (index < baseTarget.materialData.Count)
  1663. {
  1664. #region Name
  1665. {
  1666. Rect r = rect;
  1667. r.width = 144;
  1668. if (index == 0)
  1669. {
  1670. EditorGUI.LabelField(r, "default", guiStyleLabelMiddleLeftItalic);
  1671. }
  1672. else if (!baseTarget.loadFromVoxelFile)
  1673. {
  1674. EditorGUI.BeginChangeCheck();
  1675. string name = EditorGUI.TextField(r, baseTarget.materialData[index].name, guiStyleTextFieldMiddleLeft);
  1676. if (EditorGUI.EndChangeCheck())
  1677. {
  1678. UndoRecordObject("Inspector");
  1679. baseTarget.materialData[index].name = name;
  1680. }
  1681. }
  1682. else
  1683. {
  1684. EditorGUI.LabelField(r, baseTarget.materialData[index].name, guiStyleLabelMiddleLeftItalic);
  1685. }
  1686. }
  1687. #endregion
  1688. #region Material
  1689. var materials = GetMaterialListMaterials();
  1690. if (materials != null && index < materials.Count)
  1691. {
  1692. {
  1693. Rect r = rect;
  1694. r.xMin = 182;
  1695. r.width = rect.width - r.xMin;
  1696. if (baseTarget.advancedMode)
  1697. r.width -= 64;
  1698. if (baseTarget.advancedMode && materials[index] != null && !IsMainAsset(materials[index]))
  1699. r.width -= 48;
  1700. EditorGUI.BeginDisabledGroup(true);
  1701. EditorGUI.ObjectField(r, materials[index], typeof(Material), false);
  1702. EditorGUI.EndDisabledGroup();
  1703. }
  1704. if (baseTarget.advancedMode && materials[index] != null)
  1705. {
  1706. Rect r = rect;
  1707. r.xMin += rect.width - 46;
  1708. r.width = 48;
  1709. {
  1710. if (GUI.Button(r, "Reset"))
  1711. {
  1712. #region Reset Material
  1713. EditorApplication.delayCall += () =>
  1714. {
  1715. UndoRecordObject("Reset Material");
  1716. if (!IsMainAsset(materials[index]))
  1717. materials[index] = null;
  1718. else
  1719. materials[index] = Instantiate<Material>(materials[index]);
  1720. Refresh();
  1721. };
  1722. #endregion
  1723. }
  1724. }
  1725. if (!IsMainAsset(materials[index]))
  1726. {
  1727. r.xMin -= 52;
  1728. r.width = 48;
  1729. if (GUI.Button(r, "Save"))
  1730. {
  1731. #region Create Material
  1732. string path = EditorUtility.SaveFilePanel("Save material", baseCore.GetDefaultPath(), string.Format("{0}_mat{1}.mat", baseTarget.gameObject.name, index), "mat");
  1733. if (!string.IsNullOrEmpty(path))
  1734. {
  1735. if (path.IndexOf(Application.dataPath) < 0)
  1736. {
  1737. SaveInsideAssetsFolderDisplayDialog();
  1738. }
  1739. else
  1740. {
  1741. EditorApplication.delayCall += () =>
  1742. {
  1743. UndoRecordObject("Save Material");
  1744. path = path.Replace(Application.dataPath, "Assets");
  1745. AssetDatabase.CreateAsset(Material.Instantiate(materials[index]), path);
  1746. materials[index] = AssetDatabase.LoadAssetAtPath<Material>(path);
  1747. Refresh();
  1748. };
  1749. }
  1750. }
  1751. #endregion
  1752. }
  1753. }
  1754. }
  1755. }
  1756. #endregion
  1757. }
  1758. };
  1759. materialList.onSelectCallback = (list) =>
  1760. {
  1761. UndoRecordObject("Inspector");
  1762. baseTarget.edit_configureMaterialIndex = list.index;
  1763. UpdateConfigureEnableMesh();
  1764. InternalEditorUtility.RepaintAllViews();
  1765. };
  1766. materialList.onAddCallback = (list) =>
  1767. {
  1768. var index = list.index;
  1769. EditorApplication.delayCall += () =>
  1770. {
  1771. UndoRecordObject("Inspector");
  1772. AddMaterialData(baseTarget.materialData.Count.ToString());
  1773. var materials = GetMaterialListMaterials();
  1774. if (materials != null)
  1775. materials.Add(null);
  1776. baseTarget.edit_configureMaterialIndex = index;
  1777. list.index = baseTarget.edit_configureMaterialIndex;
  1778. Refresh();
  1779. InternalEditorUtility.RepaintAllViews();
  1780. };
  1781. };
  1782. materialList.onRemoveCallback = (list) =>
  1783. {
  1784. if (list.index > 0 && list.index < baseTarget.materialData.Count)
  1785. {
  1786. var index = list.index;
  1787. EditorApplication.delayCall += () =>
  1788. {
  1789. UndoRecordObject("Inspector");
  1790. RemoveMaterialData(index);
  1791. var materials = GetMaterialListMaterials();
  1792. if (materials != null)
  1793. materials.RemoveAt(index);
  1794. baseTarget.edit_configureMaterialIndex = -1;
  1795. Refresh();
  1796. InternalEditorUtility.RepaintAllViews();
  1797. };
  1798. }
  1799. };
  1800. if (baseTarget.edit_configureMaterialIndex >= 0 && baseTarget.materialData != null && baseTarget.edit_configureMaterialIndex < baseTarget.materialData.Count)
  1801. materialList.index = baseTarget.edit_configureMaterialIndex;
  1802. else
  1803. baseTarget.edit_configureMaterialIndex = 0;
  1804. }
  1805. protected virtual void UpdateConfigureEnableMesh()
  1806. {
  1807. UpdateSilhouetteMeshMesh();
  1808. if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Material)
  1809. UpdateMaterialEnableMesh();
  1810. else if (baseTarget.edit_configureMode == VoxelBase.Edit_ConfigureMode.Disable)
  1811. UpdateDisableEnableMesh();
  1812. }
  1813. protected void UpdateMaterialEnableMesh()
  1814. {
  1815. if (baseTarget.materialData == null || baseCore.voxelData == null)
  1816. {
  1817. EditEnableMeshDestroy();
  1818. return;
  1819. }
  1820. List<VoxelData.Voxel> voxels = new List<VoxelData.Voxel>(baseCore.voxelData.voxels.Length);
  1821. if (baseTarget.edit_configureMaterialIndex == 0)
  1822. {
  1823. for (int i = 0; i < baseCore.voxelData.voxels.Length; i++)
  1824. {
  1825. {
  1826. bool enable = true;
  1827. for (int j = 0; j < baseTarget.materialData.Count; j++)
  1828. {
  1829. if (baseTarget.materialData[j].GetMaterial(baseCore.voxelData.voxels[i].position))
  1830. {
  1831. enable = false;
  1832. break;
  1833. }
  1834. }
  1835. if (!enable) continue;
  1836. }
  1837. var voxel = baseCore.voxelData.voxels[i];
  1838. voxel.palette = -1;
  1839. voxels.Add(voxel);
  1840. }
  1841. }
  1842. else if (baseTarget.edit_configureMaterialIndex >= 0 && baseTarget.edit_configureMaterialIndex < baseTarget.materialData.Count)
  1843. {
  1844. baseTarget.materialData[baseTarget.edit_configureMaterialIndex].AllAction((pos) =>
  1845. {
  1846. var index = baseCore.voxelData.VoxelTableContains(pos);
  1847. if (index < 0) return;
  1848. var voxel = baseCore.voxelData.voxels[index];
  1849. voxel.palette = -1;
  1850. voxels.Add(voxel);
  1851. });
  1852. }
  1853. baseTarget.edit_enableMesh = baseCore.Edit_CreateMesh(voxels);
  1854. }
  1855. protected void UpdateDisableEnableMesh()
  1856. {
  1857. if (baseTarget.disableData == null || baseCore.voxelData == null)
  1858. {
  1859. EditEnableMeshDestroy();
  1860. return;
  1861. }
  1862. List<VoxelData.Voxel> voxels = new List<VoxelData.Voxel>(baseCore.voxelData.voxels.Length);
  1863. {
  1864. baseTarget.disableData.AllAction((pos, face) =>
  1865. {
  1866. var index = baseCore.voxelData.VoxelTableContains(pos);
  1867. if (index < 0) return;
  1868. var voxel = baseCore.voxelData.voxels[index];
  1869. voxel.palette = -1;
  1870. voxel.visible = face;
  1871. voxels.Add(voxel);
  1872. });
  1873. }
  1874. baseTarget.edit_enableMesh = baseCore.Edit_CreateMesh(voxels);
  1875. }
  1876. public void EditEnableMeshDestroy()
  1877. {
  1878. if (baseTarget.edit_enableMesh != null)
  1879. {
  1880. for (int i = 0; i < baseTarget.edit_enableMesh.Length; i++)
  1881. {
  1882. MonoBehaviour.DestroyImmediate(baseTarget.edit_enableMesh[i]);
  1883. }
  1884. baseTarget.edit_enableMesh = null;
  1885. }
  1886. }
  1887. protected void AfterRefresh()
  1888. {
  1889. if (AnimationMode.InAnimationMode())
  1890. {
  1891. return;
  1892. }
  1893. if (baseTarget.edit_afterRefresh)
  1894. Refresh();
  1895. }
  1896. protected virtual void Refresh()
  1897. {
  1898. baseCore.ReCreate();
  1899. UpdateMaterialList();
  1900. UpdateConfigureEnableMesh();
  1901. }
  1902. protected void DisconnectPrefabInstance()
  1903. {
  1904. #if !UNITY_2018_3_OR_NEWER
  1905. if (PrefabUtility.GetPrefabType(baseTarget) == PrefabType.PrefabInstance)
  1906. {
  1907. PrefabUtility.DisconnectPrefabInstance(baseTarget);
  1908. }
  1909. #endif
  1910. }
  1911. protected class PrefabCreateMonitoringAssetModificationProcessor : UnityEditor.AssetModificationProcessor
  1912. {
  1913. public static bool IsContains(string path)
  1914. {
  1915. return paths.Contains(path);
  1916. }
  1917. public static void Remove(string path)
  1918. {
  1919. paths.Remove(path);
  1920. }
  1921. private static List<string> paths = new List<string>();
  1922. private static bool delayCheck = false;
  1923. private static void OnWillCreateAsset(string path)
  1924. {
  1925. if (Path.GetExtension(path) == ".prefab")
  1926. {
  1927. paths.Add(path);
  1928. if (!delayCheck)
  1929. {
  1930. EditorApplication.delayCall += () =>
  1931. {
  1932. CheckVoxelObject();
  1933. delayCheck = false;
  1934. };
  1935. delayCheck = true;
  1936. }
  1937. }
  1938. }
  1939. private static void CheckVoxelObject()
  1940. {
  1941. List<string> removeList = new List<string>();
  1942. foreach (var path in paths)
  1943. {
  1944. var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
  1945. if (prefab == null)
  1946. {
  1947. removeList.Add(path);
  1948. continue;
  1949. }
  1950. var voxelBase = prefab.GetComponent<VoxelBase>();
  1951. if (voxelBase == null)
  1952. {
  1953. removeList.Add(path);
  1954. continue;
  1955. }
  1956. }
  1957. foreach (var path in removeList)
  1958. {
  1959. paths.Remove(path);
  1960. }
  1961. }
  1962. }
  1963. protected void EditorPrefabInstanceUpdated(GameObject go)
  1964. {
  1965. #if UNITY_2018_3_OR_NEWER
  1966. var prefabType = PrefabUtility.GetPrefabAssetType(go);
  1967. if (prefabType != PrefabAssetType.Regular) return;
  1968. var prefab = PrefabUtility.GetCorrespondingObjectFromSource(go);
  1969. #else
  1970. var prefabType = PrefabUtility.GetPrefabType(go);
  1971. if (prefabType != PrefabType.PrefabInstance) return;
  1972. #if UNITY_2018_2_OR_NEWER
  1973. var prefab = PrefabUtility.GetCorrespondingObjectFromSource(go);
  1974. #else
  1975. var prefab = PrefabUtility.GetPrefabParent(go);
  1976. #endif
  1977. #endif
  1978. var path = AssetDatabase.GetAssetPath(prefab);
  1979. if (!PrefabCreateMonitoringAssetModificationProcessor.IsContains(path)) return;
  1980. PrefabCreateMonitoringAssetModificationProcessor.Remove(path);
  1981. {
  1982. #region Children
  1983. {
  1984. var childrenVoxelBases = go.GetComponentsInChildren<VoxelBase>(true);
  1985. foreach (var vb in childrenVoxelBases)
  1986. {
  1987. VoxelBaseCore.StaticForceReCreate(vb);
  1988. }
  1989. }
  1990. #endregion
  1991. #region Extra
  1992. {
  1993. var childrenVoxelBaseExplosions = go.GetComponentsInChildren<VoxelBaseExplosion>(true);
  1994. foreach (var vb in childrenVoxelBaseExplosions)
  1995. {
  1996. VoxelBaseExplosionCore.StaticForceGenerate(vb);
  1997. }
  1998. }
  1999. #endregion
  2000. EditorApplication.delayCall += () =>
  2001. {
  2002. #if UNITY_2018_3_OR_NEWER
  2003. PrefabUtility.ApplyPrefabInstance(go, InteractionMode.AutomatedAction);
  2004. #else
  2005. PrefabUtility.ReplacePrefab(go, prefab, ReplacePrefabOptions.ConnectToPrefab);
  2006. #endif
  2007. };
  2008. }
  2009. }
  2010. protected virtual void EditorUndoRedoPerformed()
  2011. {
  2012. if (AnimationMode.InAnimationMode())
  2013. {
  2014. baseTarget.edit_afterRefresh = true;
  2015. return;
  2016. }
  2017. if (baseTarget != null && baseCore != null)
  2018. {
  2019. if (baseCore.RefreshCheckerCheck())
  2020. {
  2021. if (baseTarget.importFlags != baseTarget.refreshChecker.importFlags)
  2022. baseCore.ReadyVoxelData(true);
  2023. Refresh();
  2024. }
  2025. else
  2026. {
  2027. UpdateConfigureEnableMesh();
  2028. }
  2029. }
  2030. Repaint();
  2031. }
  2032. }
  2033. }