Inheritance: ClickableArea
        public static void EnsureProjectConsistency(SceneManager manager, WalkableArea walkableArea)
        {
            if (walkableArea.m_sprite != null)
            {
                string assetPath      = AssetDatabase.GetAssetPath(walkableArea.m_sprite);
                string assetFilename  = Path.GetFileName(assetPath);
                string targetFilename = string.Format("{0}.png", walkableArea.name);
                if (assetFilename != targetFilename)
                {
                    EditorUtility.DisplayProgressBar("Renaming WalkableArea Sprite",
                                                     string.Format("Renaming WalkableArea sprite from {0} to {1}", assetFilename, targetFilename), 0.5f);
                    string targetPath = Path.Combine(Path.GetDirectoryName(assetPath), targetFilename);
                    if (File.Exists(targetPath))
                    {
                        targetPath = AssetDatabase.GenerateUniqueAssetPath(targetPath);
                    }

                    AssetDatabase.MoveAsset(assetPath, targetPath);
                    AssetDatabase.ImportAsset(targetPath);
                    Debug.LogFormat("Moved WalkableArea sprite from {0} to {1}.", assetPath, targetPath);
                    EditorUtility.ClearProgressBar();
                }
            }

            if (walkableArea.navMeshData != null)
            {
                string assetPath      = AssetDatabase.GetAssetPath(walkableArea.navMeshData);
                string assetFilename  = Path.GetFileName(assetPath);
                string targetFilename = string.Format("{0}.asset", walkableArea.name);
                if (assetFilename != targetFilename)
                {
                    EditorUtility.DisplayProgressBar("Renaming WalkableArea NavMeshData",
                                                     string.Format("Renaming WalkableArea NavMeshData from {0} to {1}", assetFilename, targetFilename), 0.5f);
                    string targetPath = Path.Combine(Path.GetDirectoryName(assetPath), targetFilename);
                    if (File.Exists(targetPath))
                    {
                        targetPath = AssetDatabase.GenerateUniqueAssetPath(targetPath);
                    }

                    AssetDatabase.MoveAsset(assetPath, targetPath);
                    AssetDatabase.ImportAsset(targetPath);
                    Debug.LogFormat("Moved WalkableArea navMeshData from {0} to {1}.", assetPath, targetPath);
                    EditorUtility.ClearProgressBar();
                }
            }
        }
        void RegenerateMesh()
        {
            if (m_WalkableArea == null)
            {
                return;
            }

            string          assetPath = AssetDatabase.GetAssetPath(m_WalkableArea.m_sprite);
            TextureImporter importer  = AssetImporter.GetAtPath(assetPath) as TextureImporter;

            if (importer == null)
            {
                Debug.LogFormat("Failed to load TextureImporter at path: {0}", assetPath);
                return;
            }

            EditorUtility.DisplayProgressBar("Rebuilding Navmesh",
                                             string.Format("Applying Changes to WalkableArea {0}", m_WalkableArea.name), 0.5f);
            string outputPath = AssetDatabase.GetAssetPath(m_WalkableArea.m_sprite);

            byte[] bytes = m_PaintTexture.EncodeToPNG();
            File.WriteAllBytes(outputPath, bytes);
            AssetDatabase.ImportAsset(outputPath);
            m_CollisionObject.SetActive(false);

            TextureImporterSettings settings = new TextureImporterSettings();

            importer.ReadTextureSettings(settings);
            settings.spriteMeshType           = SpriteMeshType.Tight;
            settings.spriteTessellationDetail = m_WalkableArea.m_detail;
            importer.SetTextureSettings(settings);
            importer.SaveAndReimport();

            EditorUtility.SetDirty(importer);
            AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);

            Vector3[] vertices = new Vector3[m_WalkableArea.m_sprite.vertices.Length];
            Vector3[] normals  = new Vector3[m_WalkableArea.m_sprite.vertices.Length];
            Vector2[] uv       = new Vector2[m_WalkableArea.m_sprite.vertices.Length];

            // normalize the vertex data from -1.0f to 1.0f in x and z coordinates
            for (int i = 0; i < m_WalkableArea.m_sprite.vertices.Length; ++i)
            {
                vertices[i] = new Vector3(
                    m_WalkableArea.m_sprite.vertices[i].x * 2.0f * m_WalkableArea.m_sprite.pixelsPerUnit / m_WalkableArea.m_sprite.texture.width,
                    0.0f,
                    m_WalkableArea.m_sprite.vertices[i].y * 2.0f * m_WalkableArea.m_sprite.pixelsPerUnit / m_WalkableArea.m_sprite.texture.height);
                normals[i] = -Vector3.forward;
                uv[i]      = Vector2.zero;
            }

            Mesh mesh = new Mesh();

            mesh.vertices = vertices;
            mesh.normals  = normals;
            mesh.uv       = uv;

            int[] triangles = new int[m_WalkableArea.m_sprite.triangles.Length];
            for (int i = 0; i < m_WalkableArea.m_sprite.triangles.Length; ++i)
            {
                triangles[i] = m_WalkableArea.m_sprite.triangles[i];
            }

            mesh.triangles = triangles;

            MeshFilter meshFilter = m_WalkableArea.gameObject.AddComponent <MeshFilter>();

            meshFilter.mesh = mesh;

            MeshRenderer meshRenderer = m_WalkableArea.gameObject.AddComponent <MeshRenderer>();

            // set modified to false here so that OnDisable of the editor doesn't retrigger RegenerateMesh
            m_Modified = false;

            string navmeshPath      = Path.Combine(SceneManager.Instance.m_outputPath, PrefabUtility.FindPrefabRoot(m_WalkableArea.transform.parent.gameObject).name);
            string navmeshAssetPath = Path.Combine(navmeshPath, string.Format("{0}.asset", m_WalkableArea.name));

            if (m_WalkableArea.navMeshData != null)
            {
                string walkableAreaNavMeshAssetPath = AssetDatabase.GetAssetPath(m_WalkableArea.navMeshData);
                if (!string.IsNullOrEmpty(walkableAreaNavMeshAssetPath))
                {
                    navmeshAssetPath = walkableAreaNavMeshAssetPath;
                }
            }
            else
            {
                Directory.CreateDirectory(navmeshPath);
                navmeshAssetPath = AssetDatabase.GenerateUniqueAssetPath(navmeshAssetPath);
            }

            m_WalkableArea.BuildNavMesh();

            AssetDatabase.CreateAsset(m_WalkableArea.navMeshData, navmeshAssetPath);

            DestroyImmediate(meshRenderer);
            DestroyImmediate(meshFilter);

            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                WalkableArea prefab = PrefabUtility.GetCorrespondingObjectFromSource(m_WalkableArea) as WalkableArea;
                if (prefab != null)
                {
                    prefab.navMeshData = m_WalkableArea.navMeshData;
                }
            }

            EditorUtility.ClearProgressBar();
        }
        void OnEnable()
        {
            if (SceneView.sceneViews.Count > 0)
            {
                SceneView sceneView = (SceneView)SceneView.sceneViews[0];
                sceneView.Focus();
            }

            m_WalkableArea = (WalkableArea)target;

            m_Sprite            = serializedObject.FindProperty("m_sprite");
            m_NavMeshData       = serializedObject.FindProperty("m_NavMeshData");
            m_Detail            = serializedObject.FindProperty("m_detail");
            m_Color             = serializedObject.FindProperty("m_color");
            m_AgentTypeID       = serializedObject.FindProperty("m_AgentTypeID");
            m_BuildHeightMesh   = serializedObject.FindProperty("m_BuildHeightMesh");
            m_DefaultArea       = serializedObject.FindProperty("m_DefaultArea");
            m_LayerMask         = serializedObject.FindProperty("m_LayerMask");
            m_OverrideTileSize  = serializedObject.FindProperty("m_OverrideTileSize");
            m_OverrideVoxelSize = serializedObject.FindProperty("m_OverrideVoxelSize");
            m_TileSize          = serializedObject.FindProperty("m_TileSize");
            m_VoxelSize         = serializedObject.FindProperty("m_VoxelSize");

            Mesh collisionMesh = new Mesh();

            collisionMesh.vertices = new[]
            {
                new Vector3(-1.0f, -0.1f, -1.0f),
                new Vector3(1.0f, -0.1f, -1.0f),
                new Vector3(-1.0f, -0.1f, 1.0f),
                new Vector3(1.0f, -0.1f, 1.0f)
            };
            collisionMesh.triangles = new[]
            {
                0, 2, 1,
                2, 3, 1
            };
            collisionMesh.normals = new[]
            {
                -Vector3.forward,
                -Vector3.forward,
                -Vector3.forward,
                -Vector3.forward
            };
            collisionMesh.uv = new[]
            {
                new Vector2(0, 0),
                new Vector2(1, 0),
                new Vector2(0, 1),
                new Vector2(1, 1)
            };

            m_CollisionMeshMaterial = new Material(Shader.Find("UI/Default"));

            m_CollisionObject = new GameObject("__CollisionObject__");
            m_CollisionObject.transform.SetParent(m_WalkableArea.transform, false);
            m_CollisionObject.transform.localPosition = new Vector3(0.0f, 10.0f, 0.0f);
            m_CollisionObject.hideFlags = HideFlags.HideAndDontSave;

            MeshFilter   meshFilter   = m_CollisionObject.AddComponent <MeshFilter>();
            MeshRenderer meshRenderer = m_CollisionObject.AddComponent <MeshRenderer>();
            MeshCollider meshCollider = m_CollisionObject.AddComponent <MeshCollider>();

            meshFilter.mesh         = collisionMesh;
            meshCollider.sharedMesh = collisionMesh;
            meshRenderer.material   = m_CollisionMeshMaterial;

            if (SceneManager.Instance == null)
            {
                Debug.LogError("Could not find SceneManager as parent of SpriteMesh!");
                return;
            }

            if (m_WalkableArea.m_sprite == null)
            {
                GameObject root       = PrefabUtility.FindValidUploadPrefabInstanceRoot(m_WalkableArea.transform.parent.gameObject);
                string     spritePath = Path.Combine(Path.Combine(SceneManager.Instance.m_outputPath, root.name), "Editor");
                Directory.CreateDirectory(spritePath);
                string spriteAssetPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(spritePath, string.Format("{0}.png", m_WalkableArea.name)));

                // load the sprite or create it if it doesn't exist
                m_WalkableArea.m_sprite = AssetDatabase.LoadAssetAtPath <Sprite>(spriteAssetPath);
                if (m_WalkableArea.m_sprite == null)
                {
                    // create the texture if it doesn't exist
                    Texture2D texture = AssetDatabase.LoadAssetAtPath <Texture2D>(spriteAssetPath);
                    if (texture == null)
                    {
                        Directory.CreateDirectory(spritePath);

                        WalkableAreaGroup group = m_WalkableArea.transform.parent.gameObject.GetComponent <WalkableAreaGroup>();

                        m_PaintTexture = new Texture2D(group.m_textureWidth, group.m_textureHeight, TextureFormat.RGBA32, false);
                        Color[] colors = m_PaintTexture.GetPixels();
                        for (int i = 0; i < colors.Length; ++i)
                        {
                            colors[i] = k_TransparentWhite;
                        }
                        m_PaintTexture.SetPixels(colors);
                        byte[] bytes = m_PaintTexture.EncodeToPNG();
                        File.WriteAllBytes(spriteAssetPath, bytes);
                        AssetDatabase.Refresh();
                    }
                    ResetTextureImporterSettings(spriteAssetPath);

                    Sprite sprite = Sprite.Create(m_PaintTexture, new Rect(0.0f, 0.0f, m_PaintTexture.width, m_PaintTexture.height), new Vector2(0.5f, 0.5f));
                    AssetDatabase.AddObjectToAsset(sprite, spriteAssetPath);
                    AssetDatabase.SaveAssets();

                    m_WalkableArea.m_sprite = AssetDatabase.LoadAssetAtPath <Sprite>(spriteAssetPath);
                }
            }

            m_PaintTexture = new Texture2D(m_WalkableArea.m_sprite.texture.width, m_WalkableArea.m_sprite.texture.height, TextureFormat.RGBA32, false);

            string          texturePath = AssetDatabase.GetAssetPath(m_WalkableArea.m_sprite);
            TextureImporter importer    = AssetImporter.GetAtPath(texturePath) as TextureImporter;

            if (importer != null)
            {
                if (importer.DoesSourceTextureHaveAlpha())
                {
                    Graphics.CopyTexture(m_WalkableArea.m_sprite.texture, m_PaintTexture);
                }
                else
                {
                    Graphics.ConvertTexture(m_WalkableArea.m_sprite.texture, m_PaintTexture);
                }
            }

            Tools.hidden = true;
        }