void OnEnable()
        {
            //Grab the active terrain height map
            if (Gaia.TerrainHelper.GetActiveTerrainCount() == 1 && Gaia.TerrainHelper.GetActiveTerrain() != null)
            {
                //Get sea level
                GaiaSceneInfo sceneInfo = GaiaSceneInfo.GetSceneInfo();
                m_seaLevel = sceneInfo.m_seaLevel;

                //Get our manager
                m_visualiser = (ResourceVisualiser)target;
                m_visualiser.Initialise();
                m_visualiser.Visualise();

                //Update resource sea level
                m_visualiser.m_resources.ChangeSeaLevel(m_seaLevel);
            }
        }
        public override void OnInspectorGUI()
        {
            //Get our manager
            m_visualiser = (ResourceVisualiser)target;

            //Set up the box style
            if (m_boxStyle == null)
            {
                m_boxStyle = new GUIStyle(GUI.skin.box);
                m_boxStyle.normal.textColor = GUI.skin.label.normal.textColor;
                m_boxStyle.fontStyle        = FontStyle.Bold;
                m_boxStyle.alignment        = TextAnchor.UpperLeft;
            }

            //Setup the wrap style
            if (m_wrapStyle == null)
            {
                m_wrapStyle          = new GUIStyle(GUI.skin.label);
                m_wrapStyle.wordWrap = true;
            }

            //Create a nice text intro
            GUILayout.BeginVertical("Resource Visualiser", m_boxStyle);
            GUILayout.Space(20);
            EditorGUILayout.LabelField("The resource visualiser allows you to visualise and edit your resources spawn criteria. Visualiser is CPU intensive, so make range smaller, and resolution larger if you suffer from lag.", m_wrapStyle);
            GUILayout.EndVertical();

            EditorGUI.BeginChangeCheck();

            DrawDefaultInspector();

            if (m_visualiser.m_resources == null)
            {
                GUILayout.BeginVertical("ERROR!!!", m_boxStyle);
                GUILayout.Space(20);
                EditorGUILayout.LabelField("You must select a resources file to use the Visualiser!!", m_wrapStyle);
                GUILayout.EndVertical();
                EditorGUI.EndChangeCheck();
                return;
            }

            //Create a nice text intro
            GUILayout.BeginVertical("Resource Editor", m_boxStyle);
            GUILayout.Space(20);
            EditorGUILayout.LabelField("Select and edit your resource and its spawn criteria here. Changes will show in real time.", m_wrapStyle);
            GUILayout.EndVertical();

            m_visualiser.m_selectedResourceType = (Gaia.GaiaConstants.SpawnerResourceType)EditorGUILayout.EnumPopup(GetLabel("Resource Type"), m_visualiser.m_selectedResourceType);

            GUIContent[] assetChoices;
            switch (m_visualiser.m_selectedResourceType)
            {
            case GaiaConstants.SpawnerResourceType.TerrainTexture:
            {
                assetChoices = new GUIContent[m_visualiser.m_resources.m_texturePrototypes.Length];
                for (int assetIdx = 0; assetIdx < m_visualiser.m_resources.m_texturePrototypes.Length; assetIdx++)
                {
                    assetChoices[assetIdx] = new GUIContent(m_visualiser.m_resources.m_texturePrototypes[assetIdx].m_name);
                }
                break;
            }

            case GaiaConstants.SpawnerResourceType.TerrainDetail:
            {
                assetChoices = new GUIContent[m_visualiser.m_resources.m_detailPrototypes.Length];
                for (int assetIdx = 0; assetIdx < m_visualiser.m_resources.m_detailPrototypes.Length; assetIdx++)
                {
                    assetChoices[assetIdx] = new GUIContent(m_visualiser.m_resources.m_detailPrototypes[assetIdx].m_name);
                }
                break;
            }

            case GaiaConstants.SpawnerResourceType.TerrainTree:
            {
                assetChoices = new GUIContent[m_visualiser.m_resources.m_treePrototypes.Length];
                for (int assetIdx = 0; assetIdx < m_visualiser.m_resources.m_treePrototypes.Length; assetIdx++)
                {
                    assetChoices[assetIdx] = new GUIContent(m_visualiser.m_resources.m_treePrototypes[assetIdx].m_name);
                }
                break;
            }

            default:
            {
                assetChoices = new GUIContent[m_visualiser.m_resources.m_gameObjectPrototypes.Length];
                for (int assetIdx = 0; assetIdx < m_visualiser.m_resources.m_gameObjectPrototypes.Length; assetIdx++)
                {
                    assetChoices[assetIdx] = new GUIContent(m_visualiser.m_resources.m_gameObjectPrototypes[assetIdx].m_name);
                }
                break;
            }
            }


            if (assetChoices.Length > 0)
            {
                m_visualiser.m_selectedResourceIdx = EditorGUILayout.Popup(GetLabel("Selected Resource"), m_visualiser.m_selectedResourceIdx, assetChoices);

                //Then select and display the editor
                switch (m_visualiser.m_selectedResourceType)
                {
                case GaiaConstants.SpawnerResourceType.TerrainTexture:
                {
                    if (m_visualiser.m_selectedResourceIdx >= m_visualiser.m_resources.m_texturePrototypes.Length)
                    {
                        m_visualiser.m_selectedResourceIdx = 0;
                    }
                    ResourceProtoTextureSO so = ScriptableObject.CreateInstance <ResourceProtoTextureSO>();
                    so.m_texture = m_visualiser.m_resources.m_texturePrototypes[m_visualiser.m_selectedResourceIdx];
                    var ed = Editor.CreateEditor(so);
                    ed.OnInspectorGUI();
                    break;
                }

                case GaiaConstants.SpawnerResourceType.TerrainDetail:
                {
                    //Fix up indexes
                    if (m_visualiser.m_selectedResourceIdx >= m_visualiser.m_resources.m_detailPrototypes.Length)
                    {
                        m_visualiser.m_selectedResourceIdx = 0;
                    }
                    ResourceProtoDetailSO so = ScriptableObject.CreateInstance <ResourceProtoDetailSO>();
                    so.m_detail = m_visualiser.m_resources.m_detailPrototypes[m_visualiser.m_selectedResourceIdx];
                    var ed = Editor.CreateEditor(so);
                    ed.OnInspectorGUI();
                    break;
                }

                case GaiaConstants.SpawnerResourceType.TerrainTree:
                {
                    //Fix up indexes
                    if (m_visualiser.m_selectedResourceIdx >= m_visualiser.m_resources.m_treePrototypes.Length)
                    {
                        m_visualiser.m_selectedResourceIdx = 0;
                    }
                    ResourceProtoTreeSO so = ScriptableObject.CreateInstance <ResourceProtoTreeSO>();
                    so.m_tree = m_visualiser.m_resources.m_treePrototypes[m_visualiser.m_selectedResourceIdx];
                    var ed = Editor.CreateEditor(so);
                    ed.OnInspectorGUI();
                    break;
                }

                default:
                {
                    //Fix up indexes
                    if (m_visualiser.m_selectedResourceIdx >= m_visualiser.m_resources.m_gameObjectPrototypes.Length)
                    {
                        m_visualiser.m_selectedResourceIdx = 0;
                    }
                    ResourceProtoGameObjectSO so = ScriptableObject.CreateInstance <ResourceProtoGameObjectSO>();
                    so.m_gameObject = m_visualiser.m_resources.m_gameObjectPrototypes[m_visualiser.m_selectedResourceIdx];
                    var ed = Editor.CreateEditor(so);
                    ed.OnInspectorGUI();
                    break;
                }
                }
            }

            //Check for changes, make undo record, make changes and let editor know we are dirty
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(m_visualiser.m_resources, "Made resource changes");
                EditorUtility.SetDirty(m_visualiser.m_resources);
            }

            //Update some key fields in the spawner
            m_visualiser.m_spawner.m_resources            = m_visualiser.m_resources;
            m_visualiser.m_spawner.m_spawnCollisionLayers = m_visualiser.m_fitnessCollisionLayers;
            m_visualiser.m_spawner.m_spawnRange           = m_visualiser.m_range;

            //Terrain info
            //Create a nice text intro
            GUILayout.BeginVertical("Terrain Info", m_boxStyle);
            GUILayout.Space(20);
            EditorGUILayout.LabelField("Hit control key to view detailed information at current mouse position - mouse must be over the visualiser to register data.", m_wrapStyle);
            GUILayout.EndVertical();

            EditorGUILayout.Vector3Field(GetLabel("Location"), m_visualiser.m_lastHitPoint);

            EditorGUILayout.Toggle(GetLabel("Virgin"), m_visualiser.m_lastHitWasVirgin);
            if (!string.IsNullOrEmpty(m_visualiser.m_lastHitObjectname))
            {
                EditorGUILayout.TextField(GetLabel("Hit Object"), m_visualiser.m_lastHitObjectname);
            }
            EditorGUILayout.FloatField(GetLabel("Hit Height"), m_visualiser.m_lastHitHeight);
            EditorGUILayout.FloatField(GetLabel("Terrain Height"), m_visualiser.m_lastHitTerrainHeight);
            EditorGUILayout.FloatField(GetLabel("Height Above Sea"), m_visualiser.m_lastHitTerrainRelativeHeight);
            EditorGUILayout.FloatField(GetLabel("Terrain Slope"), m_visualiser.m_lastHitTerrainSlope);
            EditorGUILayout.FloatField(GetLabel("Area Slope"), m_visualiser.m_lastHitAreaSlope);
            EditorGUILayout.FloatField(GetLabel("Fitness"), m_visualiser.m_lastHitFitness);
        }
        public override void OnInspectorGUI()
        {
            //Get our resource
            m_resource = (GaiaResource)target;

            //Set up the box style
            if (m_boxStyle == null)
            {
                m_boxStyle = new GUIStyle(GUI.skin.box);
                m_boxStyle.normal.textColor = GUI.skin.label.normal.textColor;
                m_boxStyle.fontStyle        = FontStyle.Bold;
                m_boxStyle.alignment        = TextAnchor.UpperLeft;
            }

            //Setup the wrap style
            if (m_wrapStyle == null)
            {
                m_wrapStyle          = new GUIStyle(GUI.skin.label);
                m_wrapStyle.wordWrap = true;
            }

            //Create a nice text intro
            GUILayout.BeginVertical("Gaia Resource", m_boxStyle);
            GUILayout.Space(20);
            //EditorGUILayout.LabelField("The resource manager allows you to manage the resources used by your terrain and spawner. To see what every setting does you can hover over it.\n\nGet From Terrain - Pick up resources and settings from the current terrain.\n\nUpdate DNA - Updates DNA for all resources and automatically calculate sizes.\n\nApply To Terrain - Apply terrain specific settings such as texture, detail and tree prototypes back into the terrain. Prefab this settings to save time creating your next terrain.", m_wrapStyle);
            EditorGUILayout.LabelField("These are the resources used by the Spawning & Stamping system. Create a terrain, add textures, details and trees, then press Get Resources From Terrain to load. To see how the settings influence the system you can hover over them.", m_wrapStyle);
            GUILayout.EndVertical();

            float oldSeaLevel = m_resource.m_seaLevel;
            float oldHeight   = m_resource.m_terrainHeight;

            EditorGUI.BeginChangeCheck();

            DrawDefaultInspector();

            DropAreaGUI();

            GUILayout.BeginVertical("Resource Controller", m_boxStyle);
            GUILayout.Space(20);

            if (GUILayout.Button(GetLabel("Set Asset Associations")))
            {
                if (EditorUtility.DisplayDialog("Set Asset Associations", "This will update your asset associations and can not be undone ! Here temporarily until hidden.", "Yes", "No"))
                {
                    if (m_resource.SetAssetAssociations())
                    {
                        EditorUtility.SetDirty(m_resource);
                    }
                }
            }


            if (GUILayout.Button(GetLabel("Associate Assets")))
            {
                if (EditorUtility.DisplayDialog("Associate Assets", "This will locate and associate the first resource found that matches your asset and can not be undone !", "Yes", "No"))
                {
                    if (m_resource.AssociateAssets())
                    {
                        EditorUtility.SetDirty(m_resource);
                    }
                }
            }


            if (GUILayout.Button(GetLabel("Get Resources From Terrain")))
            {
                if (EditorUtility.DisplayDialog("Get Resources from Terrain ?", "Are you sure you want to get / update your resource prototypes from the terrain ? This will update your settings and can not be undone !", "Yes", "No"))
                {
                    m_resource.UpdatePrototypesFromTerrain();
                    EditorUtility.SetDirty(m_resource);
                }
            }

            if (GUILayout.Button(GetLabel("Replace Resources In Terrains")))
            {
                if (EditorUtility.DisplayDialog("Replace Resources in ALL Terrains ?", "Are you sure you want to replace the resources in ALL terrains with these? This can not be undone !", "Yes", "No"))
                {
                    m_resource.ApplyPrototypesToTerrain();
                }
            }

            if (GUILayout.Button(GetLabel("Add Missing Resources To Terrains")))
            {
                if (EditorUtility.DisplayDialog("Add Missing Resources to ALL Terrains ?", "Are you sure you want to add your missing resource prototypes to ALL terrains ? This can not be undone !", "Yes", "No"))
                {
                    m_resource.AddMissingPrototypesToTerrain();
                }
            }


            if (m_resource.m_texturePrototypes.GetLength(0) == 0)
            {
                GUI.enabled = false;
            }
            if (GUILayout.Button(GetLabel("Create Coverage Texture Spawner")))
            {
                m_resource.CreateCoverageTextureSpawner(GetRangeFromTerrain(), GetTextureIncrementFromTerrain());
            }
            GUI.enabled = true;


            if (m_resource.m_detailPrototypes.GetLength(0) == 0)
            {
                GUI.enabled = false;
            }
            if (GUILayout.Button(GetLabel("Create Clustered Grass Spawner")))
            {
                m_resource.CreateClusteredDetailSpawner(GetRangeFromTerrain(), GetDetailIncrementFromTerrain());
            }
            if (GUILayout.Button(GetLabel("Create Coverage Grass Spawner")))
            {
                m_resource.CreateCoverageDetailSpawner(GetRangeFromTerrain(), GetDetailIncrementFromTerrain());
            }
            GUI.enabled = true;


            if (m_resource.m_treePrototypes.GetLength(0) == 0)
            {
                GUI.enabled = false;
            }
            if (GUILayout.Button(GetLabel("Create Clustered Terrain Tree Spawner")))
            {
                m_resource.CreateClusteredTreeSpawner(GetRangeFromTerrain());
            }
            if (GUILayout.Button(GetLabel("Create Coverage Terrain Tree Spawner")))
            {
                m_resource.CreateCoverageTreeSpawner(GetRangeFromTerrain());
            }
            GUI.enabled = true;

            if (m_resource.m_gameObjectPrototypes.GetLength(0) == 0)
            {
                GUI.enabled = false;
            }
            if (GUILayout.Button(GetLabel("Create Clustered Prefab Spawner")))
            {
                m_resource.CreateClusteredGameObjectSpawner(GetRangeFromTerrain());
            }
            if (GUILayout.Button(GetLabel("Create Coverage Prefab Spawner")))
            {
                m_resource.CreateCoverageGameObjectSpawner(GetRangeFromTerrain());
            }
            GUI.enabled = true;

            if (GUILayout.Button(GetLabel("Visualise")))
            {
                GameObject gaiaObj = GameObject.Find("Gaia");
                if (gaiaObj == null)
                {
                    gaiaObj = new GameObject("Gaia");
                }
                GameObject visualiserObj = GameObject.Find("Visualiser");
                if (visualiserObj == null)
                {
                    visualiserObj = new GameObject("Visualiser");
                    visualiserObj.AddComponent <ResourceVisualiser>();
                    visualiserObj.transform.parent = gaiaObj.transform;
                }
                ResourceVisualiser visualiser = visualiserObj.GetComponent <ResourceVisualiser>();
                visualiser.m_resources     = m_resource;
                Selection.activeGameObject = visualiserObj;
            }

            GUILayout.Space(5f);
            GUILayout.EndVertical();

            //Check for changes, make undo record, make changes and let editor know we are dirty
            if (EditorGUI.EndChangeCheck())
            {
                if (oldHeight != m_resource.m_terrainHeight)
                {
                    m_resource.ChangeHeight(oldHeight, m_resource.m_terrainHeight);
                }

                if (oldSeaLevel != m_resource.m_seaLevel)
                {
                    m_resource.ChangeSeaLevel(oldSeaLevel, m_resource.m_seaLevel);
                }
                Undo.RecordObject(m_resource, "Made resource changes");
                EditorUtility.SetDirty(m_resource);

                //Stop the save from going nuts
                if ((DateTime.Now - m_lastSaveDT).Seconds > 5)
                {
                    m_lastSaveDT = DateTime.Now;
                    AssetDatabase.SaveAssets();
                }
            }
        }