protected override void Inspector_MeshMaterial()
        {
            #region Mesh
            {
                EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
                {
                    EditorGUI.indentLevel++;
                    {
                        if (explosionObject.meshes != null)
                        {
                            for (int i = 0; i < explosionObject.meshes.Count; i++)
                            {
                                EditorGUILayout.BeginHorizontal();
                                {
                                    EditorGUI.BeginDisabledGroup(true);
                                    EditorGUILayout.ObjectField(explosionObject.meshes[i].mesh, typeof(Mesh), false);
                                    EditorGUI.EndDisabledGroup();
                                }
                                if (explosionObject.meshes[i] != null && explosionObject.meshes[i].mesh != null)
                                {
                                    if (!EditorCommon.IsMainAsset(explosionObject.meshes[i].mesh))
                                    {
                                        if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                        {
                                            #region Create Mesh
                                            string path = EditorUtility.SaveFilePanel("Save mesh", explosionCore.voxelBaseCore.GetDefaultPath(), string.Format("{0}_explosion_mesh{1}.asset", explosionObject.gameObject.name, i), "asset");
                                            if (!string.IsNullOrEmpty(path))
                                            {
                                                if (path.IndexOf(Application.dataPath) < 0)
                                                {
                                                    EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                                }
                                                else
                                                {
                                                    Undo.RecordObject(explosionObject, "Save Mesh");
                                                    path = FileUtil.GetProjectRelativePath(path);
                                                    AssetDatabase.CreateAsset(Mesh.Instantiate(explosionObject.meshes[i].mesh), path);
                                                    explosionObject.meshes[i].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                                                    explosionCore.Generate();
                                                }
                                            }
                                            #endregion
                                        }
                                    }
                                    {
                                        if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                        {
                                            #region Reset Mesh
                                            Undo.RecordObject(explosionObject, "Reset Mesh");
                                            explosionObject.meshes[i].mesh = null;
                                            explosionCore.Generate();
                                            #endregion
                                        }
                                    }
                                }
                                EditorGUILayout.EndHorizontal();
                            }
                        }
                    }
                    EditorGUI.indentLevel--;
                }
            }
            #endregion

            #region Material
            {
                EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
                {
                    EditorGUI.indentLevel++;
                    {
                        if (explosionObject.materials != null)
                        {
                            for (int i = 0; i < explosionObject.materials.Count; i++)
                            {
                                EditorGUILayout.BeginHorizontal();
                                {
                                    EditorGUI.BeginDisabledGroup(true);
                                    EditorGUILayout.ObjectField(explosionObject.materials[i], typeof(Material), false);
                                    EditorGUI.EndDisabledGroup();
                                }
                                if (explosionObject.materials[i] != null)
                                {
                                    if (!EditorCommon.IsMainAsset(explosionObject.materials[i]))
                                    {
                                        if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                        {
                                            #region Create Material
                                            string path = EditorUtility.SaveFilePanel("Save material", explosionCore.voxelBaseCore.GetDefaultPath(), string.Format("{0}_explosion_mat{1}.mat", explosionObject.gameObject.name, i), "mat");
                                            if (!string.IsNullOrEmpty(path))
                                            {
                                                if (path.IndexOf(Application.dataPath) < 0)
                                                {
                                                    EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                                }
                                                else
                                                {
                                                    Undo.RecordObject(explosionObject, "Save Material");
                                                    path = FileUtil.GetProjectRelativePath(path);
                                                    AssetDatabase.CreateAsset(Material.Instantiate(explosionObject.materials[i]), path);
                                                    explosionObject.materials[i] = AssetDatabase.LoadAssetAtPath <Material>(path);
                                                    explosionCore.Generate();
                                                }
                                            }

                                            #endregion
                                        }
                                    }
                                    {
                                        if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                        {
                                            #region Reset Material
                                            Undo.RecordObject(explosionObject, "Reset Material");
                                            explosionObject.materials[i] = EditorCommon.Instantiate(explosionObject.materials[i]);
                                            explosionCore.Generate();
                                            #endregion
                                        }
                                    }
                                }
                                EditorGUILayout.EndHorizontal();
                            }
                        }
                    }
                    EditorGUI.indentLevel--;
                }
            }
            #endregion
        }
        protected void InspectorGUI()
        {
            #region Object
            {
                explosionObject.edit_objectFoldout = EditorGUILayout.Foldout(explosionObject.edit_objectFoldout, "Object", guiStyleFoldoutBold);
                if (explosionObject.edit_objectFoldout)
                {
                    EditorGUILayout.BeginVertical(GUI.skin.box);
                    #region Mesh
                    {
                        EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region Mesh
                        if (explosionObject.meshes != null)
                        {
                            for (int i = 0; i < explosionObject.meshes.Count; i++)
                            {
                                EditorGUILayout.BeginHorizontal();
                                {
                                    EditorGUI.BeginDisabledGroup(true);
                                    EditorGUILayout.ObjectField(explosionObject.meshes[i].mesh, typeof(Mesh), false);
                                    EditorGUI.EndDisabledGroup();
                                }
                                if (explosionObject.meshes[i].mesh != null)
                                {
                                    if (!EditorCommon.IsMainAsset(explosionObject.meshes[i].mesh))
                                    {
                                        if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                        {
                                            #region Create Mesh
                                            string path = EditorUtility.SaveFilePanel("Save mesh", chunkCore.GetDefaultPath(), string.Format("{0}_{1}_explosion_mesh{2}.asset", voxelObject.gameObject.name, chunkObject.chunkName, i), "asset");
                                            if (!string.IsNullOrEmpty(path))
                                            {
                                                if (path.IndexOf(Application.dataPath) < 0)
                                                {
                                                    EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                                }
                                                else
                                                {
                                                    Undo.RecordObject(explosionObject, "Save Mesh");
                                                    path = FileUtil.GetProjectRelativePath(path);
                                                    AssetDatabase.CreateAsset(Mesh.Instantiate(explosionObject.meshes[i].mesh), path);
                                                    explosionObject.meshes[i].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                                                    voxelExplosionCore.Generate();
                                                }
                                            }
                                            #endregion
                                        }
                                    }
                                    {
                                        if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                        {
                                            #region Reset Mesh
                                            Undo.RecordObject(voxelExplosionObject, "Reset Mesh");
                                            Undo.RecordObjects(voxelExplosionObject.chunksExplosion, "Reset Mesh");
                                            explosionObject.meshes[i].mesh = null;
                                            voxelExplosionCore.Generate();
                                            #endregion
                                        }
                                    }
                                }
                                EditorGUILayout.EndHorizontal();
                            }
                        }
                        #endregion
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    #region Material
                    if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region Material
                        for (int i = 0; i < explosionObject.materials.Count; i++)
                        {
                            EditorGUILayout.BeginHorizontal();
                            {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.ObjectField(explosionObject.materials[i], typeof(Material), false);
                                EditorGUI.EndDisabledGroup();
                            }
                            if (explosionObject.materials[i] != null)
                            {
                                if (!EditorCommon.IsMainAsset(explosionObject.materials[i]))
                                {
                                    if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Create Material
                                        string defaultName = string.Format("{0}_{1}_explosion_mat{2}.mat", voxelObject.gameObject.name, chunkObject.chunkName, i);
                                        string path        = EditorUtility.SaveFilePanel("Save material", chunkCore.GetDefaultPath(), defaultName, "mat");
                                        if (!string.IsNullOrEmpty(path))
                                        {
                                            if (path.IndexOf(Application.dataPath) < 0)
                                            {
                                                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                            }
                                            else
                                            {
                                                Undo.RecordObject(explosionObject, "Save Material");
                                                path = FileUtil.GetProjectRelativePath(path);
                                                AssetDatabase.CreateAsset(Material.Instantiate(explosionObject.materials[i]), path);
                                                explosionObject.materials[i] = AssetDatabase.LoadAssetAtPath <Material>(path);
                                                voxelExplosionCore.Generate();
                                            }
                                        }

                                        #endregion
                                    }
                                }
                                {
                                    if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Reset Material
                                        Undo.RecordObject(voxelExplosionObject, "Reset Material");
                                        Undo.RecordObjects(voxelExplosionObject.chunksExplosion, "Reset Material");
                                        explosionObject.materials[i] = EditorCommon.Instantiate(explosionObject.materials[i]);
                                        voxelExplosionCore.Generate();
                                        #endregion
                                    }
                                }
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                        #endregion
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    EditorGUILayout.EndVertical();
                }
            }
            #endregion

            #region Generate
            {
                if (GUILayout.Button("Generate"))
                {
                    Undo.RecordObject(voxelExplosionObject, "Generate Voxel Explosion");
                    Undo.RecordObjects(voxelExplosionObject.chunksExplosion, "Generate Voxel Explosion");
                    voxelExplosionCore.Generate();
                }
            }
            #endregion
        }
        private static void SaveAllUnsavedAssets(MenuCommand menuCommand)
        {
            var explosionObject = menuCommand.context as VoxelFrameAnimationObjectExplosion;

            if (explosionObject == null)
            {
                return;
            }

            var explosionCore = new VoxelFrameAnimationObjectExplosionCore(explosionObject);

            var folder = EditorUtility.OpenFolderPanel("Save all", explosionCore.voxelBaseCore.GetDefaultPath(), null);

            if (string.IsNullOrEmpty(folder))
            {
                return;
            }
            if (folder.IndexOf(Application.dataPath) < 0)
            {
                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                return;
            }

            Undo.RecordObject(explosionObject, "Save All Unsaved Assets");

            #region Mesh
            if (explosionObject.meshes != null)
            {
                for (int i = 0; i < explosionObject.meshes.Count; i++)
                {
                    if (explosionObject.meshes[i] != null && explosionObject.meshes[i].mesh != null && !EditorCommon.IsMainAsset(explosionObject.meshes[i].mesh))
                    {
                        var path = folder + "/" + string.Format("{0}_explosion_mesh{1}.asset", explosionObject.gameObject.name, i);
                        path = FileUtil.GetProjectRelativePath(path);
                        path = AssetDatabase.GenerateUniqueAssetPath(path);
                        AssetDatabase.CreateAsset(Mesh.Instantiate(explosionObject.meshes[i].mesh), path);
                        explosionObject.meshes[i].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                    }
                }
            }
            #endregion

            #region Material
            if (explosionObject.materials != null)
            {
                for (int index = 0; index < explosionObject.materials.Count; index++)
                {
                    if (explosionObject.materials[index] == null)
                    {
                        continue;
                    }
                    if (EditorCommon.IsMainAsset(explosionObject.materials[index]))
                    {
                        continue;
                    }
                    var path = folder + "/" + string.Format("{0}_explosion_mat{1}.mat", explosionObject.gameObject.name, index);
                    path = FileUtil.GetProjectRelativePath(path);
                    path = AssetDatabase.GenerateUniqueAssetPath(path);
                    AssetDatabase.CreateAsset(Material.Instantiate(explosionObject.materials[index]), path);
                    explosionObject.materials[index] = AssetDatabase.LoadAssetAtPath <Material>(path);
                }
            }
            #endregion

            explosionCore.Generate();
            InternalEditorUtility.RepaintAllViews();
        }
        private static void SaveAllUnsavedAssets(MenuCommand menuCommand)
        {
            var objectTarget = menuCommand.context as VoxelChunksObject;

            if (objectTarget == null)
            {
                return;
            }

            var objectCore = new VoxelChunksObjectCore(objectTarget);

            var folder = EditorUtility.OpenFolderPanel("Save all", objectCore.GetDefaultPath(), null);

            if (string.IsNullOrEmpty(folder))
            {
                return;
            }
            if (folder.IndexOf(Application.dataPath) < 0)
            {
                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                return;
            }

            Undo.RecordObject(objectTarget, "Save All Unsaved Assets");
            if (objectTarget.chunks != null)
            {
                Undo.RecordObjects(objectTarget.chunks, "Save All Unsaved Assets");
            }

            if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
            {
                #region Material
                if (objectTarget.materials != null)
                {
                    for (int index = 0; index < objectTarget.materials.Count; index++)
                    {
                        if (objectTarget.materials[index] == null || EditorCommon.IsMainAsset(objectTarget.materials[index]))
                        {
                            continue;
                        }
                        var path = folder + "/" + string.Format("{0}_mat{1}.mat", objectTarget.gameObject.name, index);
                        path = FileUtil.GetProjectRelativePath(path);
                        path = AssetDatabase.GenerateUniqueAssetPath(path);
                        AssetDatabase.CreateAsset(Material.Instantiate(objectTarget.materials[index]), path);
                        objectTarget.materials[index] = AssetDatabase.LoadAssetAtPath <Material>(path);
                    }
                }
                #endregion

                #region Texture
                if (objectTarget.atlasTexture != null && !EditorCommon.IsMainAsset(objectTarget.atlasTexture))
                {
                    var path = folder + "/" + string.Format("{0}_tex.png", objectTarget.gameObject.name);
                    path = EditorCommon.GenerateUniqueAssetFullPath(path);
                    File.WriteAllBytes(path, objectTarget.atlasTexture.EncodeToPNG());
                    path = FileUtil.GetProjectRelativePath(path);
                    AssetDatabase.ImportAsset(path);
                    objectCore.SetTextureImporterSetting(path, objectTarget.atlasTexture);
                    objectTarget.atlasTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
                }
                #endregion

                if (objectTarget.chunks != null)
                {
                    for (int i = 0; i < objectTarget.chunks.Length; i++)
                    {
                        if (objectTarget.chunks[i] == null)
                        {
                            continue;
                        }
                        #region Mesh
                        if (objectTarget.chunks[i].mesh != null && !EditorCommon.IsMainAsset(objectTarget.chunks[i].mesh))
                        {
                            var path = folder + "/" + string.Format("{0}_{1}_mesh.asset", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName);
                            path = FileUtil.GetProjectRelativePath(path);
                            path = AssetDatabase.GenerateUniqueAssetPath(path);
                            AssetDatabase.CreateAsset(Mesh.Instantiate(objectTarget.chunks[i].mesh), path);
                            objectTarget.chunks[i].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                        }
                        #endregion
                    }
                }
            }
            else if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Individual)
            {
                if (objectTarget.chunks != null)
                {
                    for (int i = 0; i < objectTarget.chunks.Length; i++)
                    {
                        if (objectTarget.chunks[i] == null)
                        {
                            continue;
                        }
                        #region Mesh
                        if (objectTarget.chunks[i].mesh != null && !EditorCommon.IsMainAsset(objectTarget.chunks[i].mesh))
                        {
                            var path = folder + "/" + string.Format("{0}_{1}_mesh.asset", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName);
                            path = FileUtil.GetProjectRelativePath(path);
                            path = AssetDatabase.GenerateUniqueAssetPath(path);
                            AssetDatabase.CreateAsset(Mesh.Instantiate(objectTarget.chunks[i].mesh), path);
                            objectTarget.chunks[i].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                        }
                        #endregion

                        #region Material
                        if (objectTarget.chunks[i].materials != null)
                        {
                            for (int index = 0; index < objectTarget.chunks[i].materials.Count; index++)
                            {
                                if (objectTarget.chunks[i].materials[index] == null || EditorCommon.IsMainAsset(objectTarget.chunks[i].materials[index]))
                                {
                                    continue;
                                }
                                var path = folder + "/" + string.Format("{0}_{1}_mat{2}.mat", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName, index);
                                path = FileUtil.GetProjectRelativePath(path);
                                path = AssetDatabase.GenerateUniqueAssetPath(path);
                                AssetDatabase.CreateAsset(Material.Instantiate(objectTarget.chunks[i].materials[index]), path);
                                objectTarget.chunks[i].materials[index] = AssetDatabase.LoadAssetAtPath <Material>(path);
                            }
                        }
                        #endregion

                        #region Texture
                        if (objectTarget.chunks[i].atlasTexture != null && !EditorCommon.IsMainAsset(objectTarget.chunks[i].atlasTexture))
                        {
                            var path = folder + "/" + string.Format("{0}_{1}_tex.png", objectTarget.gameObject.name, objectTarget.chunks[i].chunkName);
                            path = EditorCommon.GenerateUniqueAssetFullPath(path);
                            File.WriteAllBytes(path, objectTarget.chunks[i].atlasTexture.EncodeToPNG());
                            path = FileUtil.GetProjectRelativePath(path);
                            AssetDatabase.ImportAsset(path);
                            objectCore.SetTextureImporterSetting(path, objectTarget.chunks[i].atlasTexture);
                            objectTarget.chunks[i].atlasTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
                        }
                        #endregion
                    }
                }
            }
            else
            {
                Assert.IsTrue(false);
            }

            objectCore.ReCreate();
            InternalEditorUtility.RepaintAllViews();
        }
        protected override void InspectorGUI()
        {
            base.InspectorGUI();

#if UNITY_2018_3_OR_NEWER
            {
                if (!baseCore.isPrefabEditable)
                {
                    EditorGUI.BeginDisabledGroup(true);
                }
            }
#endif

            InspectorGUI_Import();

            #region Object
            if (!string.IsNullOrEmpty(baseTarget.voxelFilePath))
            {
                //Object
                baseTarget.edit_objectFoldout = EditorGUILayout.Foldout(baseTarget.edit_objectFoldout, "Object", guiStyleFoldoutBold);
                if (baseTarget.edit_objectFoldout)
                {
                    EditorGUI.BeginDisabledGroup(isPrefab);

                    EditorGUILayout.BeginVertical(GUI.skin.box);
                    #region Mesh
                    if (baseTarget.advancedMode)
                    {
                        EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        InspectorGUI_Object_Mesh_Settings();
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    #region Material
                    {
                        EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region updateMeshRendererMaterials
                        if (baseTarget.advancedMode)
                        {
                            EditorGUI.BeginChangeCheck();
                            var updateMeshRendererMaterials = EditorGUILayout.ToggleLeft("Update the Mesh Renderer Materials", baseTarget.updateMeshRendererMaterials);
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (EditorUtility.DisplayDialog("Update the Mesh Renderer Materials", "It will be changed.\nAre you sure?", "ok", "cancel"))
                                {
                                    UndoRecordObject("Inspector");
                                    baseTarget.updateMeshRendererMaterials = updateMeshRendererMaterials;
                                    baseCore.SetRendererCompornent();
                                }
                            }
                        }
                        #endregion
                        #region Material Mode
                        if (baseTarget.advancedMode)
                        {
                            EditorGUI.BeginChangeCheck();
                            var materialMode = (VoxelChunksObject.MaterialMode)EditorGUILayout.EnumPopup("Material Mode", objectTarget.materialMode);
                            if (EditorGUI.EndChangeCheck())
                            {
                                UndoRecordObject("Inspector");
                                {
                                    var chunkObjects = objectTarget.chunks;
                                    if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
                                    {
                                        objectTarget.materials    = null;
                                        objectTarget.atlasTexture = null;
                                    }
                                    else if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Individual)
                                    {
                                        for (int i = 0; i < chunkObjects.Length; i++)
                                        {
                                            if (chunkObjects[i] == null)
                                            {
                                                continue;
                                            }
                                            chunkObjects[i].materials    = null;
                                            chunkObjects[i].atlasTexture = null;
                                        }
                                    }
                                }
                                objectTarget.materialMode = materialMode;
                                Refresh();
                            }
                        }
                        #endregion
                        if (materialList != null)
                        {
                            materialList.DoLayoutList();
                        }
                        InspectorGUI_ConfigureMaterial();
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    #region Texture
                    if (baseTarget.advancedMode)
                    {
                        EditorGUILayout.LabelField("Texture", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region updateMaterialTexture
                        {
                            EditorGUI.BeginChangeCheck();
                            var updateMaterialTexture = EditorGUILayout.ToggleLeft("Update the Material Texture", baseTarget.updateMaterialTexture);
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (EditorUtility.DisplayDialog("Update the Material Texture", "It will be changed.\nAre you sure?", "ok", "cancel"))
                                {
                                    UndoRecordObject("Inspector");
                                    baseTarget.updateMaterialTexture = updateMaterialTexture;
                                    baseCore.SetRendererCompornent();
                                }
                            }
                        }
                        #endregion
                        #region Texture
                        if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
                        {
                            EditorGUILayout.BeginHorizontal();
                            {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.ObjectField(objectTarget.atlasTexture, typeof(Texture2D), false);
                                EditorGUI.EndDisabledGroup();
                            }
                            if (objectTarget.atlasTexture != null)
                            {
                                if (!EditorCommon.IsMainAsset(objectTarget.atlasTexture))
                                {
                                    if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Create Texture
                                        string path = EditorUtility.SaveFilePanel("Save atlas texture", baseCore.GetDefaultPath(), string.Format("{0}_tex.png", baseTarget.gameObject.name), "png");
                                        if (!string.IsNullOrEmpty(path))
                                        {
                                            if (path.IndexOf(Application.dataPath) < 0)
                                            {
                                                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                            }
                                            else
                                            {
                                                UndoRecordObject("Save Atlas Texture");
                                                File.WriteAllBytes(path, objectTarget.atlasTexture.EncodeToPNG());
                                                path = FileUtil.GetProjectRelativePath(path);
                                                AssetDatabase.ImportAsset(path);
                                                objectCore.SetTextureImporterSetting(path, objectTarget.atlasTexture);
                                                objectTarget.atlasTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
                                                Refresh();
                                            }
                                        }
                                        #endregion
                                    }
                                }
                                {
                                    if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Reset Texture
                                        UndoRecordObject("Reset Atlas Texture");
                                        objectTarget.atlasTexture = null;
                                        Refresh();
                                        #endregion
                                    }
                                }
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                        #endregion
                        #region Generate Mip Maps
                        {
                            EditorGUI.BeginChangeCheck();
                            var generateMipMaps = EditorGUILayout.Toggle("Generate Mip Maps", baseTarget.generateMipMaps);
                            if (EditorGUI.EndChangeCheck())
                            {
                                UndoRecordObject("Inspector");
                                baseTarget.generateMipMaps = generateMipMaps;
                                Refresh();
                            }
                        }
                        #endregion
                        #region Texture Size
                        if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Combine)
                        {
                            EditorGUILayout.LabelField("Texture Size", objectTarget.atlasTexture != null ? string.Format("{0} x {1}", objectTarget.atlasTexture.width, objectTarget.atlasTexture.height) : "");
                        }
                        #endregion
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    EditorGUILayout.EndVertical();

                    EditorGUI.EndDisabledGroup();
                }
            }
            #endregion

            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.Space();
                if (GUILayout.Button("Reset All Chunks Transform"))
                {
                    for (int i = 0; i < objectTarget.chunks.Length; i++)
                    {
                        if (objectTarget.chunks[i] == null)
                        {
                            continue;
                        }
                        var t = objectTarget.chunks[i].transform;
                        Undo.RecordObject(t, "Reset All Chunks Transform");
                        t.localPosition = objectTarget.chunks[i].basicOffset;
                        t.localRotation = Quaternion.identity;
                        t.localScale    = Vector3.one;
                    }
                }
                EditorGUILayout.Space();
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.Space();

            {
                EditorGUILayout.BeginHorizontal();
                EditorGUI.BeginDisabledGroup(isPrefab);

                InspectorGUI_Refresh();

                #region Refresh all chunks
                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.")))
                {
                    UndoRecordObject("Inspector", true);
                    Refresh();
                }
                #endregion

                EditorGUI.EndDisabledGroup();
                EditorGUILayout.EndHorizontal();
            }

#if UNITY_2018_3_OR_NEWER
            {
                if (!baseCore.isPrefabEditable)
                {
                    EditorGUI.EndDisabledGroup();
                }
            }
#endif
        }
