VoxelChunksObjectEditor.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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. namespace VoxelImporter
  10. {
  11. [CustomEditor(typeof(VoxelChunksObject))]
  12. public class VoxelChunksObjectEditor : VoxelBaseEditor
  13. {
  14. public VoxelChunksObject objectTarget { get; protected set; }
  15. public VoxelChunksObjectCore objectCore { get; protected set; }
  16. #region strings
  17. private static string[] SplitModeQBStrings =
  18. {
  19. "Chunk Size",
  20. "Qubicle Matrix",
  21. };
  22. private static string[] SplitModeVOXStrings =
  23. {
  24. "Chunk Size",
  25. "MagicaVoxel World Editor",
  26. };
  27. private static string[] SplitModeDefaultStrings =
  28. {
  29. "Chunk Size",
  30. };
  31. #endregion
  32. protected override void OnEnable()
  33. {
  34. base.OnEnable();
  35. objectTarget = target as VoxelChunksObject;
  36. if (objectTarget == null) return;
  37. baseCore = objectCore = new VoxelChunksObjectCore(objectTarget);
  38. OnEnableInitializeSet();
  39. }
  40. protected override void InspectorGUI()
  41. {
  42. base.InspectorGUI();
  43. #if UNITY_2018_3_OR_NEWER
  44. {
  45. if (prefabType == PrefabAssetType.Regular && !baseCore.isPrefabEditMode)
  46. {
  47. EditorGUI.BeginDisabledGroup(true);
  48. }
  49. }
  50. #endif
  51. Action<UnityEngine.Object, string> TypeTitle = (o, title) =>
  52. {
  53. if (o == null)
  54. EditorGUILayout.LabelField(title, guiStyleMagentaBold);
  55. else if (prefabEnable && !AssetDatabase.Contains(o))
  56. EditorGUILayout.LabelField(title, guiStyleRedBold);
  57. else
  58. EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
  59. };
  60. InspectorGUI_Import();
  61. #region Object
  62. if (!string.IsNullOrEmpty(baseTarget.voxelFilePath))
  63. {
  64. //Object
  65. baseTarget.edit_objectFoldout = EditorGUILayout.Foldout(baseTarget.edit_objectFoldout, "Object", guiStyleFoldoutBold);
  66. if (baseTarget.edit_objectFoldout)
  67. {
  68. EditorGUI.BeginDisabledGroup(isPrefab);
  69. EditorGUILayout.BeginVertical(GUI.skin.box);
  70. #region Mesh
  71. if (baseTarget.advancedMode)
  72. {
  73. EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
  74. EditorGUI.indentLevel++;
  75. InspectorGUI_Object_Mesh_Settings();
  76. EditorGUI.indentLevel--;
  77. }
  78. #endregion
  79. #region Material
  80. {
  81. if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
  82. {
  83. if (objectTarget.materials == null || objectTarget.materials.Count == 0)
  84. EditorGUILayout.LabelField("Material", guiStyleMagentaBold);
  85. else if (prefabEnable)
  86. {
  87. bool contains = true;
  88. for (int i = 0; i < objectTarget.materials.Count; i++)
  89. {
  90. if (objectTarget.materials[i] == null || !AssetDatabase.Contains(objectTarget.materials[i]))
  91. {
  92. contains = false;
  93. break;
  94. }
  95. }
  96. EditorGUILayout.LabelField("Material", contains ? EditorStyles.boldLabel : guiStyleRedBold);
  97. }
  98. else
  99. EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
  100. }
  101. else
  102. {
  103. EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
  104. }
  105. EditorGUI.indentLevel++;
  106. #region updateMeshRendererMaterials
  107. if (baseTarget.advancedMode)
  108. {
  109. EditorGUI.BeginChangeCheck();
  110. var updateMeshRendererMaterials = EditorGUILayout.ToggleLeft("Update the Mesh Renderer Materials", baseTarget.updateMeshRendererMaterials);
  111. if (EditorGUI.EndChangeCheck())
  112. {
  113. if (EditorUtility.DisplayDialog("Update the Mesh Renderer Materials", "It will be changed.\nAre you sure?", "ok", "cancel"))
  114. {
  115. UndoRecordObject("Inspector");
  116. baseTarget.updateMeshRendererMaterials = updateMeshRendererMaterials;
  117. baseCore.SetRendererCompornent();
  118. }
  119. }
  120. }
  121. #endregion
  122. #region Material Mode
  123. if (baseTarget.advancedMode)
  124. {
  125. EditorGUI.BeginChangeCheck();
  126. var materialMode = (VoxelChunksObject.MaterialMode)EditorGUILayout.EnumPopup("Material Mode", objectTarget.materialMode);
  127. if (EditorGUI.EndChangeCheck())
  128. {
  129. UndoRecordObject("Inspector");
  130. {
  131. var chunkObjects = objectTarget.chunks;
  132. if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
  133. {
  134. objectTarget.materials = null;
  135. objectTarget.atlasTexture = null;
  136. }
  137. else if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Individual)
  138. {
  139. for (int i = 0; i < chunkObjects.Length; i++)
  140. {
  141. if (chunkObjects[i] == null) continue;
  142. chunkObjects[i].materials = null;
  143. chunkObjects[i].atlasTexture = null;
  144. }
  145. }
  146. }
  147. objectTarget.materialMode = materialMode;
  148. Refresh();
  149. }
  150. }
  151. #endregion
  152. if (materialList != null)
  153. {
  154. materialList.DoLayoutList();
  155. }
  156. InspectorGUI_ConfigureMaterial();
  157. EditorGUI.indentLevel--;
  158. }
  159. #endregion
  160. #region Texture
  161. if (baseTarget.advancedMode)
  162. {
  163. if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
  164. TypeTitle(objectTarget.atlasTexture, "Texture");
  165. else
  166. EditorGUILayout.LabelField("Texture", EditorStyles.boldLabel);
  167. EditorGUI.indentLevel++;
  168. #region updateMaterialTexture
  169. {
  170. EditorGUI.BeginChangeCheck();
  171. var updateMaterialTexture = EditorGUILayout.ToggleLeft("Update the Material Texture", baseTarget.updateMaterialTexture);
  172. if (EditorGUI.EndChangeCheck())
  173. {
  174. if (EditorUtility.DisplayDialog("Update the Material Texture", "It will be changed.\nAre you sure?", "ok", "cancel"))
  175. {
  176. UndoRecordObject("Inspector");
  177. baseTarget.updateMaterialTexture = updateMaterialTexture;
  178. baseCore.SetRendererCompornent();
  179. }
  180. }
  181. }
  182. #endregion
  183. #region Texture
  184. if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
  185. {
  186. EditorGUILayout.BeginHorizontal();
  187. {
  188. EditorGUI.BeginDisabledGroup(true);
  189. EditorGUILayout.ObjectField(objectTarget.atlasTexture, typeof(Texture2D), false);
  190. EditorGUI.EndDisabledGroup();
  191. }
  192. if (objectTarget.atlasTexture != null)
  193. {
  194. if (!IsMainAsset(objectTarget.atlasTexture))
  195. {
  196. if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
  197. {
  198. #region Create Texture
  199. string path = EditorUtility.SaveFilePanel("Save atlas texture", baseCore.GetDefaultPath(), string.Format("{0}_tex.png", baseTarget.gameObject.name), "png");
  200. if (!string.IsNullOrEmpty(path))
  201. {
  202. if (path.IndexOf(Application.dataPath) < 0)
  203. {
  204. SaveInsideAssetsFolderDisplayDialog();
  205. }
  206. else
  207. {
  208. UndoRecordObject("Save Atlas Texture");
  209. File.WriteAllBytes(path, objectTarget.atlasTexture.EncodeToPNG());
  210. path = path.Replace(Application.dataPath, "Assets");
  211. AssetDatabase.ImportAsset(path);
  212. objectCore.SetTextureImporterSetting(path, objectTarget.atlasTexture);
  213. objectTarget.atlasTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
  214. Refresh();
  215. }
  216. }
  217. #endregion
  218. }
  219. }
  220. {
  221. if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
  222. {
  223. #region Reset Texture
  224. UndoRecordObject("Reset Atlas Texture");
  225. objectTarget.atlasTexture = null;
  226. Refresh();
  227. #endregion
  228. }
  229. }
  230. }
  231. EditorGUILayout.EndHorizontal();
  232. }
  233. #endregion
  234. #region Generate Mip Maps
  235. {
  236. EditorGUI.BeginChangeCheck();
  237. var generateMipMaps = EditorGUILayout.Toggle("Generate Mip Maps", baseTarget.generateMipMaps);
  238. if (EditorGUI.EndChangeCheck())
  239. {
  240. UndoRecordObject("Inspector");
  241. baseTarget.generateMipMaps = generateMipMaps;
  242. Refresh();
  243. }
  244. }
  245. #endregion
  246. #region Texture Size
  247. if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
  248. {
  249. EditorGUILayout.LabelField("Texture Size", objectTarget.atlasTexture != null ? string.Format("{0} x {1}", objectTarget.atlasTexture.width, objectTarget.atlasTexture.height) : "");
  250. }
  251. #endregion
  252. EditorGUI.indentLevel--;
  253. }
  254. #endregion
  255. EditorGUILayout.EndVertical();
  256. EditorGUI.EndDisabledGroup();
  257. }
  258. }
  259. #endregion
  260. {
  261. EditorGUILayout.BeginHorizontal();
  262. EditorGUI.BeginDisabledGroup(isPrefab);
  263. InspectorGUI_Refresh();
  264. #region Refresh all chunks
  265. if (GUILayout.Button(new GUIContent("Refresh all chunks", "This will be created completely from Chunk's GameObject again.\nInformation maintained in normal Refresh will also be updated.")))
  266. {
  267. UndoRecordObject("Inspector", true);
  268. Refresh();
  269. }
  270. #endregion
  271. EditorGUI.EndDisabledGroup();
  272. EditorGUILayout.EndHorizontal();
  273. }
  274. #if UNITY_2018_3_OR_NEWER
  275. {
  276. if (prefabType == PrefabAssetType.Regular && !baseCore.isPrefabEditMode)
  277. {
  278. EditorGUI.EndDisabledGroup();
  279. }
  280. }
  281. #endif
  282. }
  283. protected override void UndoRecordObject(string text, bool reset = false)
  284. {
  285. base.UndoRecordObject(text);
  286. for (int i = 0; i < objectTarget.chunks.Length; i++)
  287. {
  288. if (objectTarget.chunks[i] == null) continue;
  289. Undo.RecordObject(objectTarget.chunks[i], text);
  290. }
  291. if (reset)
  292. {
  293. objectCore.RemoveAllChunk();
  294. }
  295. }
  296. protected override void InspectorGUI_ImportSettingsImportScaleVector()
  297. {
  298. EditorGUI.BeginChangeCheck();
  299. var importScale = EditorGUILayout.Vector3Field("Import Scale", objectTarget.edit_importScale);
  300. if (EditorGUI.EndChangeCheck())
  301. {
  302. InspectorGUI_ImportSettingsImportScale_Set(importScale);
  303. }
  304. }
  305. protected override void InspectorGUI_ImportSettingsImportScale_Set(Vector3 scale)
  306. {
  307. UndoRecordObject("Inspector");
  308. objectTarget.edit_importScale = scale;
  309. }
  310. protected override void InspectorGUI_ImportSettingsImportOffset()
  311. {
  312. EditorGUI.BeginChangeCheck();
  313. var importOffset = EditorGUILayout.Vector3Field("Import Offset", objectTarget.edit_importOffset);
  314. if (EditorGUI.EndChangeCheck())
  315. {
  316. UndoRecordObject("Inspector");
  317. objectTarget.edit_importOffset = importOffset;
  318. }
  319. }
  320. protected override void InspectorGUI_ImportSettingsExtra()
  321. {
  322. #region Split Mode
  323. {
  324. EditorGUI.BeginChangeCheck();
  325. int splitMode = 0;
  326. switch (objectTarget.fileType)
  327. {
  328. case VoxelBase.FileType.vox:
  329. splitMode = EditorGUILayout.Popup("Split Mode", objectTarget.splitMode == VoxelChunksObject.SplitMode.ChunkSize ? 0 : 1, SplitModeVOXStrings);
  330. break;
  331. case VoxelBase.FileType.qb:
  332. splitMode = EditorGUILayout.Popup("Split Mode", objectTarget.splitMode == VoxelChunksObject.SplitMode.ChunkSize ? 0 : 1, SplitModeQBStrings);
  333. break;
  334. default:
  335. splitMode = EditorGUILayout.Popup("Split Mode", objectTarget.splitMode == VoxelChunksObject.SplitMode.ChunkSize ? 0 : 1, SplitModeDefaultStrings);
  336. break;
  337. }
  338. if (EditorGUI.EndChangeCheck())
  339. {
  340. UndoRecordObject("Inspector", true);
  341. if (splitMode == 0)
  342. objectTarget.splitMode = VoxelChunksObject.SplitMode.ChunkSize;
  343. else
  344. objectTarget.splitMode = VoxelChunksObject.SplitMode.QubicleMatrix;
  345. Refresh();
  346. }
  347. }
  348. #endregion
  349. {
  350. EditorGUI.indentLevel++;
  351. #region Chunk Size
  352. if (objectTarget.splitMode == VoxelChunksObject.SplitMode.ChunkSize)
  353. {
  354. EditorGUI.BeginChangeCheck();
  355. var chunkSize = EditorGUILayout.Vector3Field("Chunk Size", new Vector3(objectTarget.edit_chunkSize.x, objectTarget.edit_chunkSize.y, objectTarget.edit_chunkSize.z));
  356. if (EditorGUI.EndChangeCheck())
  357. {
  358. UndoRecordObject("Inspector");
  359. objectTarget.edit_chunkSize.x = Mathf.RoundToInt(chunkSize.x);
  360. objectTarget.edit_chunkSize.y = Mathf.RoundToInt(chunkSize.y);
  361. objectTarget.edit_chunkSize.z = Mathf.RoundToInt(chunkSize.z);
  362. }
  363. }
  364. #endregion
  365. EditorGUI.indentLevel--;
  366. }
  367. #region Create contact faces of chunks
  368. if (baseTarget.advancedMode)
  369. {
  370. EditorGUI.BeginChangeCheck();
  371. var createContactChunkFaces = EditorGUILayout.Toggle("Create contact faces of chunks", objectTarget.createContactChunkFaces);
  372. if (EditorGUI.EndChangeCheck())
  373. {
  374. UndoRecordObject("Inspector");
  375. objectTarget.createContactChunkFaces = createContactChunkFaces;
  376. Refresh();
  377. }
  378. }
  379. #endregion
  380. #region Changed
  381. {
  382. if (objectTarget.IsEditorChanged())
  383. {
  384. EditorGUILayout.BeginHorizontal();
  385. EditorGUILayout.LabelField("Change Settings", guiStyleRedBold);
  386. EditorGUILayout.Space();
  387. if (GUILayout.Button("Revert", GUILayout.Width(64f)))
  388. {
  389. UndoRecordObject("Inspector");
  390. objectTarget.RevertEditorParam();
  391. }
  392. if (GUILayout.Button("Apply", GUILayout.Width(64f)))
  393. {
  394. UndoRecordObject("Inspector", true);
  395. objectTarget.ApplyEditorParam();
  396. Refresh();
  397. }
  398. EditorGUILayout.EndHorizontal();
  399. }
  400. }
  401. #endregion
  402. }
  403. protected override void Refresh()
  404. {
  405. base.Refresh();
  406. objectTarget.RevertEditorParam();
  407. }
  408. protected override List<Material> GetMaterialListMaterials()
  409. {
  410. return objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine ? objectTarget.materials : null;
  411. }
  412. [MenuItem("CONTEXT/VoxelChunksObject/Save All Unsaved Assets")]
  413. private static void ContextSaveAllUnsavedAssets(MenuCommand menuCommand)
  414. {
  415. var objectTarget = menuCommand.context as VoxelChunksObject;
  416. if (objectTarget == null) return;
  417. var objectCore = new VoxelChunksObjectCore(objectTarget);
  418. var folder = EditorUtility.OpenFolderPanel("Save all", objectCore.GetDefaultPath(), null);
  419. if (string.IsNullOrEmpty(folder)) return;
  420. if (folder.IndexOf(Application.dataPath) < 0)
  421. {
  422. SaveInsideAssetsFolderDisplayDialog();
  423. return;
  424. }
  425. Undo.RecordObject(objectTarget, "Save All Unsaved Assets");
  426. if (objectTarget.chunks != null)
  427. Undo.RecordObjects(objectTarget.chunks, "Save All Unsaved Assets");
  428. if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
  429. {
  430. #region Material
  431. if (objectTarget.materials != null)
  432. {
  433. for (int index = 0; index < objectTarget.materials.Count; index++)
  434. {
  435. if (objectTarget.materials[index] == null || IsMainAsset(objectTarget.materials[index])) continue;
  436. var path = folder + "/" + string.Format("{0}_mat{1}.mat", objectTarget.gameObject.name, index);
  437. path = path.Replace(Application.dataPath, "Assets");
  438. path = AssetDatabase.GenerateUniqueAssetPath(path);
  439. AssetDatabase.CreateAsset(Material.Instantiate(objectTarget.materials[index]), path);
  440. objectTarget.materials[index] = AssetDatabase.LoadAssetAtPath<Material>(path);
  441. }
  442. }
  443. #endregion
  444. #region Texture
  445. if (objectTarget.atlasTexture != null && !IsMainAsset(objectTarget.atlasTexture))
  446. {
  447. var path = folder + "/" + string.Format("{0}_tex.png", objectTarget.gameObject.name);
  448. {
  449. path = AssetDatabase.GenerateUniqueAssetPath(path.Replace(Application.dataPath, "Assets"));
  450. path = (Application.dataPath + path).Replace("AssetsAssets", "Assets");
  451. }
  452. File.WriteAllBytes(path, objectTarget.atlasTexture.EncodeToPNG());
  453. path = path.Replace(Application.dataPath, "Assets");
  454. AssetDatabase.ImportAsset(path);
  455. objectCore.SetTextureImporterSetting(path, objectTarget.atlasTexture);
  456. objectTarget.atlasTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
  457. }
  458. #endregion
  459. if (objectTarget.chunks != null)
  460. {
  461. for (int i = 0; i < objectTarget.chunks.Length; i++)
  462. {
  463. if (objectTarget.chunks[i] == null) continue;
  464. #region Mesh
  465. if (objectTarget.chunks[i].mesh != null && !IsMainAsset(objectTarget.chunks[i].mesh))
  466. {
  467. var path = folder + "/" + string.Format("{0}_{1}_mesh.asset", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName);
  468. path = path.Replace(Application.dataPath, "Assets");
  469. path = AssetDatabase.GenerateUniqueAssetPath(path);
  470. AssetDatabase.CreateAsset(Mesh.Instantiate(objectTarget.chunks[i].mesh), path);
  471. objectTarget.chunks[i].mesh = AssetDatabase.LoadAssetAtPath<Mesh>(path);
  472. }
  473. #endregion
  474. }
  475. }
  476. }
  477. else if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Individual)
  478. {
  479. if (objectTarget.chunks != null)
  480. {
  481. for (int i = 0; i < objectTarget.chunks.Length; i++)
  482. {
  483. if (objectTarget.chunks[i] == null) continue;
  484. #region Mesh
  485. if (objectTarget.chunks[i].mesh != null && !IsMainAsset(objectTarget.chunks[i].mesh))
  486. {
  487. var path = folder + "/" + string.Format("{0}_{1}_mesh.asset", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName);
  488. path = path.Replace(Application.dataPath, "Assets");
  489. path = AssetDatabase.GenerateUniqueAssetPath(path);
  490. AssetDatabase.CreateAsset(Mesh.Instantiate(objectTarget.chunks[i].mesh), path);
  491. objectTarget.chunks[i].mesh = AssetDatabase.LoadAssetAtPath<Mesh>(path);
  492. }
  493. #endregion
  494. #region Material
  495. if (objectTarget.chunks[i].materials != null)
  496. {
  497. for (int index = 0; index < objectTarget.chunks[i].materials.Count; index++)
  498. {
  499. if (objectTarget.chunks[i].materials[index] == null || IsMainAsset(objectTarget.chunks[i].materials[index])) continue;
  500. var path = folder + "/" + string.Format("{0}_{1}_mat{2}.mat", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName, index);
  501. path = path.Replace(Application.dataPath, "Assets");
  502. path = AssetDatabase.GenerateUniqueAssetPath(path);
  503. AssetDatabase.CreateAsset(Material.Instantiate(objectTarget.chunks[i].materials[index]), path);
  504. objectTarget.chunks[i].materials[index] = AssetDatabase.LoadAssetAtPath<Material>(path);
  505. }
  506. }
  507. #endregion
  508. #region Texture
  509. if (objectTarget.chunks[i].atlasTexture != null && !IsMainAsset(objectTarget.chunks[i].atlasTexture))
  510. {
  511. var path = folder + "/" + string.Format("{0}_{1}_tex.png", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName);
  512. {
  513. path = AssetDatabase.GenerateUniqueAssetPath(path.Replace(Application.dataPath, "Assets"));
  514. path = (Application.dataPath + path).Replace("AssetsAssets", "Assets");
  515. }
  516. File.WriteAllBytes(path, objectTarget.chunks[i].atlasTexture.EncodeToPNG());
  517. path = path.Replace(Application.dataPath, "Assets");
  518. AssetDatabase.ImportAsset(path);
  519. objectCore.SetTextureImporterSetting(path, objectTarget.chunks[i].atlasTexture);
  520. objectTarget.chunks[i].atlasTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
  521. }
  522. #endregion
  523. }
  524. }
  525. }
  526. else
  527. {
  528. Assert.IsTrue(false);
  529. }
  530. objectCore.ReCreate();
  531. InternalEditorUtility.RepaintAllViews();
  532. }
  533. [MenuItem("CONTEXT/VoxelChunksObject/Reset All Assets")]
  534. private static void ResetAllSavedAssets(MenuCommand menuCommand)
  535. {
  536. var objectTarget = menuCommand.context as VoxelChunksObject;
  537. if (objectTarget == null) return;
  538. var objectCore = new VoxelChunksObjectCore(objectTarget);
  539. Undo.RecordObject(objectTarget, "Reset All Assets");
  540. if (objectTarget.chunks != null)
  541. Undo.RecordObjects(objectTarget.chunks, "Save All Unsaved Assets");
  542. #region Material
  543. if (objectTarget.materials != null)
  544. {
  545. for (int i = 0; i < objectTarget.materials.Count; i++)
  546. {
  547. if (!IsMainAsset(objectTarget.materials[i]))
  548. objectTarget.materials[i] = null;
  549. else
  550. objectTarget.materials[i] = Instantiate<Material>(objectTarget.materials[i]);
  551. }
  552. }
  553. #endregion
  554. #region Texture
  555. objectTarget.atlasTexture = null;
  556. #endregion
  557. if (objectTarget.chunks != null)
  558. {
  559. for (int i = 0; i < objectTarget.chunks.Length; i++)
  560. {
  561. if (objectTarget.chunks[i] == null) continue;
  562. objectTarget.chunks[i].mesh = null;
  563. #region Material
  564. if (objectTarget.chunks[i].materials != null)
  565. {
  566. for (int j = 0; j < objectTarget.chunks[i].materials.Count; j++)
  567. {
  568. if (!IsMainAsset(objectTarget.chunks[i].materials[j]))
  569. objectTarget.chunks[i].materials[j] = null;
  570. else
  571. objectTarget.chunks[i].materials[j] = Instantiate<Material>(objectTarget.chunks[i].materials[j]);
  572. }
  573. }
  574. #endregion
  575. objectTarget.chunks[i].atlasTexture = null;
  576. }
  577. }
  578. objectCore.ReCreate();
  579. InternalEditorUtility.RepaintAllViews();
  580. }
  581. [MenuItem("CONTEXT/VoxelChunksObject/Export COLLADA(dae) File", false, 10000)]
  582. private static void ExportDaeFile(MenuCommand menuCommand)
  583. {
  584. var objectTarget = menuCommand.context as VoxelChunksObject;
  585. if (objectTarget == null) return;
  586. var objectCore = new VoxelChunksObjectCore(objectTarget);
  587. string path = EditorUtility.SaveFilePanel("Export COLLADA(dae) File", objectCore.GetDefaultPath(), string.Format("{0}.dae", Path.GetFileNameWithoutExtension(objectTarget.voxelFilePath)), "dae");
  588. if (string.IsNullOrEmpty(path)) return;
  589. if (!objectCore.ExportDaeFile(path))
  590. {
  591. Debug.LogErrorFormat("<color=green>[Voxel Importer]</color> Export COLLADA(dae) File error. file:{0}", path);
  592. }
  593. }
  594. [MenuItem("CONTEXT/VoxelChunksObject/Export COLLADA(dae) File", true)]
  595. private static bool IsValidateExportDaeFile(MenuCommand menuCommand)
  596. {
  597. var objectTarget = menuCommand.context as VoxelChunksObject;
  598. if (objectTarget == null) return false;
  599. #if UNITY_2018_3_OR_NEWER
  600. return true;
  601. #else
  602. return PrefabUtility.GetPrefabType(objectTarget) != PrefabType.Prefab;
  603. #endif
  604. }
  605. [MenuItem("CONTEXT/VoxelChunksObject/Remove All Voxel Importer Compornent", false, 10100)]
  606. private static void RemoveAllVoxelImporterCompornent(MenuCommand menuCommand)
  607. {
  608. var objectTarget = menuCommand.context as VoxelChunksObject;
  609. if (objectTarget == null) return;
  610. if (objectTarget.chunks != null)
  611. {
  612. for (int i = 0; i < objectTarget.chunks.Length; i++)
  613. {
  614. Undo.DestroyObjectImmediate(objectTarget.chunks[i]);
  615. }
  616. }
  617. Undo.DestroyObjectImmediate(objectTarget);
  618. }
  619. }
  620. }