コード例 #1
0
        /// <summary>
        /// Get the terrain that matches this location, otherwise return null
        /// </summary>
        /// <param name="locationWU">Location to check in world units</param>
        /// <returns>Terrain here or null</returns>
        public static Terrain GetTerrain(Vector3 locationWU, bool selectWorldMapTerrains = false)
        {
            Terrain terrain;
            Vector3 terrainMin = new Vector3();
            Vector3 terrainMax = new Vector3();

            //First check active terrain - most likely already selected
            terrain = Terrain.activeTerrain;
            if (terrain != null && terrain.terrainData != null && (selectWorldMapTerrains == TerrainHelper.IsWorldMapTerrain(terrain)))
            {
                terrainMin = terrain.GetPosition();
                terrainMax = terrainMin + terrain.terrainData.size;
                if (locationWU.x >= terrainMin.x && locationWU.x <= terrainMax.x)
                {
                    if (locationWU.z >= terrainMin.z && locationWU.z <= terrainMax.z)
                    {
                        return(terrain);
                    }
                }
            }

            //Then check rest of terrains
            Terrain closestTerrain  = null;
            float   closestDistance = float.MaxValue;

            for (int idx = 0; idx < Terrain.activeTerrains.Length; idx++)
            {
                terrain = Terrain.activeTerrains[idx];
                if (terrain.terrainData == null || (selectWorldMapTerrains != TerrainHelper.IsWorldMapTerrain(terrain)))
                {
                    continue;
                }
                terrainMin = terrain.GetPosition();
                terrainMax = terrainMin + terrain.terrainData.size;

                if (locationWU.x >= terrainMin.x && locationWU.x <= terrainMax.x)
                {
                    if (locationWU.z >= terrainMin.z && locationWU.z <= terrainMax.z)
                    {
                        return(terrain);
                    }
                }

                if (closestTerrain == null || Vector3.Distance(terrain.transform.position, locationWU) < closestDistance)
                {
                    closestTerrain = terrain;
                }
            }
            return(closestTerrain);
        }
コード例 #2
0
        public Terrain GetCurrentTerrain()
        {
            Terrain currentTerrain = Gaia.TerrainHelper.GetTerrain(transform.position, false);

            //Check if the stamper is over a terrain currently
            //if not, we will draw a preview based on the last active terrain we were over
            //if that is null either we can't draw a stamp preview
            if (currentTerrain)
            {
                //Update last active terrain with current
                if (m_lastActiveTerrain != currentTerrain)
                {
                    //if the current terrain is a new terrain, we should refresh the min max values in case this terrain has never been calculated before
                    SessionManager.GetWorldMinMax(ref m_minWorldHeight, ref m_maxWorldHeight);
                }
                m_lastActiveTerrain = currentTerrain;
            }
            //if not, we check if there is any terrain within the bounds of the biome spawner
            if (currentTerrain == null)
            {
                float  width         = m_settings.m_range * 2f;
                Bounds stamperBounds = new Bounds(transform.position, new Vector3(width, width, width));

                foreach (Terrain t in Terrain.activeTerrains)
                {
                    //only look at this terrain if it matches the selected world map mode
                    if (!TerrainHelper.IsWorldMapTerrain(t) && t.terrainData != null)
                    {
                        Bounds worldSpaceBounds = t.terrainData.bounds;
                        worldSpaceBounds.center = new Vector3(worldSpaceBounds.center.x + t.transform.position.x, worldSpaceBounds.center.y + t.transform.position.y, worldSpaceBounds.center.z + t.transform.position.z);

                        if (worldSpaceBounds.Intersects(stamperBounds))
                        {
                            currentTerrain = t;
                            break;
                        }
                    }
                }
            }
            return(currentTerrain);
        }
