예제 #1
0
        internal static Dictionary <int, TerrainMap> CollectTerrains(bool onlyAutoConnectedTerrains = true)
        {
            if (!ValidTerrainsExist())
            {
                return(null);
            }

            // Collect by groups
            Dictionary <int, TerrainMap> groups = new Dictionary <int, TerrainMap>();

            foreach (Terrain t in Terrain.activeTerrains)
            {
                if (onlyAutoConnectedTerrains && !t.allowAutoConnect)
                {
                    continue;
                }

                if (!groups.ContainsKey(t.groupingID))
                {
                    TerrainMap map = TerrainMap.CreateFromPlacement(t, (x => (x.groupingID == t.groupingID) && !(onlyAutoConnectedTerrains && !x.allowAutoConnect)));
                    if (map != null)
                    {
                        groups.Add(t.groupingID, map);
                    }
                }
            }
            return((groups.Count != 0) ? groups : null);
        }
예제 #2
0
        public static void AutoConnect()
        {
            if (!ValidTerrainsExist())
            {
                return;
            }

            ClearConnectivity();

            Dictionary <int, TerrainMap> terrainGroups = CollectTerrains();

            if (terrainGroups == null)
            {
                return;
            }

            foreach (var group in terrainGroups)
            {
                TerrainMap terrains = group.Value;

                foreach (var tile in terrains.terrainTiles)
                {
                    TerrainTileCoord coords = tile.Key;

                    Terrain center = terrains.GetTerrain(coords.tileX, coords.tileZ);

                    Terrain left   = terrains.GetTerrain(coords.tileX - 1, coords.tileZ);
                    Terrain right  = terrains.GetTerrain(coords.tileX + 1, coords.tileZ);
                    Terrain top    = terrains.GetTerrain(coords.tileX, coords.tileZ + 1);
                    Terrain bottom = terrains.GetTerrain(coords.tileX, coords.tileZ - 1);

                    center.SetNeighbors(left, top, right, bottom);
                }
            }
        }
예제 #3
0
        // create a terrain map of ALL terrains, by using only their placement to fit them to a grid
        // the position and size of originTerrain defines the grid alignment and origin.  if NULL, we use the first active terrain
        static public TerrainMap CreateFromPlacement(Vector2 gridOrigin, Vector2 gridSize, System.Predicate <Terrain> filter = null, bool fullValidation = true)
        {
            if ((Terrain.activeTerrains == null) || (Terrain.activeTerrains.Length == 0))
            {
                return(null);
            }

            TerrainMap terrainMap = new TerrainMap();

            float gridScaleX = 1.0f / gridSize.x;
            float gridScaleZ = 1.0f / gridSize.y;

            // iterate all active terrains
            foreach (Terrain terrain in Terrain.activeTerrains)
            {
                // some integration tests just create a terrain component without terrain data
                if (terrain.terrainData == null)
                {
                    continue;
                }

                if ((filter == null) || filter(terrain))
                {
                    // convert position to a grid index, with proper rounding
                    Vector3 pos   = terrain.transform.position;
                    int     tileX = Mathf.RoundToInt((pos.x - gridOrigin.x) * gridScaleX);
                    int     tileZ = Mathf.RoundToInt((pos.z - gridOrigin.y) * gridScaleZ);
                    // attempt to add the terrain at that grid position
                    terrainMap.TryToAddTerrain(tileX, tileZ, terrain);
                }
            }

            // run validation to check alignment status
            if (fullValidation)
            {
                terrainMap.Validate();
            }

            return((terrainMap.m_terrainTiles.Count > 0) ? terrainMap : null);
        }
예제 #4
0
        static public TerrainMap CreateFromConnectedNeighbors(Terrain originTerrain, System.Predicate <Terrain> filter = null, bool fullValidation = true)
        {
            if (originTerrain == null)
            {
                return(null);
            }

            if (originTerrain.terrainData == null)
            {
                return(null);
            }

            TerrainMap terrainMap = new TerrainMap();

            Queue <QueueElement> todoQueue = new Queue <QueueElement>();

            todoQueue.Enqueue(new QueueElement(0, 0, originTerrain));

            int maxTerrains = Terrain.activeTerrains.Length;

            while (todoQueue.Count > 0)
            {
                QueueElement cur = todoQueue.Dequeue();
                if ((filter == null) || filter(cur.terrain))
                {
                    if (terrainMap.TryToAddTerrain(cur.tileX, cur.tileZ, cur.terrain))
                    {
                        // sanity check to stop bad neighbors causing infinite iteration
                        if (terrainMap.m_terrainTiles.Count > maxTerrains)
                        {
                            break;
                        }

                        if (cur.terrain.leftNeighbor != null)
                        {
                            todoQueue.Enqueue(new QueueElement(cur.tileX - 1, cur.tileZ, cur.terrain.leftNeighbor));
                        }
                        if (cur.terrain.bottomNeighbor != null)
                        {
                            todoQueue.Enqueue(new QueueElement(cur.tileX, cur.tileZ - 1, cur.terrain.bottomNeighbor));
                        }
                        if (cur.terrain.rightNeighbor != null)
                        {
                            todoQueue.Enqueue(new QueueElement(cur.tileX + 1, cur.tileZ, cur.terrain.rightNeighbor));
                        }
                        if (cur.terrain.topNeighbor != null)
                        {
                            todoQueue.Enqueue(new QueueElement(cur.tileX, cur.tileZ + 1, cur.terrain.topNeighbor));
                        }
                    }
                }
            }

            // run validation to check alignment status
            if (fullValidation)
            {
                terrainMap.Validate();
            }

            return(terrainMap);
        }