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); }
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); } } }
// 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); }
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); }