コード例 #3
0
        /// <summary>
        /// Gets the world map terrain from the scene
        /// </summary>
        /// <returns>The world map terrain</returns>
        public static Terrain GetWorldMapTerrain()
        {
            foreach (Terrain t in Terrain.activeTerrains)
            {
                if (TerrainHelper.IsWorldMapTerrain(t))
                {
                    return(t);
                }
            }

            //still no world map terrain? might be a deactivated GameObject, check those as well
            GameObject worldMapGO = GaiaUtils.FindObjectDeactivated(GaiaConstants.worldMapTerrainPrefix + "_", false);

            if (worldMapGO != null)
            {
                Terrain t = worldMapGO.GetComponent <Terrain>();
                if (t != null)
                {
                    return(t);
                }
            }
            return(null);
        }
コード例 #4
0
        /// <summary>
        /// Get the bounds of the terrain at this location or fail with a null
        /// </summary>
        /// <param name="locationWU">Location to check and get terrain for</param>
        /// <returns>Bounds of selected terrain or null if invalid for some reason</returns>
        public static bool GetTerrainBounds(ref BoundsDouble bounds, bool activeTerrainsOnly = false)
        {
            //Terrain terrain = GetTerrain(locationWU);
            //if (terrain == null)
            //{
            //    return false;
            //}
            //bounds.center = terrain.transform.position;
            //bounds.size = terrain.terrainData.size;
            //bounds.center += bounds.extents;

            Vector3Double accumulatedCenter = new Vector3Double();

            //Do we use dynamic loaded terrains in the scene?
            if (GaiaUtils.HasDynamicLoadedTerrains() && !activeTerrainsOnly)
            {
#if GAIA_PRO_PRESENT
                //we do have dynamic terrains -> calculate the bounds according to the terrain scene data in the session
                GaiaSessionManager gsm = GaiaSessionManager.GetSessionManager(false);

                foreach (TerrainScene t in TerrainLoaderManager.TerrainScenes)
                {
                    accumulatedCenter += t.m_bounds.center;
                }

                bounds.center = accumulatedCenter / TerrainLoaderManager.TerrainScenes.Count;

                foreach (TerrainScene t in TerrainLoaderManager.TerrainScenes)
                {
                    bounds.Encapsulate(t.m_bounds);
                }
#endif
            }
            else
            {
                //no placeholder -> calculate bounds according to the active terrains in the scene
                if (Terrain.activeTerrains.Length > 0)
                {
                    foreach (Terrain t in Terrain.activeTerrains)
                    {
                        if (!TerrainHelper.IsWorldMapTerrain(t))
                        {
                            if (t.terrainData != null)
                            {
                                accumulatedCenter += new Vector3Double(t.transform.position) + new Vector3Double(t.terrainData.bounds.extents);
                            }
                            else
                            {
                                Debug.LogWarning("Terrain " + t.name + " in the scene is missing the terrain data object!");
                            }
                        }
                    }
                    bounds.center = accumulatedCenter / Terrain.activeTerrains.Length;

                    foreach (Terrain t in Terrain.activeTerrains)
                    {
                        if (!TerrainHelper.IsWorldMapTerrain(t))
                        {
                            if (t.terrainData != null)
                            {
                                Bounds newBounds = new Bounds();
                                newBounds.center  = t.transform.position;
                                newBounds.size    = t.terrainData.size;
                                newBounds.center += t.terrainData.bounds.extents;
                                bounds.Encapsulate(newBounds);
                            }
                        }
                    }
                }
                else
                {
                    bounds = new BoundsDouble(Vector3Double.zero, Vector3Double.zero);
                    //No active terrains? There might be mesh terrains we can use then
                    GameObject meshTerrainExportObject = GaiaUtils.GetTerrainExportObject(false);
                    if (meshTerrainExportObject != null)
                    {
                        foreach (Transform t in meshTerrainExportObject.transform)
                        {
                            MeshRenderer mr = t.GetComponent <MeshRenderer>();
                            if (mr != null)
                            {
                                bounds.Encapsulate(mr.bounds);
                            }
                        }
                    }
                }
            }


            return(true);
        }
