private void OnEnable()
        {
            inited                    = serializedObject.FindProperty("inited");
            mazeGeneratedEvent        = serializedObject.FindProperty("mazeGeneratedEvent");
            mazePieceGeneratedEvent   = serializedObject.FindProperty("mazePieceGeneratedEvent");
            mazeGenerateProgressEvent = serializedObject.FindProperty("mazeGenerateProgressEvent");

            mazeEngine = (QMazeEngine)target;

            QInspectorUtils.SetIcon(mazeEngine, QInspectorUtils.getAsset <Texture2D>("MazeEngineIcon t:texture2D"));

            mazeIcon  = QInspectorUtils.getAsset <Texture2D>("MazeIcon t:texture2D");
            pieceIcon = QInspectorUtils.getAsset <Texture2D>("PieceIcon t:texture2D");

            startFoldout    = mazeEngine.getStartPositionList().Count > 0 || mazeEngine.getStartRandomPositionCount() > 0;
            finishFoldout   = mazeEngine.getFinishPositionList().Count > 0 || mazeEngine.getFinishRandomPositionCount() > 0;
            exitFoldout     = mazeEngine.getExitPositionList().Count > 0;
            obstacleFoldout = mazeEngine.getObstaclePositionList().Count > 0;
            eventFoldout    = mazeEngine.mazeGeneratedEvent.GetPersistentEventCount() +
                              mazeEngine.mazePieceGeneratedEvent.GetPersistentEventCount() +
                              mazeEngine.mazeGenerateProgressEvent.GetPersistentEventCount() > 0;
        }
        public override void OnInspectorGUI()
        {
            if (labelCaption == null)
            {
                initStyle();
            }

            serializedObject.Update();
            if (!inited.boolValue)
            {
                MethodInfo awakeMethod = mazeEngine.GetType().GetMethod("Awake", BindingFlags.NonPublic | BindingFlags.Instance);
                awakeMethod.Invoke(mazeEngine, null);
            }

            bool errorFound = false;

            GUI.changed = false;
            Undo.RecordObject(target, "MazeEngineChnaged");

            GUILayout.Space(7);
            GUILayout.BeginHorizontal();
            {
                GUILayout.BeginVertical();
                {
                    GUILayout.BeginHorizontal();
                    {
                        GUILayout.Space(28);
                        GUILayout.Label("Maze Size", labelCaption, GUILayout.Width(94));
                    }
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    {
                        GUI.DrawTexture(EditorGUILayout.GetControlRect(GUILayout.Width(120), GUILayout.Height(50)), mazeIcon, ScaleMode.ScaleToFit);
                        mazeEngine.setMazeHeight(EditorGUILayout.IntField(mazeEngine.getMazeHeight(), textFieldVC, GUILayout.Height(50), GUILayout.Width(30)));
                        if (mazeEngine.getMazeHeight() < 1)
                        {
                            mazeEngine.setMazeHeight(1);
                        }
                    }
                    GUILayout.EndHorizontal();
                    mazeEngine.setMazeWidth(EditorGUILayout.IntField(mazeEngine.getMazeWidth(), textFieldHC, GUILayout.Width(97)));
                    if (mazeEngine.getMazeWidth() < 1)
                    {
                        mazeEngine.setMazeWidth(1);
                    }
                }
                GUILayout.EndVertical();

                GUILayout.BeginVertical();
                {
                    GUILayout.BeginHorizontal();
                    {
                        GUILayout.Space(28);
                        GUILayout.Label("Piece Size", labelCaption, GUILayout.Width(94));
                    }
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    {
                        GUI.DrawTexture(EditorGUILayout.GetControlRect(GUILayout.Width(120), GUILayout.Height(50)), pieceIcon, ScaleMode.ScaleToFit);
                        mazeEngine.setMazePieceHeight(EditorGUILayout.FloatField(mazeEngine.getMazePieceHeight(), textFieldVC, GUILayout.Height(50), GUILayout.Width(30)));
                    }
                    GUILayout.EndHorizontal();
                    mazeEngine.setMazePieceWidth(EditorGUILayout.FloatField(mazeEngine.getMazePieceWidth(), textFieldHC, GUILayout.Width(97)));
                }
                GUILayout.EndVertical();
            }
            GUILayout.EndHorizontal();

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            mazeEngine.setMazeScale(EditorGUILayout.FloatField("Maze scale", mazeEngine.getMazeScale(), textFieldHC, GUILayout.Width(200)));

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            mazeEngine.setMazePiecePack((QMazePiecePack)EditorGUILayout.ObjectField("Maze Piece Pack", mazeEngine.getMazePiecePack(), typeof(QMazePiecePack), true));
            if (mazeEngine.getMazePiecePack() == null)
            {
                EditorGUILayout.HelpBox("Maze Piece Pack is required", MessageType.Warning);
                errorFound = true;
            }

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            startFoldout = EditorGUILayout.Foldout(startFoldout, "List Of Start Piece", (!startFoldout && (mazeEngine.getStartPositionList().Count > 0 || mazeEngine.getStartRandomPositionCount() > 0)) ? foldoutBold : EditorStyles.foldout);
            EditorGUI.indentLevel++;
            if (startFoldout)
            {
                mazeEngine.setStartRandomPosition(EditorGUILayout.Toggle("Random Position", mazeEngine.isStartRandomPosition(), GUILayout.ExpandWidth(true)));

                if (mazeEngine.isStartRandomPosition())
                {
                    mazeEngine.setStartRandomPositionCount(EditorGUILayout.IntField("Count", mazeEngine.getStartRandomPositionCount()));
                }
                else
                {
                    startListFoldout = showVector2IntDirList(mazeEngine.getStartPositionList(), startListFoldout);
                }
            }
            EditorGUI.indentLevel--;

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            finishFoldout = EditorGUILayout.Foldout(finishFoldout, "List Of Finish Piece", (!finishFoldout && (mazeEngine.getFinishPositionList().Count > 0 || mazeEngine.getFinishRandomPositionCount() > 0)) ? foldoutBold : EditorStyles.foldout);
            EditorGUI.indentLevel++;
            if (finishFoldout)
            {
                mazeEngine.setFinishRandomPosition(EditorGUILayout.Toggle("Random Position", mazeEngine.isFinishRandomPosition(), GUILayout.ExpandWidth(true)));

                if (mazeEngine.isFinishRandomPosition())
                {
                    mazeEngine.setFinishRandomPositionCount(EditorGUILayout.IntField("Count", mazeEngine.getFinishRandomPositionCount()));
                }
                else
                {
                    finishListFoldout = showVector2IntDirList(mazeEngine.getFinishPositionList(), finishListFoldout);
                }
            }
            EditorGUI.indentLevel--;

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            exitFoldout = EditorGUILayout.Foldout(exitFoldout, "List Of Exits", (!exitFoldout && mazeEngine.getExitPositionList().Count > 0 ? foldoutBold : EditorStyles.foldout));
            EditorGUI.indentLevel++;
            if (exitFoldout)
            {
                exitListFoldout = showVector2IntDirList(mazeEngine.getExitPositionList(), exitListFoldout);
            }
            EditorGUI.indentLevel--;

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            obstacleFoldout = EditorGUILayout.Foldout(obstacleFoldout, "List Of Obstacles", (!obstacleFoldout && mazeEngine.getObstaclePositionList().Count > 0 ? foldoutBold : EditorStyles.foldout));
            EditorGUI.indentLevel++;
            if (obstacleFoldout)
            {
                mazeEngine.setObstacleIsNone(EditorGUILayout.Toggle("Use None pieces in areas of obstacles", mazeEngine.isObstacleIsNone(), GUILayout.ExpandWidth(true)));
                obstacleListFoldout = showVector2IntList(mazeEngine.getObstaclePositionList(), obstacleListFoldout);
            }
            EditorGUI.indentLevel--;

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            if (mazeGeneratedEvent == null)
            {
                mazeEngine.mazeGeneratedEvent = new QMazeEngine.QMazeGeneratedEvent();
                mazeGeneratedEvent            = serializedObject.FindProperty("mazeGeneratedEvent");
            }
            if (mazePieceGeneratedEvent == null)
            {
                mazeEngine.mazePieceGeneratedEvent = new QMazeEngine.QMazePieceGeneratedEvent();
                mazePieceGeneratedEvent            = serializedObject.FindProperty("mazePieceGeneratedEvent");
            }
            if (mazeGenerateProgressEvent == null)
            {
                mazeEngine.mazeGenerateProgressEvent = new QMazeEngine.QMazeGenerateProgressEvent();
                mazeGenerateProgressEvent            = serializedObject.FindProperty("mazeGenerateProgressEvent");
            }

            int eventCount = mazeEngine.mazeGeneratedEvent.GetPersistentEventCount() +
                             mazeEngine.mazePieceGeneratedEvent.GetPersistentEventCount() +
                             mazeEngine.mazeGenerateProgressEvent.GetPersistentEventCount();

            eventFoldout = EditorGUILayout.Foldout(eventFoldout, "List Of Events", !eventFoldout && eventCount > 0 ? foldoutBold : EditorStyles.foldout);
            EditorGUI.indentLevel++;
            if (eventFoldout)
            {
                EditorGUILayout.PropertyField(mazeGeneratedEvent);
                EditorGUILayout.PropertyField(mazePieceGeneratedEvent);
                EditorGUILayout.PropertyField(mazeGenerateProgressEvent);
            }
            EditorGUI.indentLevel--;

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            mazeEngine.setUseSeed(GUILayout.Toggle(mazeEngine.isUseSeed(), "Use seed for generation"));
            if (mazeEngine.isUseSeed())
            {
                EditorGUI.indentLevel++;
                mazeEngine.setSeed(EditorGUILayout.IntField("Seed", mazeEngine.getSeed()));
                EditorGUI.indentLevel--;
            }

            GUILayout.Space(5);
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
            GUILayout.Space(5);

            mazeEngine.setOnlyPathMode(GUILayout.Toggle(mazeEngine.isOnlyPathMode(), "Generation with the only path"));

            if (mazeEngine.gameObject.activeInHierarchy)
            {
                GUILayout.Space(5);
                GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
                GUILayout.Space(5);

                if (mazeEngine.transform.childCount == 0)
                {
                    if (errorFound)
                    {
                        GUI.enabled = false;
                    }
                    if (GUILayout.Button("Generate a Maze", GUILayout.ExpandWidth(true)))
                    {
                        mazeEngine.generateMaze();
                    }
                    GUI.enabled = true;
                }
                else
                {
                    if (GUILayout.Button("Destroy the Maze", GUILayout.ExpandWidth(true)))
                    {
                        mazeEngine.destroyImmediateMazeGeometry();
                    }
                }
            }

            GUILayout.Space(5);

            if (GUI.changed)
            {
                EditorUtility.SetDirty(mazeEngine);
                serializedObject.ApplyModifiedProperties();
            }
        }