public override void OnInspectorGUI()
    {
        RevertLodMerge _target = (RevertLodMerge)target;

        if (_target.original == null)
        {
            try
            {
                Undo.DestroyObjectImmediate(this);
            }
            catch
            {
            }
            return;
        }
        else
        {
            SerializedProperty original_s     = serializedObject.FindProperty("original");
            SerializedProperty texutrePath_s  = serializedObject.FindProperty("texutrePath");
            SerializedProperty materialPath_s = serializedObject.FindProperty("materialPath");

            GUI.enabled = false;
            EditorGUILayout.PropertyField(original_s, new GUIContent("Original Grp Reference"));
            EditorGUILayout.PropertyField(texutrePath_s, new GUIContent("texutrePath Reference"));
            EditorGUILayout.PropertyField(materialPath_s, new GUIContent("materialPath Reference"));
            GUI.enabled = true;

            GUI.color = new Color(1, 0.3f, 0.3f);
            if (GUILayout.Button("Revert"))
            {
                LodMerge lodMerge = (LodMerge)EditorWindow.GetWindow(typeof(LodMerge), true);
                lodMerge.Revert(_target);
            }
        }
    }
    public void Revert(RevertLodMerge _revert)
    {
        Undo.RecordObject(_revert.original, "setActive");
        _revert.original.SetActive(true);
        Selection.activeGameObject = _revert.original;
        Undo.DestroyObjectImmediate(_revert.gameObject);

        if (_revert.texutrePath != string.Empty)
        {
            AssetDatabase.DeleteAsset(_revert.texutrePath);
        }
        if (_revert.materialPath != string.Empty)
        {
            AssetDatabase.DeleteAsset(_revert.materialPath);
        }
        for (int i = 0; i < _revert.meshPath.Count; i++)
        {
            if (_revert.meshPath[i] != string.Empty)
            {
                AssetDatabase.DeleteAsset(_revert.meshPath[i]);
            }
        }
    }
    void OnGUI()
    {
        state = (State)EditorGUILayout.EnumPopup(state);

        //if (state == State.Merge)
        //{
        EditorGUILayout.HelpBox("If using LOD 0-3 setup, name your child with the suffix: 'LOD0', 'LOD1', 'LOD2' respectfully.", MessageType.Info);
        GUILayout.BeginHorizontal();
        sizeUnit = EditorGUILayout.IntField("sizeUnit", sizeUnit);

        if (GUILayout.Button("10"))
        {
            sizeUnit = 10;
        }
        if (GUILayout.Button("50"))
        {
            sizeUnit = 50;
        }
        if (GUILayout.Button("100"))
        {
            sizeUnit = 100;
        }
        if (GUILayout.Button("500"))
        {
            sizeUnit = 500;
        }
        GUILayout.EndHorizontal();
        if (sizeUnit < 5)
        {
            sizeUnit = 5;
        }
        GUILayout.Label(amountX + " x " + amountY);

        //spacer
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
        //
        //}
        if (_tr != null)
        {
            lockSelection = EditorGUILayout.Toggle("lockSelection", lockSelection);
        }

        if (_tr == null || (Selection.activeTransform == null || Selection.activeTransform.transform.childCount < 2))
        {
            EditorGUILayout.HelpBox("Select 'Root GO' in scene to merge meshes. Requires an empty root GO container", MessageType.Info);
        }
        else
        {
            if (GUILayout.Button("Merge within: " + _tr.name))
            {
                Undo.RecordObject(_tr, "setActive");
                _tr.gameObject.SetActive(true);
                _tr.tag = "EditorOnly";

                DoesMerge(_tr);
            }
        }

        if (Selection.activeTransform != null && Selection.activeTransform.GetComponent <RevertLodMerge>() != null)
        {
            RevertLodMerge _revert = Selection.activeTransform.GetComponent <RevertLodMerge>();
            if (_revert.original != null)
            {
                GUI.color = new Color(1, 0.3f, 0.3f);
                if (GUILayout.Button("Revert"))
                {
                    Revert(_revert);
                }
            }
            else
            {
                Undo.DestroyObjectImmediate(_revert);
            }
        }
        GUI.color = Color.white;

        //atlas ui
        if (state == State.AtlasPack)
        {
            //sizeUnit = 9999;
            //spacer
            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
            lodMergeSO = (LodMergeSO)EditorGUILayout.ObjectField(lodMergeSO, typeof(LodMergeSO), false);
            EditorGUILayout.HelpBox("Name the GameObject unique names to prevent texture overwrites!", MessageType.Info);
            GUILayout.BeginVertical(EditorStyles.helpBox);
            GUILayout.BeginHorizontal();
            atlasTextureSize = EditorGUILayout.IntField("atlasTextureSize", atlasTextureSize);

            if (GUILayout.Button("128"))
            {
                atlasTextureSize = 128;
            }
            if (GUILayout.Button("256"))
            {
                atlasTextureSize = 256;
            }
            if (GUILayout.Button("512"))
            {
                atlasTextureSize = 512;
            }
            if (GUILayout.Button("1024"))
            {
                atlasTextureSize = 1024;
            }
            GUILayout.EndHorizontal();
            GUILayout.Box(atlas, GUILayout.Width(Screen.width / 2), GUILayout.Height(Screen.height / 2), GUILayout.MaxWidth(atlasTextureSize), GUILayout.MaxHeight(atlasTextureSize));

            GUILayout.EndVertical();
        }
    }
    //phase B Merge===========================================
    void AtlasCombine()
    {
        //atlas setup

        atlasTextures.Clear();
        //make all textures found readable
        for (int i = 0; i < gridNodes.Count; i++)
        {
            for (int ii = 0; ii < gridNodes[i].mat.Count; ii++)
            {
                Texture2D _mainTex = GetMainTexture(gridNodes[i].mat[ii].mat); //get the main texture
                if (_mainTex != null)
                {
                    string path = AssetDatabase.GetAssetPath(_mainTex);

                    TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path);
                    importer.isReadable = true;
                    AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

                    atlasTextures.Add(_mainTex);
                }
            }
        }

        //make texture ------------------------------------------------------------------------------------------
        Texture2D preBakeAtlas = new Texture2D(atlasTextureSize, atlasTextureSize);

        rects = preBakeAtlas.PackTextures(atlasTextures.ToArray(), 0, atlasTextureSize, false);

        //TO DO please make a list of texture name to reference back what each rect i are so I can reference to my grid support. Avoid unknow material uv set//////////////////////////////////////!!!

        //Encode the packed texture to PNG
        byte[] bytes = preBakeAtlas.EncodeToTGA();
        //Save the packed texture to the datapath of your choice
        string SelectedName = _tr.name;

        string SetFolderPath  = Path.GetDirectoryName(EditorSceneManager.GetActiveScene().path) + "/AtlasCombine/" + EditorSceneManager.GetActiveScene().name;
        var    folder         = Directory.CreateDirectory(SetFolderPath);
        string SetTexturePath = SetFolderPath + "/" + SelectedName + ".tga";
        string SetMathPath    = SetFolderPath + "/" + SelectedName + "_AtlasMat" + ".mat";

        //texture
        File.WriteAllBytes(SetTexturePath, bytes);
        AssetDatabase.ImportAsset(SetTexturePath, ImportAssetOptions.ForceUpdate);
        atlas = (Texture2D)AssetDatabase.LoadAssetAtPath(SetTexturePath, typeof(Texture2D));
        //mat
        Material atlasMat = new Material(GetShader());

        atlasMat.mainTexture = atlas;
        AssetDatabase.CreateAsset(atlasMat, SetMathPath);
        AssetDatabase.ImportAsset(SetMathPath, ImportAssetOptions.ForceUpdate);

        //destroy prebake
        DestroyImmediate(preBakeAtlas);

        //cleanup atlas. revert all textures found to unreadable
        for (int i = 0; i < gridNodes.Count; i++)
        {
            for (int ii = 0; ii < gridNodes[i].mat.Count; ii++)
            {
                Texture2D _mainTex = GetMainTexture(gridNodes[i].mat[ii].mat);
                string    path     = AssetDatabase.GetAssetPath(_mainTex);

                TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path);
                importer.isReadable = false;
                AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
            }
        }



        //setup
        GameObject newRootGO;

        newRootGO = new GameObject("Combine_" + _tr.name);
        Undo.RegisterCreatedObjectUndo(newRootGO, "created GO");
        Undo.RecordObject(newRootGO.transform, "Move GO");
        newRootGO.transform.position = _tr.position;

        RevertLodMerge _revertLODMerge = newRootGO.gameObject.AddComponent <RevertLodMerge>();

        _revertLODMerge.original     = _tr.gameObject;
        _revertLODMerge.texutrePath  = SetTexturePath;
        _revertLODMerge.materialPath = SetMathPath;
        //organizing
        if (_tr.parent != null)
        {
            newRootGO.transform.SetParent(_tr.parent);
        }
        newRootGO.transform.SetSiblingIndex(_tr.GetSiblingIndex());
        //----------------------------

        int ExistMatInGridCount = 0;

        for (int i = 0; i < gridNodes.Count; i++)
        {
            if (gridNodes[i].mat != null && gridNodes[i].mat.Count > 0)
            {
                ExistMatInGridCount += 1;
            }
        }

        for (int i = 0; i < gridNodes.Count; i++)
        {
            List <CombineInstance> combine = new List <CombineInstance>();


            for (int ii = 0; ii < gridNodes[i].mat.Count; ii++)
            {
                //List<CombineInstance> combine = new List<CombineInstance>();

                int meshR_i          = 0;
                int TotalMeshR_Count = gridNodes[i].mat[ii].meshR.Count;

                int uv_x = 0;
                int uv_y = 0;
                int OptimizedRowColumn = (int)Math.Ceiling(Mathf.Sqrt(TotalMeshR_Count));
                Debug.Log("OptimizedRowColumn" + OptimizedRowColumn);
                float perPerc = ((float)1 / (float)OptimizedRowColumn);


                while (meshR_i < TotalMeshR_Count)
                {
                    CombineInstance _combine = new CombineInstance();

                    Mesh newMesh = Instantiate(gridNodes[i].mat[ii].meshR[meshR_i].sharedMesh);
                    newMesh.name = "_processingMesh_";

                    _combine.mesh      = newMesh;
                    _combine.transform = gridNodes[i].mat[ii].meshR[meshR_i].transform.localToWorldMatrix;

                    int ThisRectID = -1;
                    for (int x = 0; x < atlasTextures.Count; x++)
                    {
                        if (atlasTextures[x] == gridNodes[i].mat[ii].mat.mainTexture)
                        {
                            ThisRectID = x;
                        }
                    }

                    ///uv0
                    if (ThisRectID > -1)
                    {
                        Vector2[] lightMapUV0 = newMesh.uv;
                        int       thisUV0_i   = 0;
                        while (thisUV0_i < lightMapUV0.Length)
                        {
                            Debug.Log("rect + " + ThisRectID + "  " + rects[ThisRectID]);
                            lightMapUV0[thisUV0_i] = (lightMapUV0[thisUV0_i] * new Vector2(rects[ThisRectID].width, rects[ThisRectID].height)) + (new Vector2(rects[ThisRectID].x, rects[ThisRectID].y));


                            thisUV0_i += 1;
                        }
                        newMesh.SetUVs(0, lightMapUV0);
                    }


                    combine.Add(_combine);

                    meshR_i += 1;
                }
            }
            GameObject newGO;
            newGO = new GameObject("_Combine_Atlas_");
            if (combine.Count > 0)
            {
                //Mesh
                Mesh atlasMesh = new Mesh();

                string SetMeshPath = SetFolderPath + "/" + SelectedName + "_AtlasMesh_" + i + ".asset";
                AssetDatabase.CreateAsset(atlasMesh, SetMeshPath);
                AssetDatabase.ImportAsset(SetMeshPath, ImportAssetOptions.ForceUpdate);
                _revertLODMerge.meshPath.Add(SetMeshPath);

                atlasMesh.name = "_Combine_Atlas_Mesh";
                MeshFilter mf = newGO.AddComponent <MeshFilter>();
                atlasMesh.CombineMeshes(combine.ToArray(), true, true);
                atlasMesh.uv2 = new Vector2[0];
                Unwrapping.GenerateSecondaryUVSet(atlasMesh);

                mf.sharedMesh = atlasMesh;

                MeshRenderer thisMr = newGO.AddComponent <MeshRenderer>();
                thisMr.sharedMaterial = atlasMat;
                newGO.transform.SetParent(newRootGO.transform);
            }
            else
            {
                if (newGO != null)
                {
                    Undo.DestroyObjectImmediate(newGO);
                    //DestroyImmediate(newGO);
                }
            }
        }



        //------------------------- end
        Undo.RecordObject(_tr.gameObject, "setActive");
        _tr.gameObject.SetActive(false);
        Selection.activeGameObject = newRootGO;
    }