IEnumerator ConnectVillages(ChunkData chunkData) { //Cannot connect villages until all trees have been combined while (combineQueue.GetQueueSize() > 0) { yield return(null); } float maxDistanceBetweenPoints = ProceduralTerrain.Current.TerrainHouseData.MaxDistanceBetweenConnectionPoints; int maxNumberOfConnections = ProceduralTerrain.Current.TerrainHouseData.MaxNumberOfConnectionsPerVillage; //Foreach village center in this chunk foreach (GameObject villageCenter in chunkData.VillageCenterList) { //Get connection point GameObject connectionPoint1 = villageCenter.transform.FindChild("ConnectionPoint").gameObject; //If connection point can't be found, exit if (!connectionPoint1) { continue; } VillageConnectionData connectionData1 = connectionPoint1.GetComponent <VillageConnectionData>(); //Check there is less than max number of connections if (connectionData1.NumberOfConnections >= maxNumberOfConnections) { continue; } foreach (GameObject otherVillageCenter in chunkData.VillageCenterList) { //Make sure not comparing to self if (villageCenter == otherVillageCenter) { continue; } //If connection1 has reached its max number, break out of this loops if (connectionData1.NumberOfConnections >= maxNumberOfConnections) { break; } GameObject connectionPoint2 = otherVillageCenter.transform.FindChild("ConnectionPoint").gameObject; if (!connectionPoint2) { continue; } VillageConnectionData connectionData2 = connectionPoint2.GetComponent <VillageConnectionData>(); //Less than max number of connections and connection 1 has 1+ connection, prevents centers having no connections when close enough to other centers if (connectionData2.NumberOfConnections >= maxNumberOfConnections && connectionData1.NumberOfConnections != 0) { continue; } //Check these aren't already paired if (connectionData2.Connections.Contains(connectionPoint1)) { continue; } Vector3 pointA = connectionPoint1.transform.position; Vector3 pointB = connectionPoint2.transform.position; Vector3 halfwayPoint = (pointA + pointB) / 2; float distance = (pointA - pointB).magnitude; float treeHouseRadius = ProceduralTerrain.Current.TerrainHouseData.VillageCenterRadius; //From center point of tree house so bridge connects to outer edge not trunk //If the distance between the points is too large, go to next comparison if (distance > maxDistanceBetweenPoints) { continue; } //Check for collisions in the bridge area bool canPlace = true; Collider[] colliders = Physics.OverlapCapsule(pointA, pointB, 2); foreach (Collider coll in colliders) { //If colliding with terrain or a tree, don't build a bridge here if (coll.CompareTag("Terrain") || coll.CompareTag("Tree")) { canPlace = false; break; } //If colliding with a house if (coll.CompareTag("House")) { //If not colliding with a connection point's house, don't build a bridge if (coll.gameObject != connectionPoint1.transform.parent.gameObject && coll.gameObject != connectionPoint2.transform.parent.gameObject) { canPlace = false; break; } } } //If can't place, go to next connection point if (!canPlace) { continue; } //Create bridge GameObject bridge = Instantiate(ProceduralTerrain.Current.TerrainHouseData.BridgePrefab);//GameObject.CreatePrimitive(PrimitiveType.Cube); bridge.name = "Bridge"; bridge.transform.localScale = new Vector3(1, 1, distance - treeHouseRadius * 2); bridge.transform.position = halfwayPoint; bridge.transform.LookAt(pointB); bridge.transform.SetParent(villageCenter.transform); //Update connections on connection points connectionData1.AddConnection(connectionPoint2); connectionData2.AddConnection(connectionPoint1); } } yield return(null); }