Beispiel #6
0
        private static void SaveAllUnsavedAssets(MenuCommand menuCommand)
        {
            var explosionObject = menuCommand.context as VoxelChunksObjectExplosion;

            if (explosionObject == null)
            {
                return;
            }

            var explosionCore = new VoxelChunksObjectExplosionCore(explosionObject);

            var folder = EditorUtility.OpenFolderPanel("Save all", explosionCore.voxelBaseCore.GetDefaultPath(), null);

            if (string.IsNullOrEmpty(folder))
            {
                return;
            }
            if (folder.IndexOf(Application.dataPath) < 0)
            {
                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                return;
            }

            Undo.RecordObject(explosionObject, "Save All Unsaved Assets");
            if (explosionObject.chunksExplosion != null)
            {
                Undo.RecordObjects(explosionObject.chunksExplosion, "Save All Unsaved Assets");
            }

            if (explosionObject.materialMode == VoxelChunksObject.MaterialMode.Combine)
            {
                if (explosionObject.chunksExplosion != null)
                {
                    for (int i = 0; i < explosionObject.chunksExplosion.Length; i++)
                    {
                        if (explosionObject.chunksExplosion[i] == null)
                        {
                            continue;
                        }
                        #region Mesh
                        for (int j = 0; j < explosionObject.chunksExplosion[i].meshes.Count; j++)
                        {
                            if (explosionObject.chunksExplosion[i].meshes[j] != null && explosionObject.chunksExplosion[i].meshes[j].mesh != null && !EditorCommon.IsMainAsset(explosionObject.chunksExplosion[i].meshes[j].mesh))
                            {
                                var chunkObject = explosionObject.chunksExplosion[i].GetComponent <VoxelChunksObjectChunk>();
                                if (chunkObject == null)
                                {
                                    continue;
                                }
                                var path = folder + "/" + string.Format("{0}_{1}_explosion_mesh{2}.asset", explosionObject.gameObject.name, chunkObject.chunkName, j);
                                path = FileUtil.GetProjectRelativePath(path);
                                AssetDatabase.CreateAsset(Mesh.Instantiate(explosionObject.chunksExplosion[i].meshes[j].mesh), path);
                                explosionObject.chunksExplosion[i].meshes[j].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                            }
                        }
                        #endregion
                    }
                }

                #region Material
                if (explosionObject.materials != null)
                {
                    for (int index = 0; index < explosionObject.materials.Count; index++)
                    {
                        if (explosionObject.materials[index] == null)
                        {
                            continue;
                        }
                        if (EditorCommon.IsMainAsset(explosionObject.materials[index]))
                        {
                            continue;
                        }
                        var path = folder + "/" + string.Format("{0}_explosion_mat{1}.mat", explosionObject.gameObject.name, index);
                        path = FileUtil.GetProjectRelativePath(path);
                        AssetDatabase.CreateAsset(Material.Instantiate(explosionObject.materials[index]), path);
                        explosionObject.materials[index] = AssetDatabase.LoadAssetAtPath <Material>(path);
                    }
                }
                #endregion
            }
            else if (explosionObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
            {
                if (explosionObject.chunksExplosion != null)
                {
                    for (int i = 0; i < explosionObject.chunksExplosion.Length; i++)
                    {
                        if (explosionObject.chunksExplosion[i] == null)
                        {
                            continue;
                        }
                        var chunkObject = explosionObject.chunksExplosion[i].GetComponent <VoxelChunksObjectChunk>();
                        if (chunkObject == null)
                        {
                            continue;
                        }
                        #region Mesh
                        for (int j = 0; j < explosionObject.chunksExplosion[i].meshes.Count; j++)
                        {
                            if (explosionObject.chunksExplosion[i].meshes[j] != null && explosionObject.chunksExplosion[i].meshes[j].mesh != null && !EditorCommon.IsMainAsset(explosionObject.chunksExplosion[i].meshes[j].mesh))
                            {
                                var path = folder + "/" + string.Format("{0}_{1}_explosion_mesh{2}.asset", explosionObject.gameObject.name, chunkObject.chunkName, j);
                                path = FileUtil.GetProjectRelativePath(path);
                                AssetDatabase.CreateAsset(Mesh.Instantiate(explosionObject.chunksExplosion[i].meshes[j].mesh), path);
                                explosionObject.chunksExplosion[i].meshes[j].mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                            }
                        }
                        #endregion

                        #region Material
                        if (explosionObject.chunksExplosion[i].materials != null)
                        {
                            for (int index = 0; index < explosionObject.chunksExplosion[i].materials.Count; index++)
                            {
                                if (explosionObject.chunksExplosion[i].materials[index] == null)
                                {
                                    continue;
                                }
                                if (EditorCommon.IsMainAsset(explosionObject.chunksExplosion[i].materials[index]))
                                {
                                    continue;
                                }
                                var path = folder + "/" + string.Format("{0}_{1}_explosion_mat{2}.mat", explosionObject.gameObject.name, chunkObject.chunkName, index);
                                path = FileUtil.GetProjectRelativePath(path);
                                AssetDatabase.CreateAsset(Material.Instantiate(explosionObject.chunksExplosion[i].materials[index]), path);
                                explosionObject.chunksExplosion[i].materials[index] = AssetDatabase.LoadAssetAtPath <Material>(path);
                            }
                        }
                        #endregion
                    }
                }
            }
            else
            {
                Assert.IsTrue(false);
            }

            explosionCore.Generate();
            InternalEditorUtility.RepaintAllViews();
        }
Beispiel #7
0
        public override void GenerateOnly()
        {
            if (voxelObject == null || voxelObjectCore.voxelData == null)
            {
                return;
            }
            var voxelData = voxelObjectCore.voxelData;

            //BasicCube
            Vector3        cubeCenter;
            List <Vector3> cubeVertices;
            List <Vector3> cubeNormals;
            List <int>     cubeTriangles;

            CreateBasicCube(out cubeCenter, out cubeVertices, out cubeNormals, out cubeTriangles);

            #region Voxels
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector3> normals   = new List <Vector3>();
            List <Color>   colors    = new List <Color>();
            List <Vector4> tangents  = new List <Vector4>();
            List <int>[]   triangles = new List <int> [voxelBase.materialData.Count];
            for (int i = 0; i < triangles.Length; i++)
            {
                triangles[i] = new List <int>();
            }

            #region Mesh
            Func <VoxelBaseExplosion.MeshData, VoxelBaseExplosion.MeshData> CreateMesh = (data) =>
            {
                if (data == null)
                {
                    data = new VoxelObjectExplosion.MeshData();
                }
                if (data.mesh == null)
                {
                    data.mesh = new Mesh();
                }
                else
                {
                    data.mesh.Clear(false);
                    data.mesh.ClearBlendShapes();
                }
                data.materialIndexes.Clear();
#if UNITY_2017_3_OR_NEWER
                data.mesh.indexFormat = vertices.Count > 65000 ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16;
#endif
                data.mesh.vertices = vertices.ToArray();
                data.mesh.normals  = normals.ToArray();
                data.mesh.colors   = colors.ToArray();
                data.mesh.tangents = tangents.ToArray();
                {
                    int materialCount = 0;
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        if (triangles[i].Count > 0)
                        {
                            materialCount++;
                        }
                    }
                    data.mesh.subMeshCount = materialCount;
                    int submesh = 0;
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        if (triangles[i].Count > 0)
                        {
                            data.materialIndexes.Add(i);
                            data.mesh.SetTriangles(triangles[i].ToArray(), submesh++);
                        }
                    }
                }
                data.mesh.RecalculateBounds();
                {
                    var bounds = data.mesh.bounds;
                    bounds.min      -= Vector3.one * explosionBase.edit_velocityMax;
                    bounds.max      += Vector3.one * explosionBase.edit_velocityMax;
                    data.mesh.bounds = bounds;
                }
                vertices.Clear();
                normals.Clear();
                colors.Clear();
                tangents.Clear();
                for (int i = 0; i < voxelBase.materialData.Count; i++)
                {
                    triangles[i].Clear();
                }
                return(data);
            };
            #endregion

            {
                var        chunkObjects = voxelObject.chunks;
                FlagTable3 doneTable    = new FlagTable3(voxelData.voxelSize.x, voxelData.voxelSize.y, voxelData.voxelSize.z);
                for (int chunkIndex = 0; chunkIndex < chunkObjects.Length; chunkIndex++)
                {
                    var chunkObject = chunkObjects[chunkIndex];
                    if (chunkObject == null)
                    {
                        explosionObject.chunksExplosion[chunkIndex] = null;
                        continue;
                    }
                    var explosionChunk = explosionObject.chunksExplosion[chunkIndex] = chunkObject.gameObject.GetComponent <VoxelChunksObjectChunkExplosion>();
                    if (explosionChunk == null)
                    {
                        explosionChunk = explosionObject.chunksExplosion[chunkIndex] = Undo.AddComponent <VoxelChunksObjectChunkExplosion>(chunkObject.gameObject);
                    }

                    int meshIndex = 0;
                    Action <int, int> AddVertex = (mat, index) =>
                    {
                        if (explosionBase.edit_birthRate < 1f)
                        {
                            if (UnityEngine.Random.value >= explosionBase.edit_birthRate)
                            {
                                return;
                            }
                        }
                        if (explosionBase.edit_visibleOnly)
                        {
                            if (!voxelObjectCore.IsVoxelVisible(voxelData.voxels[index].position))
                            {
                                return;
                            }
                        }

#if !UNITY_2017_3_OR_NEWER
                        if (vertices.Count + cubeVertices.Count >= 65000)
                        {
                            for (int i = explosionChunk.meshes.Count; i <= meshIndex; i++)
                            {
                                explosionChunk.meshes.Add(null);
                            }
                            explosionChunk.meshes[meshIndex] = CreateMesh(explosionChunk.meshes[meshIndex]);
                            if (!AssetDatabase.Contains(explosionChunk.meshes[meshIndex].mesh))
                            {
                                voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.meshes[meshIndex].mesh, string.Format("{0}_explosion_mesh", explosionChunk.name), meshIndex);
                            }
                            meshIndex++;
                        }
#endif

                        var velocity = UnityEngine.Random.Range(explosionBase.edit_velocityMin, explosionBase.edit_velocityMax);
                        var color    = voxelData.palettes[voxelData.voxels[index].palette];
#if UNITY_2018_1_OR_NEWER
                        if (EditorCommon.IsUniversalRenderPipeline() || EditorCommon.IsHighDefinitionRenderPipeline())
                        {
                            color.a = velocity;
                        }
#endif
                        var vOffset = vertices.Count;
                        for (int i = 0; i < cubeVertices.Count; i++)
                        {
                            var pos = cubeVertices[i];
                            pos.x += voxelData.voxels[index].position.x * voxelBase.importScale.x;
                            pos.y += voxelData.voxels[index].position.y * voxelBase.importScale.y;
                            pos.z += voxelData.voxels[index].position.z * voxelBase.importScale.z;
                            vertices.Add(pos);
                        }
                        normals.AddRange(cubeNormals);
                        for (int j = 0; j < cubeTriangles.Count; j++)
                        {
                            triangles[mat].Add(vOffset + cubeTriangles[j]);
                        }
                        for (int j = 0; j < cubeVertices.Count; j++)
                        {
                            colors.Add(color);
                        }
                        {
                            Vector3 center = new Vector3
                                             (
                                center.x = cubeCenter.x + voxelData.voxels[index].position.x * voxelBase.importScale.x,
                                center.y = cubeCenter.y + voxelData.voxels[index].position.y * voxelBase.importScale.y,
                                center.z = cubeCenter.z + voxelData.voxels[index].position.z * voxelBase.importScale.z
                                             );
                            for (int j = 0; j < cubeVertices.Count; j++)
                            {
                                tangents.Add(new Vector4(center.x - vertices[vOffset + j].x, center.y - vertices[vOffset + j].y, center.z - vertices[vOffset + j].z, velocity));
                            }
                        }
                    };

                    if (explosionChunk.meshes == null)
                    {
                        explosionChunk.meshes = new List <VoxelBaseExplosion.MeshData>();
                    }
                    for (int i = 1; i < voxelBase.materialData.Count; i++)
                    {
                        voxelBase.materialData[i].AllAction((pos) =>
                        {
                            if (doneTable.Get(pos))
                            {
                                return;
                            }
                            if (voxelData.chunkTable.Get(pos) != chunkObject.position)
                            {
                                return;
                            }
                            doneTable.Set(pos, true);
                            var index = voxelData.VoxelTableContains(pos);
                            if (index < 0)
                            {
                                return;
                            }
                            AddVertex(i, index);
                        });
                    }
                    for (int index = 0; index < voxelData.voxels.Length; index++)
                    {
                        var pos = voxelData.voxels[index].position;
                        if (doneTable.Get(pos))
                        {
                            continue;
                        }
                        if (voxelData.chunkTable.Get(pos) != chunkObject.position)
                        {
                            continue;
                        }
                        doneTable.Set(pos, true);
                        AddVertex(0, index);
                    }
                    if (vertices.Count > 0)
                    {
                        for (int i = explosionChunk.meshes.Count; i <= meshIndex; i++)
                        {
                            explosionChunk.meshes.Add(null);
                        }
                        explosionChunk.meshes[meshIndex] = CreateMesh(explosionChunk.meshes[meshIndex]);
                        if (!AssetDatabase.Contains(explosionChunk.meshes[meshIndex].mesh))
                        {
                            voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.meshes[meshIndex].mesh, string.Format("{0}_explosion_mesh", explosionChunk.name), meshIndex);
                        }
                        meshIndex++;
                    }
                    explosionChunk.meshes.RemoveRange(meshIndex, explosionChunk.meshes.Count - meshIndex);

                    explosionChunk.chunkBasicOffset = chunkObject.basicOffset;
                }
            }
            #endregion

            #region Material
            explosionObject.materialMode = voxelObject.materialMode;
            if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine)
            {
                if (explosionObject.materials == null)
                {
                    explosionObject.materials = new List <Material>();
                }
                if (explosionObject.materials.Count < voxelBase.materialData.Count)
                {
                    for (int i = explosionObject.materials.Count; i < voxelBase.materialData.Count; i++)
                    {
                        explosionObject.materials.Add(null);
                    }
                }
                else if (explosionObject.materials.Count > voxelBase.materialData.Count)
                {
                    explosionObject.materials.RemoveRange(voxelBase.materialData.Count, explosionObject.materials.Count - voxelBase.materialData.Count);
                }
                for (int i = 0; i < explosionObject.chunksExplosion.Length; i++)
                {
                    explosionObject.chunksExplosion[i].materials = null;
                }
                for (int i = 0; i < voxelBase.materialData.Count; i++)
                {
                    if (!voxelBase.materialIndexes.Contains(i))
                    {
                        if (explosionObject.materials[i] != null)
                        {
                            explosionObject.materials[i] = null;
                            voxelBaseCore.DestroyUnusedObjectInPrefabObject();
                        }
                        continue;
                    }
                    if (explosionObject.materials[i] == null)
                    {
                        explosionObject.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent));
                    }
                    else
                    {
                        explosionObject.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent);
                    }
                    if (!AssetDatabase.Contains(explosionObject.materials[i]))
                    {
                        explosionObject.materials[i].name = explosionObject.materials[i].shader.name;
                    }
                    if (!AssetDatabase.Contains(explosionObject.materials[i]))
                    {
                        voxelBaseCore.AddObjectToPrefabAsset(explosionObject.materials[i], "explosion_mat", i);
                    }
                }
            }
            else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
            {
                explosionObject.materials = null;
                for (int chunkIndex = 0; chunkIndex < explosionObject.chunksExplosion.Length; chunkIndex++)
                {
                    var explosionChunk = explosionObject.chunksExplosion[chunkIndex];
                    if (explosionChunk.materials == null)
                    {
                        explosionChunk.materials = new List <Material>();
                    }
                    if (explosionChunk.materials.Count < voxelBase.materialData.Count)
                    {
                        for (int i = explosionChunk.materials.Count; i < voxelBase.materialData.Count; i++)
                        {
                            explosionChunk.materials.Add(null);
                        }
                    }
                    else if (explosionChunk.materials.Count > voxelBase.materialData.Count)
                    {
                        explosionChunk.materials.RemoveRange(voxelBase.materialData.Count, explosionChunk.materials.Count - voxelBase.materialData.Count);
                    }
                    for (int i = 0; i < voxelBase.materialData.Count; i++)
                    {
                        if (!voxelObject.chunks[chunkIndex].materialIndexes.Contains(i))
                        {
                            if (explosionChunk.materials[i] != null)
                            {
                                explosionChunk.materials[i] = null;
                                voxelBaseCore.DestroyUnusedObjectInPrefabObject();
                            }
                            continue;
                        }
                        if (explosionChunk.materials[i] == null)
                        {
                            explosionChunk.materials[i] = new Material(GetStandardShader(voxelBase.materialData[i].transparent));
                        }
                        else
                        {
                            explosionChunk.materials[i].shader = GetStandardShader(voxelBase.materialData[i].transparent);
                        }
                        if (!AssetDatabase.Contains(explosionChunk.materials[i]))
                        {
                            explosionChunk.materials[i].name = explosionChunk.materials[i].shader.name;
                        }
                        if (!AssetDatabase.Contains(explosionChunk.materials[i]))
                        {
                            voxelBaseCore.AddObjectToPrefabAsset(explosionChunk.materials[i], string.Format("{0}_explosion_mat", explosionChunk.name), i);
                        }
                    }
                }
            }
            else
            {
                Assert.IsTrue(false);
            }
            #endregion
        }
        protected void InspectorGUI()
        {
            #region Simple
            {
                EditorGUI.BeginChangeCheck();
                var mode = GUILayout.Toolbar(objectTarget.advancedMode ? 1 : 0, VoxelBaseEditor.Edit_AdvancedModeStrings);
                if (EditorGUI.EndChangeCheck())
                {
                    objectTarget.advancedMode = mode != 0 ? true : false;
                }
            }
            #endregion

            EditorGUILayout.Space();

            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.Space();
                if (GUILayout.Button("Reset Transform"))
                {
                    Undo.RecordObject(chunkTarget.transform, "Reset Chunk Transform");
                    chunkTarget.transform.localPosition = chunkTarget.basicOffset;
                    chunkTarget.transform.localRotation = Quaternion.identity;
                    chunkTarget.transform.localScale    = Vector3.one;
                }
                EditorGUILayout.Space();
                EditorGUILayout.EndHorizontal();
            }

            #region Object
            if (objectTarget.advancedMode)
            {
                chunkTarget.edit_objectFoldout = EditorGUILayout.Foldout(chunkTarget.edit_objectFoldout, "Object", guiStyleFoldoutBold);
                if (chunkTarget.edit_objectFoldout)
                {
                    EditorGUILayout.BeginVertical(GUI.skin.box);
                    #region Mesh
                    {
                        EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region Mesh
                        {
                            EditorGUILayout.BeginHorizontal();
                            {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.ObjectField(chunkTarget.mesh, typeof(Mesh), false);
                                EditorGUI.EndDisabledGroup();
                            }
                            if (chunkTarget.mesh != null)
                            {
                                if (!EditorCommon.IsMainAsset(chunkTarget.mesh))
                                {
                                    if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Create Mesh
                                        string path = EditorUtility.SaveFilePanel("Save mesh", chunkCore.GetDefaultPath(), string.Format("{0}_{1}_mesh.asset", objectTarget.gameObject.name, chunkTarget.chunkName), "asset");
                                        if (!string.IsNullOrEmpty(path))
                                        {
                                            if (path.IndexOf(Application.dataPath) < 0)
                                            {
                                                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                            }
                                            else
                                            {
                                                Undo.RecordObject(objectTarget, "Save Mesh");
                                                Undo.RecordObject(chunkTarget, "Save Mesh");
                                                path = FileUtil.GetProjectRelativePath(path);
                                                AssetDatabase.CreateAsset(Mesh.Instantiate(chunkTarget.mesh), path);
                                                chunkTarget.mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                                                Refresh();
                                            }
                                        }
                                        #endregion
                                    }
                                }
                                {
                                    if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Reset Mesh
                                        Undo.RecordObject(objectTarget, "Reset Mesh");
                                        Undo.RecordObject(chunkTarget, "Reset Mesh");
                                        chunkTarget.mesh = null;
                                        Refresh();
                                        #endregion
                                    }
                                }
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                        #endregion
                        #region Vertex Count
                        {
                            EditorGUILayout.LabelField("Vertex Count", chunkTarget.mesh != null ? chunkTarget.mesh.vertexCount.ToString() : "");
                        }
                        #endregion
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    #region Material
                    if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region Material
                        for (int i = 0; i < chunkTarget.materials.Count; i++)
                        {
                            EditorGUILayout.BeginHorizontal();
                            {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.ObjectField(chunkTarget.materials[i], typeof(Material), false);
                                EditorGUI.EndDisabledGroup();
                            }
                            if (chunkTarget.materials[i] != null)
                            {
                                if (!EditorCommon.IsMainAsset(chunkTarget.materials[i]))
                                {
                                    if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Create Material
                                        string defaultName = string.Format("{0}_{1}_mat{2}.mat", objectTarget.gameObject.name, chunkTarget.chunkName, i);
                                        string path        = EditorUtility.SaveFilePanel("Save material", chunkCore.GetDefaultPath(), defaultName, "mat");
                                        if (!string.IsNullOrEmpty(path))
                                        {
                                            if (path.IndexOf(Application.dataPath) < 0)
                                            {
                                                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                            }
                                            else
                                            {
                                                Undo.RecordObject(objectTarget, "Save Material");
                                                Undo.RecordObject(chunkTarget, "Save Material");
                                                path = FileUtil.GetProjectRelativePath(path);
                                                AssetDatabase.CreateAsset(Material.Instantiate(chunkTarget.materials[i]), path);
                                                chunkTarget.materials[i] = AssetDatabase.LoadAssetAtPath <Material>(path);
                                                Refresh();
                                            }
                                        }

                                        #endregion
                                    }
                                }
                                {
                                    if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Reset Material
                                        Undo.RecordObject(objectTarget, "Reset Material");
                                        Undo.RecordObject(chunkTarget, "Reset Material");
                                        chunkTarget.materials[i] = EditorCommon.Instantiate(chunkTarget.materials[i]);
                                        Refresh();
                                        #endregion
                                    }
                                }
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                        #endregion
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    #region Texture
                    if (objectTarget.materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        EditorGUILayout.LabelField("Texture", EditorStyles.boldLabel);
                        EditorGUI.indentLevel++;
                        #region Texture
                        {
                            EditorGUILayout.BeginHorizontal();
                            {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.ObjectField(chunkTarget.atlasTexture, typeof(Texture2D), false);
                                EditorGUI.EndDisabledGroup();
                            }
                            if (chunkTarget.atlasTexture != null)
                            {
                                if (!EditorCommon.IsMainAsset(chunkTarget.atlasTexture))
                                {
                                    if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Create Texture
                                        string defaultName = string.Format("{0}_{1}_tex.png", objectTarget.gameObject.name, chunkTarget.chunkName);
                                        string path        = EditorUtility.SaveFilePanel("Save atlas texture", chunkCore.GetDefaultPath(), defaultName, "png");
                                        if (!string.IsNullOrEmpty(path))
                                        {
                                            if (path.IndexOf(Application.dataPath) < 0)
                                            {
                                                EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                            }
                                            else
                                            {
                                                Undo.RecordObject(objectTarget, "Save Atlas Texture");
                                                Undo.RecordObject(chunkTarget, "Save Atlas Texture");
                                                File.WriteAllBytes(path, chunkTarget.atlasTexture.EncodeToPNG());
                                                path = FileUtil.GetProjectRelativePath(path);
                                                AssetDatabase.ImportAsset(path);
                                                objectCore.SetTextureImporterSetting(path, chunkTarget.atlasTexture);
                                                chunkTarget.atlasTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
                                                Refresh();
                                            }
                                        }
                                        #endregion
                                    }
                                }
                                {
                                    if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                                    {
                                        #region Reset Texture
                                        Undo.RecordObject(objectTarget, "Reset Atlas Texture");
                                        Undo.RecordObject(chunkTarget, "Reset Atlas Texture");
                                        chunkTarget.atlasTexture = null;
                                        Refresh();
                                        #endregion
                                    }
                                }
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                        #endregion
                        #region Texture Size
                        {
                            EditorGUILayout.LabelField("Texture Size", chunkTarget.atlasTexture != null ? string.Format("{0} x {1}", chunkTarget.atlasTexture.width, chunkTarget.atlasTexture.height) : "");
                        }
                        #endregion
                        EditorGUI.indentLevel--;
                    }
                    #endregion
                    EditorGUILayout.EndVertical();
                }
            }
            else
            {
                EditorGUILayout.Space();
            }
            #endregion

            #region Refresh
            if (GUILayout.Button("Refresh"))
            {
                Undo.RecordObject(objectTarget, "Inspector");
                Undo.RecordObject(chunkTarget, "Inspector");
                Refresh();
            }
            #endregion
        }
        protected override bool CreateMesh()
        {
            base.CreateMesh();

            #region ProgressBar
            const float     MaxProgressCount   = 14f;
            float           ProgressCount      = 0;
            Action <string> DisplayProgressBar = (info) =>
            {
                if (voxelData.voxels.Length > 10000)
                {
                    EditorUtility.DisplayProgressBar("Create Mesh...", string.Format("{0} / {1}", ProgressCount, MaxProgressCount), (ProgressCount++ / MaxProgressCount));
                }
            };
            #endregion

            DisplayProgressBar("");

            {
                bool reloadVoxelData = false;
                foreach (var frame in voxelObject.frames)
                {
                    if (frame.disableData != null &&
                        frame.disableData.Count > 0)
                    {
                        reloadVoxelData = true;
                        break;
                    }
                    if (frame.materialData != null)
                    {
                        foreach (var material in frame.materialData)
                        {
                            if (material != null && material.Count > 0)
                            {
                                reloadVoxelData = true;
                                break;
                            }
                        }
                        if (reloadVoxelData)
                        {
                            break;
                        }
                    }
                }
                if (reloadVoxelData)
                {
                    ReadyIndividualVoxelData();
                }
            };

            DisplayProgressBar("");

            #region Combine VoxelData
            {
                voxelBase.voxelData            = new VoxelData();
                voxelBase.voxelData.chunkTable = new DataTable3 <IntVector3>(voxelBase.voxelData.voxelSize.x, voxelBase.voxelData.voxelSize.y, voxelBase.voxelData.voxelSize.z);

                chunkDataList = new List <ChunkData>(voxelObject.frames.Count);
                int totalVoxelCount = 0;
                {
                    for (int i = 0; i < voxelObject.frames.Count; i++)
                    {
                        totalVoxelCount += voxelObject.frames[i].voxelData.voxels.Length;
                    }
                }
                var        voxels    = new VoxelData.Voxel[totalVoxelCount];
                IntVector3 voxelSize = IntVector3.zero;
                Dictionary <Color, int> paletteTable = new Dictionary <Color, int>();
                {
                    int offset = 0;
                    int index  = 0;
                    for (int i = 0; i < voxelObject.frames.Count; i++)
                    {
                        var voxelData = voxelObject.frames[i].voxelData;
                        chunkDataList.Add(new ChunkData());
                        chunkDataList[i].voxelBegin = index;
                        for (int j = 0; j < voxelData.voxels.Length; j++)
                        {
                            var voxel = voxelData.voxels[j];
                            var color = voxelData.palettes[voxel.palette];
                            if (!paletteTable.ContainsKey(color))
                            {
                                paletteTable.Add(color, paletteTable.Count);
                            }
                            voxel.palette   = paletteTable[color];
                            voxel.z        += offset;
                            voxels[index++] = voxel;
                            voxelBase.voxelData.chunkTable.Set(voxel.position, new IntVector3(i, 0, 0));
                        }
                        chunkDataList[i].voxelEnd = index;
                        chunkDataList[i].area     = new VoxelData.ChunkArea()
                        {
                            min = new IntVector3(0, 0, offset), max = new IntVector3(voxelData.voxelSize.x, voxelData.voxelSize.y, offset + voxelData.voxelSize.z)
                        };
                        voxelSize = IntVector3.Max(voxelSize, new IntVector3(voxelData.voxelSize.x, voxelData.voxelSize.y, offset + voxelData.voxelSize.z));
                        offset   += voxelData.voxelSize.z + 1;
                    }
                }
                #region Create
                voxelBase.localOffset = Vector3.zero;

                voxelBase.fileType = VoxelBase.FileType.vox;

                voxelBase.voxelData.voxels   = voxels;
                voxelBase.voxelData.palettes = new Color[paletteTable.Count];
                foreach (var pair in paletteTable)
                {
                    voxelBase.voxelData.palettes[pair.Value] = pair.Key;
                }
                voxelBase.voxelData.voxelSize = voxelSize;

                base.CreateVoxelTable();
                base.UpdateVisibleFlags();
                #endregion
            }
            #endregion

            DisplayProgressBar("");

            #region Combine DisableData
            {
                #region Erase
                for (int i = 0; i < voxelObject.frames.Count; i++)
                {
                    if (voxelObject.frames[i].disableData == null)
                    {
                        continue;
                    }

                    List <IntVector3> removeList = new List <IntVector3>();
                    voxelObject.frames[i].disableData.AllAction((pos, face) =>
                    {
                        if (voxelObject.frames[i].voxelData.VoxelTableContains(pos) < 0)
                        {
                            removeList.Add(pos);
                        }
                    });
                    for (int k = 0; k < removeList.Count; k++)
                    {
                        voxelObject.frames[i].disableData.RemoveDisable(removeList[k]);
                    }
                }
                #endregion
                for (int i = 0; i < voxelObject.frames.Count; i++)
                {
                    if (voxelObject.frames[i].disableData == null)
                    {
                        voxelObject.frames[i].disableData = new DisableData();
                    }
                }
                {
                    voxelObject.disableData = new DisableData();
                    for (int j = 0; j < voxelObject.frames.Count; j++)
                    {
                        if (voxelObject.frames[j].disableData == null)
                        {
                            continue;
                        }
                        voxelObject.frames[j].disableData.AllAction((pos, face) =>
                        {
                            voxelObject.disableData.SetDisable(chunkDataList[j].area.min + pos, face);
                        });
                    }
                }
            }
            #endregion

            DisplayProgressBar("");

            #region Combine MaterialData
            {
                #region Erase
                for (int i = 0; i < voxelObject.frames.Count; i++)
                {
                    if (voxelObject.frames[i].materialData == null)
                    {
                        continue;
                    }
                    for (int j = 0; j < voxelObject.frames[i].materialData.Count; j++)
                    {
                        List <IntVector3> removeList = new List <IntVector3>();
                        voxelObject.frames[i].materialData[j].AllAction((pos) =>
                        {
                            if (voxelObject.frames[i].voxelData.VoxelTableContains(pos) < 0)
                            {
                                removeList.Add(pos);
                            }
                        });
                        for (int k = 0; k < removeList.Count; k++)
                        {
                            voxelObject.frames[i].materialData[j].RemoveMaterial(removeList[k]);
                        }
                    }
                }
                #endregion
                voxelObject.materialData = new List <MaterialData>();
                int materialCount = 1;
                for (int i = 0; i < voxelObject.frames.Count; i++)
                {
                    if (voxelObject.frames[i].materialData != null)
                    {
                        materialCount = Math.Max(materialCount, voxelObject.frames[i].materialData.Count);
                    }
                }
                for (int i = 0; i < voxelObject.frames.Count; i++)
                {
                    if (voxelObject.frames[i].materialData == null)
                    {
                        voxelObject.frames[i].materialData = new List <MaterialData>();
                    }
                    for (int j = voxelObject.frames[i].materialData.Count; j < materialCount; j++)
                    {
                        voxelObject.frames[i].materialData.Add(new MaterialData());
                    }
                }
                for (int i = 0; i < materialCount; i++)
                {
                    voxelObject.materialData.Add(new MaterialData());
                    voxelObject.materialData[i].name        = voxelObject.frames[0].materialData[i].name;
                    voxelObject.materialData[i].transparent = voxelObject.frames[0].materialData[i].transparent;
                    voxelObject.materialData[i].material    = voxelObject.frames[0].materialData[i].material;
                    for (int j = 0; j < voxelObject.frames.Count; j++)
                    {
                        if (voxelObject.frames[j].materialData[i] == null)
                        {
                            continue;
                        }
                        voxelObject.frames[j].materialData[i].AllAction((pos) =>
                        {
                            voxelObject.materialData[i].SetMaterial(chunkDataList[j].area.min + pos);
                        });
                    }
                }
            }
            #endregion

            DisplayProgressBar("");

            #region Material
            {
                if (voxelBase.materialData == null)
                {
                    voxelBase.materialData = new List <MaterialData>();
                }
                if (voxelBase.materialData.Count == 0)
                {
                    voxelBase.materialData.Add(null);
                }
                for (int i = 0; i < voxelBase.materialData.Count; i++)
                {
                    if (voxelBase.materialData[i] == null)
                    {
                        voxelBase.materialData[i] = new MaterialData();
                    }
                }
                if (voxelObject.materials == null)
                {
                    voxelObject.materials = new List <Material>();
                }
                if (voxelObject.materials.Count < voxelObject.materialData.Count)
                {
                    for (int i = voxelObject.materials.Count; i < voxelObject.materialData.Count; i++)
                    {
                        voxelObject.materials.Add(null);
                    }
                }
                else if (voxelObject.materials.Count > voxelObject.materialData.Count)
                {
                    voxelObject.materials.RemoveRange(voxelObject.materialData.Count, voxelObject.materials.Count - voxelObject.materialData.Count);
                }
            }
            voxelBase.CreateMaterialIndexTable();
            #endregion

            DisplayProgressBar("");

            CalcDataCreate(voxelBase.voxelData.voxels);

            DisplayProgressBar("");

            #region CreateFaceAreaTable
            {
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    VoxelData.Voxel[] voxels = new VoxelData.Voxel[chunkDataList[i].voxelEnd - chunkDataList[i].voxelBegin];
                    Array.Copy(voxelBase.voxelData.voxels, chunkDataList[i].voxelBegin, voxels, 0, voxels.Length);
                    chunkDataList[i].faceAreaTable = CreateFaceArea(voxels);
                }
            }
            #endregion

            DisplayProgressBar("");

            #region CreateTexture
            {
                var tmpFaceAreaTable = new VoxelData.FaceAreaTable();
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    tmpFaceAreaTable.Merge(chunkDataList[i].faceAreaTable);
                }
                {
                    var atlasTextureTmp = voxelObject.atlasTexture;
                    if (!CreateTexture(tmpFaceAreaTable, voxelBase.voxelData.palettes, ref atlasRectTable, ref atlasTextureTmp, ref atlasRects))
                    {
                        EditorUtility.ClearProgressBar();
                        return(false);
                    }
                    voxelObject.atlasTexture = atlasTextureTmp;
                    if (!AssetDatabase.Contains(voxelObject.atlasTexture))
                    {
                        AddObjectToPrefabAsset(voxelObject.atlasTexture, "tex");
                    }
                }
            }
            #endregion

            DisplayProgressBar("");

            #region CreateMesh
            DisplayProgressBar("");
            if (voxelObject.importMode == VoxelBase.ImportMode.LowPoly)
            {
                int forward = 0;
                int up      = 0;
                int right   = 0;
                int left    = 0;
                int down    = 0;
                int back    = 0;
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    AtlasRectTable atlasRectTableTmp = new AtlasRectTable();
                    {
                        atlasRectTableTmp.forward = atlasRectTable.forward.GetRange(forward, chunkDataList[i].faceAreaTable.forward.Count);
                        forward += chunkDataList[i].faceAreaTable.forward.Count;
                        atlasRectTableTmp.up = atlasRectTable.up.GetRange(up, chunkDataList[i].faceAreaTable.up.Count);
                        up += chunkDataList[i].faceAreaTable.up.Count;
                        atlasRectTableTmp.right = atlasRectTable.right.GetRange(right, chunkDataList[i].faceAreaTable.right.Count);
                        right += chunkDataList[i].faceAreaTable.right.Count;
                        atlasRectTableTmp.left = atlasRectTable.left.GetRange(left, chunkDataList[i].faceAreaTable.left.Count);
                        left += chunkDataList[i].faceAreaTable.left.Count;
                        atlasRectTableTmp.down = atlasRectTable.down.GetRange(down, chunkDataList[i].faceAreaTable.down.Count);
                        down += chunkDataList[i].faceAreaTable.down.Count;
                        atlasRectTableTmp.back = atlasRectTable.back.GetRange(back, chunkDataList[i].faceAreaTable.back.Count);
                        back += chunkDataList[i].faceAreaTable.back.Count;
                    }
                    var extraOffset = new Vector3(0, 0f, -chunkDataList[i].area.min.z);
                    voxelBase.localOffset      = voxelObject.frames[i].localOffset;
                    voxelObject.frames[i].mesh = CreateMeshOnly(voxelObject.frames[i].mesh, chunkDataList[i].faceAreaTable, voxelObject.atlasTexture, atlasRects, atlasRectTableTmp, extraOffset, out voxelObject.frames[i].materialIndexes);
                }
            }
            else
            {
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    var extraOffset = new Vector3(0, 0f, -chunkDataList[i].area.min.z);
                    voxelBase.localOffset      = voxelObject.frames[i].localOffset;
                    voxelObject.frames[i].mesh = CreateMeshOnly(voxelObject.frames[i].mesh, chunkDataList[i].faceAreaTable, voxelObject.atlasTexture, atlasRects, atlasRectTable, extraOffset, out voxelObject.frames[i].materialIndexes);
                }
            }
            {
                HashSet <int> combineMaterialIndexes = new HashSet <int>();
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    foreach (var index in voxelObject.frames[i].materialIndexes)
                    {
                        combineMaterialIndexes.Add(index);
                    }
                }
                voxelObject.materialIndexes = combineMaterialIndexes.ToList();
            }
            #endregion

            DisplayProgressBar("");

            #region CreateMaterial
            {
                if (voxelObject.materialData == null)
                {
                    voxelObject.materialData = new List <MaterialData>();
                }
                if (voxelObject.materialData.Count == 0)
                {
                    voxelObject.materialData.Add(null);
                }
                for (int i = 0; i < voxelObject.materialData.Count; i++)
                {
                    if (voxelObject.materialData[i] == null)
                    {
                        voxelObject.materialData[i] = new MaterialData();
                    }
                }
                if (voxelObject.materials == null)
                {
                    voxelObject.materials = new List <Material>();
                }
                if (voxelObject.materials.Count < voxelObject.materialData.Count)
                {
                    for (int i = voxelObject.materials.Count; i < voxelObject.materialData.Count; i++)
                    {
                        voxelObject.materials.Add(null);
                    }
                }
                else if (voxelObject.materials.Count > voxelObject.materialData.Count)
                {
                    voxelObject.materials.RemoveRange(voxelObject.materialData.Count, voxelObject.materials.Count - voxelObject.materialData.Count);
                }

                for (int i = 0; i < voxelObject.materials.Count; i++)
                {
                    if (!voxelObject.materialIndexes.Contains(i))
                    {
                        if (voxelObject.materials[i] != null)
                        {
                            voxelObject.materials[i] = null;
                            DestroyUnusedObjectInPrefabObject();
                        }
                        continue;
                    }
                    if (voxelObject.materials[i] == null)
                    {
                        voxelObject.materials[i] = EditorCommon.CreateStandardMaterial();
                    }
                    if (!AssetDatabase.Contains(voxelObject.materials[i]))
                    {
                        AddObjectToPrefabAsset(voxelObject.materials[i], "mat", i);
                    }
                }
            }
            #endregion

            DisplayProgressBar("");
            {
                if (voxelBase.generateLightmapUVs)
                {
                    var param = voxelBase.GetLightmapParam();
                    for (int i = 0; i < chunkDataList.Count; i++)
                    {
                        if (voxelObject.frames[i].mesh.uv.Length > 0)
                        {
                            Unwrapping.GenerateSecondaryUVSet(voxelObject.frames[i].mesh, param);
                        }
                    }
                }
                if (voxelBase.generateTangents)
                {
                    for (int i = 0; i < chunkDataList.Count; i++)
                    {
                        voxelObject.frames[i].mesh.RecalculateTangents();
                    }
                }
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    if (!AssetDatabase.Contains(voxelObject.frames[i].mesh))
                    {
                        AddObjectToPrefabAsset(voxelObject.frames[i].mesh, string.Format("mesh_{0}", voxelObject.frames[i].name));
                    }
                }
            }

            DisplayProgressBar("");

            SetRendererCompornent();

            RefreshCheckerSave();

            EditorUtility.ClearProgressBar();

            voxelObject.Edit_SetFrameCurrentVoxelOtherData();

            return(true);
        }
 protected virtual void InspectorGUI_Object_Mesh()
 {
     #region Mesh
     if (baseTarget.advancedMode)
     {
         EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
         EditorGUI.indentLevel++;
         #region Mesh
         {
             EditorGUILayout.BeginHorizontal();
             {
                 EditorGUI.BeginDisabledGroup(true);
                 EditorGUILayout.ObjectField(mesh, typeof(Mesh), false);
                 EditorGUI.EndDisabledGroup();
             }
             if (mesh != null)
             {
                 if (!EditorCommon.IsMainAsset(mesh))
                 {
                     if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                     {
                         #region Create Mesh
                         string path = EditorUtility.SaveFilePanel("Save mesh", objectCore.GetDefaultPath(), string.Format("{0}_mesh.asset", baseTarget.gameObject.name), "asset");
                         if (!string.IsNullOrEmpty(path))
                         {
                             if (path.IndexOf(Application.dataPath) < 0)
                             {
                                 EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                             }
                             else
                             {
                                 UndoRecordObject("Save Mesh");
                                 path = FileUtil.GetProjectRelativePath(path);
                                 AssetDatabase.CreateAsset(Mesh.Instantiate(mesh), path);
                                 mesh = AssetDatabase.LoadAssetAtPath <Mesh>(path);
                                 Refresh();
                             }
                         }
                         #endregion
                     }
                 }
                 {
                     if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                     {
                         #region Reset Mesh
                         UndoRecordObject("Reset Mesh");
                         mesh = null;
                         Refresh();
                         #endregion
                     }
                 }
             }
             EditorGUILayout.EndHorizontal();
         }
         #endregion
         InspectorGUI_Object_Mesh_Settings();
         #region Vertex Count
         {
             EditorGUILayout.LabelField("Vertex Count", mesh != null ? mesh.vertexCount.ToString() : "");
         }
         #endregion
         EditorGUI.indentLevel--;
     }
     #endregion
 }
 protected virtual void InspectorGUI_Object_Texture()
 {
     #region Texture
     if (baseTarget.advancedMode)
     {
         EditorGUILayout.LabelField("Texture", EditorStyles.boldLabel);
         EditorGUI.indentLevel++;
         #region updateMaterialTexture
         {
             EditorGUI.BeginChangeCheck();
             var updateMaterialTexture = EditorGUILayout.ToggleLeft("Update the Material Texture", baseTarget.updateMaterialTexture);
             if (EditorGUI.EndChangeCheck())
             {
                 if (EditorUtility.DisplayDialog("Update the Material Texture", "It will be changed.\nAre you sure?", "ok", "cancel"))
                 {
                     UndoRecordObject("Inspector");
                     baseTarget.updateMaterialTexture = updateMaterialTexture;
                     baseCore.SetRendererCompornent();
                 }
             }
         }
         #endregion
         #region Texture
         {
             EditorGUILayout.BeginHorizontal();
             {
                 EditorGUI.BeginDisabledGroup(true);
                 EditorGUILayout.ObjectField(atlasTexture, typeof(Texture2D), false);
                 EditorGUI.EndDisabledGroup();
             }
             if (atlasTexture != null)
             {
                 if (!EditorCommon.IsMainAsset(atlasTexture))
                 {
                     if (GUILayout.Button("Save", GUILayout.Width(48), GUILayout.Height(16)))
                     {
                         #region Create Texture
                         string path = EditorUtility.SaveFilePanel("Save atlas texture", objectCore.GetDefaultPath(), string.Format("{0}_tex.png", baseTarget.gameObject.name), "png");
                         if (!string.IsNullOrEmpty(path))
                         {
                             if (path.IndexOf(Application.dataPath) < 0)
                             {
                                 EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                             }
                             else
                             {
                                 UndoRecordObject("Save Atlas Texture");
                                 var newTex = Texture2D.Instantiate(atlasTexture);
                                 File.WriteAllBytes(path, newTex.EncodeToPNG());
                                 path = FileUtil.GetProjectRelativePath(path);
                                 AssetDatabase.ImportAsset(path);
                                 objectCore.SetTextureImporterSetting(path, newTex);
                                 atlasTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
                                 Refresh();
                             }
                         }
                         #endregion
                     }
                 }
                 {
                     if (GUILayout.Button("Reset", GUILayout.Width(48), GUILayout.Height(16)))
                     {
                         #region Reset Texture
                         UndoRecordObject("Reset Atlas Texture");
                         atlasTexture = null;
                         Refresh();
                         #endregion
                     }
                 }
             }
             EditorGUILayout.EndHorizontal();
         }
         #endregion
         #region Generate Mip Maps
         if (!EditorCommon.IsMainAsset(atlasTexture))
         {
             EditorGUI.BeginChangeCheck();
             var generateMipMaps = EditorGUILayout.Toggle("Generate Mip Maps", baseTarget.generateMipMaps);
             if (EditorGUI.EndChangeCheck())
             {
                 UndoRecordObject("Inspector");
                 baseTarget.generateMipMaps = generateMipMaps;
                 Refresh();
             }
         }
         #endregion
         #region Texture Size
         {
             EditorGUILayout.LabelField("Texture Size", atlasTexture != null ? string.Format("{0} x {1}", atlasTexture.width, atlasTexture.height) : "");
         }
         #endregion
         EditorGUI.indentLevel--;
     }
     #endregion
 }
        public override void OnInspectorGUI()
        {
            var vtarget = target as VoxelScriptedImporter;

            if (vtarget == null)
            {
                base.OnInspectorGUI();
                return;
            }

            GUIStyleReady();

            SerializedObjectUpdate();

            #region Simple
            {
                EditorGUI.BeginChangeCheck();
                var mode = GUILayout.Toolbar(advancedMode ? 1 : 0, VoxelBaseEditor.Edit_AdvancedModeStrings);
                if (EditorGUI.EndChangeCheck())
                {
                    advancedMode = mode != 0 ? true : false;
                }
            }
            #endregion

            #region Settings
            {
                EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.IntPopup(meshModeProp, MeshModeStrings, MeshModeValues, new GUIContent("Mesh Mode", "Integrate into one mesh, or select split into multiple meshes"));
#if UNITY_2017_3 || UNITY_2017_4
                    if ((VoxelScriptedImporter.MeshMode)meshModeProp.intValue == VoxelScriptedImporter.MeshMode.Individual)
                    {
                        EditorGUILayout.HelpBox("In environments where bugs fixed in Unity 2018.1 or later are not supported, a lot of warnings and errors occur.\nWe recommend using Unity 2018.1 or later.", MessageType.Warning);
                    }
#endif
                    if (advancedMode)
                    {
                        EditorGUILayout.IntPopup(importModeProp, ImportModeStrings, ImportModeValues, new GUIContent("Import Mode"));
                    }
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PropertyField(importScaleProp);
                        if (GUILayout.Button("Set", guiStyleDropDown, GUILayout.Width(40), GUILayout.Height(14)))
                        {
                            GenericMenu menu = new GenericMenu();
                            #region Division
                            {
                                foreach (var value in VoxelBaseEditor.ScaleDivisionTemplate)
                                {
                                    menu.AddItem(new GUIContent(string.Format("Division/{0}", value)), false, () =>
                                    {
                                        var tmp = 1f / (float)value;
                                        SerializedObjectUpdate();
                                        {
                                            importScaleProp.vector3Value = new Vector3(tmp, tmp, tmp);
                                        }
                                        SerializedObjectApplyModifiedProperties();
                                    });
                                }
                            }
                            #endregion
                            #region Template
                            {
                                foreach (var value in VoxelBaseEditor.ScaleTemplateTemplate)
                                {
                                    menu.AddItem(new GUIContent(string.Format("Template/{0}", value)), false, () =>
                                    {
                                        SerializedObjectUpdate();
                                        {
                                            importScaleProp.vector3Value = new Vector3(value, value, value);
                                        }
                                        SerializedObjectApplyModifiedProperties();
                                    });
                                }
                            }
                            #endregion
                            menu.AddSeparator("");
                            #region Default value
                            {
                                menu.AddItem(new GUIContent("Default value/Save to default value"), false, () =>
                                {
                                    EditorPrefs.SetFloat("VoxelImporter_DefaultScaleX", importScaleProp.vector3Value.x);
                                    EditorPrefs.SetFloat("VoxelImporter_DefaultScaleY", importScaleProp.vector3Value.y);
                                    EditorPrefs.SetFloat("VoxelImporter_DefaultScaleZ", importScaleProp.vector3Value.z);
                                });
                                menu.AddItem(new GUIContent("Default value/Load from default value"), false, () =>
                                {
                                    var x = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleX", 1f);
                                    var y = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleY", 1f);
                                    var z = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleZ", 1f);
                                    SerializedObjectUpdate();
                                    {
                                        importScaleProp.vector3Value = new Vector3(x, y, z);
                                    }
                                    SerializedObjectApplyModifiedProperties();
                                });
                            }
                            #endregion
                            menu.ShowAsContext();
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PropertyField(importOffsetProp);
                        if (GUILayout.Button("Set", guiStyleDropDown, GUILayout.Width(40), GUILayout.Height(14)))
                        {
                            GenericMenu menu = new GenericMenu();
                            #region Reset
                            menu.AddItem(new GUIContent("Reset"), false, () =>
                            {
                                SerializedObjectUpdate();
                                {
                                    importOffsetProp.vector3Value = Vector3.zero;
                                }
                                SerializedObjectApplyModifiedProperties();
                            });
                            #endregion
                            menu.ShowAsContext();
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Optimize
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Optimize", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.PropertyField(combineFacesProp, VoxelBaseEditor.CombineVoxelFacesContent);
                    EditorGUILayout.PropertyField(ignoreCavityProp, VoxelBaseEditor.IgnoreCavityContent);
                    EditorGUILayout.PropertyField(shareSameFaceProp, VoxelBaseEditor.ShareSameFaceContent);
                    if (vtarget.fileType == VoxelBase.FileType.vox)
                    {
                        EditorGUILayout.PropertyField(removeUnusedPalettesProp, VoxelBaseEditor.RemoveUnusedPalettesContent);
                    }
                    if ((VoxelScriptedImporter.MeshMode)meshModeProp.intValue == VoxelScriptedImporter.MeshMode.Individual)
                    {
                        EditorGUILayout.PropertyField(createContactChunkFacesProp, new GUIContent("Create contact faces of chunks", "Generate faces of adjacent part of Chunk"));
                    }
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Output
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Output", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.PropertyField(outputStructureProp, new GUIContent("Voxel Structure", "Save the structure information."));
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Mesh
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.PropertyField(generateLightmapUVsProp, new GUIContent("Generate Lightmap UVs", "Generate lightmap UVs into UV2."));
                    if (generateLightmapUVsProp.boolValue)
                    {
                        EditorGUI.indentLevel++;
                        generateLightmapUVsAdvanced = EditorGUILayout.Foldout(generateLightmapUVsAdvanced, new GUIContent("Advanced"));
                        if (generateLightmapUVsAdvanced)
                        {
                            {
                                EditorGUI.BeginChangeCheck();
                                EditorGUILayout.Slider(generateLightmapUVsHardAngleProp, 0f, 180f, new GUIContent("Hard Angle", "Angle between neighbor triangles that will generate seam."));
                                if (EditorGUI.EndChangeCheck())
                                {
                                    generateLightmapUVsHardAngleProp.floatValue = Mathf.Round(generateLightmapUVsHardAngleProp.floatValue);
                                }
                            }
                            {
                                EditorGUI.BeginChangeCheck();
                                EditorGUILayout.Slider(generateLightmapUVsPackMarginProp, 1f, 64f, new GUIContent("Pack Margin", "Measured in pixels, assuming mesh will cover an entire 1024x1024 lightmap."));
                                if (EditorGUI.EndChangeCheck())
                                {
                                    generateLightmapUVsPackMarginProp.floatValue = Mathf.Round(generateLightmapUVsPackMarginProp.floatValue);
                                }
                            }
                            {
                                EditorGUI.BeginChangeCheck();
                                EditorGUILayout.Slider(generateLightmapUVsAngleErrorProp, 1f, 75f, 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."));
                                if (EditorGUI.EndChangeCheck())
                                {
                                    generateLightmapUVsAngleErrorProp.floatValue = Mathf.Round(generateLightmapUVsAngleErrorProp.floatValue);
                                }
                            }
                            {
                                EditorGUI.BeginChangeCheck();
                                EditorGUILayout.Slider(generateLightmapUVsAreaErrorProp, 1f, 75f, new GUIContent("Area Error"));
                                if (EditorGUI.EndChangeCheck())
                                {
                                    generateLightmapUVsAreaErrorProp.floatValue = Mathf.Round(generateLightmapUVsAreaErrorProp.floatValue);
                                }
                            }
                        }
                        EditorGUI.indentLevel--;
                    }
                    EditorGUILayout.PropertyField(generateTangentsProp, new GUIContent("Generate Tangents", "Generate Tangents."));
                    EditorGUILayout.Slider(meshFaceVertexOffsetProp, 0f, 0.01f, new GUIContent("Vertex Offset", "Increase this value if flickering of polygon gaps occurs at low resolution."));
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Material
            {
                EditorGUILayout.LabelField("Material", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    if (advancedMode)
                    {
                        if ((VoxelScriptedImporter.MeshMode)meshModeProp.intValue == VoxelScriptedImporter.MeshMode.Individual)
                        {
                            EditorGUILayout.IntPopup(materialModeProp, MaterialModeStrings, MaterialModeValues, new GUIContent("Material Mode", "Choose to share the Material across all Meshes, or generate a separate Material for each Mesh"));
                        }
                        EditorGUILayout.PropertyField(loadFromVoxelFileProp, new GUIContent("Load From Voxel File"));
                    }
#if UNITY_2017_3_OR_NEWER
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Materials");
                        bool disableExtract = false;
                        {
                            if (vtarget.materials == null || vtarget.materials.Length <= 0)
                            {
                                disableExtract = true;
                            }
                            else
                            {
                                disableExtract = true;
                                for (int i = 0; i < vtarget.materials.Length; i++)
                                {
                                    if (vtarget.materials[i] != null)
                                    {
                                        disableExtract = false;
                                        break;
                                    }
                                }
                            }
                        }
                        EditorGUI.BeginDisabledGroup(disableExtract);
                        if (GUILayout.Button(new GUIContent("Extract Materials...", "Click on this button to extract the embedded materials.")))
                        {
                            string path = vtarget.assetPath;
                            path = EditorUtility.SaveFolderPanel("Select Materials Folder", Path.GetDirectoryName(path), "");
                            if (!string.IsNullOrEmpty(path))
                            {
                                path = FileUtil.GetProjectRelativePath(path);
                                if (string.IsNullOrEmpty(path))
                                {
                                    EditorCommon.SaveInsideAssetsFolderDisplayDialog();
                                }
                                else
                                {
                                    try
                                    {
                                        AssetDatabase.StartAssetEditing();
                                        {
                                            foreach (var t in targets)
                                            {
                                                var importer = t as VoxelScriptedImporter;
                                                if (importer == null)
                                                {
                                                    continue;
                                                }
                                                SerializedObject   so       = new SerializedObject(importer);
                                                SerializedProperty rmatProp = so.FindProperty("remappedMaterials");
                                                var materials = AssetDatabase.LoadAllAssetsAtPath(importer.assetPath).Where(x => x.GetType() == typeof(Material));
                                                foreach (var material in materials)
                                                {
                                                    if (EditorCommon.IsMainAsset(material))
                                                    {
                                                        continue;
                                                    }
                                                    string assetPath;
                                                    if (importer.legacyAssetNaming)
                                                    {
                                                        assetPath = string.Format("{0}/{1}_{2}.mat", path, Path.GetFileNameWithoutExtension(importer.assetPath), material.name);
                                                    }
                                                    else
                                                    {
                                                        assetPath = string.Format("{0}/{1}.mat", path, material.name);
                                                    }
                                                    assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
                                                    AssetDatabase.CreateAsset(Material.Instantiate(material), assetPath);
                                                    {
                                                        var saveMaterial = UnityEditor.AssetDatabase.LoadAssetAtPath <Material>(assetPath);
                                                        var remap        = rmatProp.GetArrayElementAtIndex(rmatProp.arraySize++);
                                                        remap.FindPropertyRelative("name").stringValue = material.name;
                                                        remap.FindPropertyRelative("material").objectReferenceValue = saveMaterial;
                                                    }
                                                }
                                                so.ApplyModifiedProperties();
                                                importer.SaveAndReimport();
                                            }
                                            return; //Force Exit
                                        }
                                    }
                                    finally
                                    {
                                        AssetDatabase.StopAssetEditing();
                                    }
                                }
                            }
                        }
                        EditorGUI.EndDisabledGroup();
                        EditorGUILayout.EndHorizontal();
                    }
                    {
                        EditorGUILayout.LabelField(new GUIContent("Remapped Materials", "External materials to use for each embedded material."), EditorStyles.boldLabel);

                        EditorGUI.indentLevel++;
                        for (int index = 0; index < vtarget.materialNames.Length; index++)
                        {
                            SerializedProperty materialProp = null;
                            Material           material     = null;
                            int propertyIdx = 0;
                            for (int i = 0, count = remappedMaterialsProp.arraySize; i < count; i++)
                            {
                                try
                                {
                                    var remap = remappedMaterialsProp.GetArrayElementAtIndex(i);
                                    var name  = remap.FindPropertyRelative("name").stringValue;
                                    var prop  = remap.FindPropertyRelative("material");
                                    if (vtarget.materialNames[index] == name)
                                    {
                                        materialProp = prop;
                                        material     = prop.objectReferenceValue as Material;
                                        propertyIdx  = i;
                                        break;
                                    }
                                }
                                catch
                                {
                                    continue;
                                }
                            }
                            if (materialProp != null)
                            {
                                EditorGUI.BeginChangeCheck();
                                EditorGUILayout.ObjectField(materialProp, typeof(Material), new GUIContent(vtarget.materialNames[index]));
                                if (EditorGUI.EndChangeCheck())
                                {
                                    if (materialProp.objectReferenceValue == null)
                                    {
                                        remappedMaterialsProp.DeleteArrayElementAtIndex(propertyIdx);
                                    }
                                }
                            }
                            else
                            {
                                EditorGUI.BeginChangeCheck();
                                material = EditorGUILayout.ObjectField(vtarget.materialNames[index], material, typeof(Material), false) as Material;
                                if (EditorGUI.EndChangeCheck())
                                {
                                    if (material != null)
                                    {
                                        var remap = remappedMaterialsProp.GetArrayElementAtIndex(remappedMaterialsProp.arraySize++);
                                        remap.FindPropertyRelative("name").stringValue = vtarget.materialNames[index];
                                        remap.FindPropertyRelative("material").objectReferenceValue = material;
                                    }
                                }
                            }
                        }
                        EditorGUI.indentLevel--;
                    }
#else
                    {
                        EditorGUILayout.HelpBox("It is impossible to change the material due to issue of Issue ID 1012200.\nWhen using Material change please use Unity 2017.4.1 or later.", MessageType.Warning);
                    }
#endif
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Texture
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Texture", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.PropertyField(generateMipMapsProp, new GUIContent("Generate Mip Maps"));
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Collider
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Collider", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.IntPopup(colliderTypeProp, ColliderTypeStrings, ColliderTypeValues, new GUIContent("Generate Colliders"));
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Export
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Export", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                {
                    EditorGUILayout.PropertyField(exportProp, new GUIContent("Export", "Export COLLADA(dae) File"));
                }
                EditorGUI.indentLevel--;
            }
            #endregion

            #region Legacy
            if (advancedMode)
            {
                EditorGUILayout.LabelField("Legacy", EditorStyles.boldLabel);
                EditorGUI.indentLevel++;
                if (vtarget.fileType == VoxelBase.FileType.vox)
                {
                    EditorGUILayout.PropertyField(legacyVoxImportProp, 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."));
                }
                EditorGUILayout.PropertyField(legacyAssetNamingProp, new GUIContent("Legacy Asset Naming", "Name the subasset a traditional name, such as 'mat0', instead of the voxel file name."));
                EditorGUI.indentLevel--;
            }
            #endregion

            SerializedObjectApplyModifiedProperties();

            ApplyRevertGUI();
        }