コード例 #5
0
        public Spawner CreateSpawner(bool autoAddResources = false, Transform targetTransform = null)
        {
            //Find or create gaia
            GameObject gaiaObj    = GaiaUtils.GetGaiaGameObject();
            GameObject spawnerObj = new GameObject(this.name);

            spawnerObj.AddComponent <Spawner>();
            if (targetTransform != null)
            {
                spawnerObj.transform.parent = targetTransform;
            }
            else
            {
                spawnerObj.transform.parent = gaiaObj.transform;
            }

            Spawner spawner = spawnerObj.GetComponent <Spawner>();

            spawner.LoadSettings(this);
            //spawner.m_settings.m_resources = (GaiaResource)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(this.m_resourcesGUID), typeof(GaiaResource));
            if (autoAddResources)
            {
                TerrainLayer[]    terrainLayers  = new TerrainLayer[0];
                DetailPrototype[] terrainDetails = new DetailPrototype[0];
                TreePrototype[]   terrainTrees   = new TreePrototype[0];
                GaiaDefaults.GetPrototypes(new List <BiomeSpawnerListEntry>()
                {
                    new BiomeSpawnerListEntry()
                    {
                        m_spawnerSettings = this, m_autoAssignPrototypes = true
                    }
                }, ref terrainLayers, ref terrainDetails, ref terrainTrees, Terrain.activeTerrain);

                foreach (Terrain t in Terrain.activeTerrains)
                {
                    GaiaDefaults.ApplyPrototypesToTerrain(t, terrainLayers, terrainDetails, terrainTrees);
                }
            }

            //We need to check the texture prototypes in this spawner against the already created terrain layers for this session
            //- otherwise the spawner will not know about those in subsequent spawns and might create unneccessary additional layers

            //Get a list of all exisiting Terrain Layers for this session
            string path = GaiaDirectories.GetTerrainLayerPath();

#if UNITY_EDITOR
            AssetDatabase.ImportAsset(path);
            if (Directory.Exists(path))
            {
                string[] allLayerGuids = AssetDatabase.FindAssets("t:TerrainLayer", new string[1] {
                    path
                });
                List <TerrainLayer> existingTerrainLayers = new List <TerrainLayer>();
                foreach (string guid in allLayerGuids)
                {
                    try
                    {
                        TerrainLayer layer = (TerrainLayer)AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), typeof(TerrainLayer));
                        if (layer != null)
                        {
                            existingTerrainLayers.Add(layer);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.Message == "")
                        {
                        }
                    }
                }
                foreach (SpawnRule sr in spawner.m_settings.m_spawnerRules)
                {
                    if (sr.m_resourceType == SpawnerResourceType.TerrainTexture)
                    {
                        ResourceProtoTexture protoTexture = spawner.m_settings.m_resources.m_texturePrototypes[sr.m_resourceIdx];
                        //if a terrainLayer with these properties exist we can assume it fits to the given spawn rule
                        TerrainLayer terrainLayer = existingTerrainLayers.FirstOrDefault(x => x.diffuseTexture == protoTexture.m_texture &&
                                                                                         x.normalMapTexture == protoTexture.m_normal &&
                                                                                         x.tileOffset == new Vector2(protoTexture.m_offsetX, protoTexture.m_offsetY) &&
                                                                                         x.tileSize == new Vector2(protoTexture.m_sizeX, protoTexture.m_sizeY)
                                                                                         );
                        if (terrainLayer != null)
                        {
                            protoTexture.m_LayerGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(terrainLayer));
                        }
                    }
                }
            }
#endif


            foreach (SpawnRule rule in spawner.m_settings.m_spawnerRules)
            {
                rule.m_spawnedInstances = 0;
            }

            if (Terrain.activeTerrains.Where(x => !TerrainHelper.IsWorldMapTerrain(x)).Count() > 0)
            {
                spawner.FitToAllTerrains();
            }
            //else
            //{
            //    spawner.FitToTerrain();
            //}
            return(spawner);
        }
コード例 #6
0
        public void CreateWorldMapTerrain()
        {
            //Remove old world map terrain, if any
            Terrain oldWMTerrain = TerrainHelper.GetWorldMapTerrain();

            if (oldWMTerrain != null)
            {
#if UNITY_EDITOR
                if (EditorUtility.DisplayDialog("Delete old world map?", "You are about to create a new world map in this scene. This will delete the existing world map and the stamp tokens on it. This will only affect the small world map terrain, the actual full scene terrain tiles will not be removed. Continue?", "Continue", "Cancel"))
                {
                    DestroyImmediate(oldWMTerrain.gameObject);
                }
                else
                {
                    return;
                }
#else
                Destroy(oldWMTerrain.gameObject);
#endif
            }

            GaiaSettings       gaiaSettings    = GaiaUtils.GetGaiaSettings();
            GaiaDefaults       currentDefaults = gaiaSettings.m_currentDefaults;
            GaiaSessionManager gsm             = GaiaSessionManager.GetSessionManager();

            //Collect some info from the existing world, if any.

            //We need the average height from the terrains to create the height of the worldmap accordingly in scale
            double averageHeight = currentDefaults.m_terrainHeight;
            //We need the heightmap resolution and terrain size stored in the session
            //To properly scale between world map and local map even when one of the two is not loaded at the moment

            int count = 0;

            foreach (Terrain t in Terrain.activeTerrains)
            {
                averageHeight += t.terrainData.size.y;
                if (!TerrainHelper.IsWorldMapTerrain(t))
                {
                    m_localHeightmapRes = t.terrainData.heightmapResolution;
                    m_localTileSize     = t.terrainData.size.x;
                }

                count++;
            }
            //}
            //only calculate an average if there is at least one placeholder or terrain
            if (count > 0)
            {
                averageHeight /= count;
            }


            BoundsDouble bounds = new BoundsDouble();
            TerrainHelper.GetTerrainBounds(ref bounds);
            //Collect the new world settings for world creation
            WorldCreationSettings worldCreationSettings = ScriptableObject.CreateInstance <WorldCreationSettings>();
            worldCreationSettings.m_xTiles                = 1;
            worldCreationSettings.m_zTiles                = 1;
            worldCreationSettings.m_tileSize              = (count > 0) ? Mathd.RoundToInt(bounds.size.x) : gaiaSettings.m_tilesX * currentDefaults.m_terrainSize;
            worldCreationSettings.m_tileHeight            = currentDefaults.m_terrainHeight;
            worldCreationSettings.m_createInScene         = false;
            worldCreationSettings.m_autoUnloadScenes      = false;
            worldCreationSettings.m_applyFloatingPointFix = false;
            worldCreationSettings.m_applyFloatingPointFix = false;
            worldCreationSettings.m_centerOffset          = Vector3.zero; //(count > 0) ? new Vector2Double(bounds.center.x + bounds.extents.x + worldCreationSettings.m_tileSize, bounds.center.z) : Vector2Double.zero;
            worldCreationSettings.m_isWorldMap            = true;
            //clone defaults so we can inject our custom heightmap resolution for the worldmap
            GaiaDefaults clonedDefaults = Instantiate(currentDefaults);
            clonedDefaults.m_heightmapResolution = (int)m_heightmapResolution;

            worldCreationSettings.m_gaiaDefaults = clonedDefaults;

            m_currentWorldCreationSettings     = worldCreationSettings;
            GaiaSessionManager.OnWorldCreated -= OnWorldMapCreate;
            GaiaSessionManager.OnWorldCreated += OnWorldMapCreate;
            GaiaSessionManager.CreateWorld(worldCreationSettings);
        }