private void Awake() { streetPieces = GetComponent <StreetPieces>(); // Generate the Wellington layout. streetLayout = new Levels.Wellington(); Generate(); }
public void Generate(City city) { // Create the intersection game object as a child of Intersections. gameObject = new GameObject($"Intersection ({position.x}, {position.y})"); gameObject.transform.parent = city.transform.Find("Intersections"); // Position in the game world. Vector2 size = GetSize(); gameObject.transform.localPosition = new Vector3 { x = position.x - size.x / 2, z = position.y - size.y / 2 }; // Set bounds. bounds = new Bounds { center = new Vector3(position.x, City.boundsBaseY + City.boundsHeight / 2, position.y), size = new Vector3(size.x, City.boundsHeight, size.y) }; // Place prefabs. StreetPieces streetPieces = city.streetPieces; GameObject road = streetPieces.Instantiate(streetPieces.roadPrefab, gameObject); road.transform.localScale = new Vector3(size.x, 1, size.y); // Place sidewalk corners or sides. void CreateCorner(float rotation, float x, float z) { GameObject corner = streetPieces.Instantiate(streetPieces.sidewalkCornerPrefab, gameObject); corner.transform.localScale = new Vector3(City.sidewalkWidth, 1, City.sidewalkWidth); corner.transform.localRotation = Quaternion.Euler(0, rotation, 0); corner.transform.localPosition = new Vector3 { x = x, z = z }; } if (southStreet != null && westStreet != null) { CreateCorner(0, 0, 0); } if (northStreet != null && westStreet != null) { CreateCorner(90, 0, size.y); } if (northStreet != null && eastStreet != null) { CreateCorner(180, size.x, size.y); } if (southStreet != null && eastStreet != null) { CreateCorner(270, size.x, 0); } if (northStreet == null) { GameObject sidewalk = streetPieces.Instantiate(streetPieces.sidewalkPrefab, gameObject); sidewalk.transform.localScale = new Vector3(size.x, 1, City.sidewalkWidth); sidewalk.transform.localPosition = new Vector3 { z = size.y - City.sidewalkWidth }; } if (southStreet == null) { GameObject sidewalk = streetPieces.Instantiate(streetPieces.sidewalkPrefab, gameObject); sidewalk.transform.localScale = new Vector3(size.x, 1, City.sidewalkWidth); } if (eastStreet == null) { GameObject sidewalk = streetPieces.Instantiate(streetPieces.sidewalkPrefab, gameObject); sidewalk.transform.localScale = new Vector3(City.sidewalkWidth, 1, size.y); sidewalk.transform.localPosition = new Vector3 { x = size.x - City.sidewalkWidth }; } if (westStreet == null) { GameObject sidewalk = streetPieces.Instantiate(streetPieces.sidewalkPrefab, gameObject); sidewalk.transform.localScale = new Vector3(City.sidewalkWidth, 1, size.y); } // Place lines if one street has priority. bool hasLinesNorthSouth = false; bool hasLinesEastWest = false; Street northSouthStreet = northStreet ?? southStreet; Street eastWestStreet = eastStreet ?? westStreet; if (isFourWayIntersection) { // 4-way intersections have lines where there are no stop signs on both ends. hasLinesEastWest = !HasStopLineForStreet(eastStreet) && !HasStopLineForStreet(westStreet); hasLinesNorthSouth = !HasStopLineForStreet(northStreet) && !HasStopLineForStreet(southStreet); } else if (isTIntersection) { // T intersections always have priority on the street that doesn't end. hasLinesEastWest = northStreet == null || southStreet == null; hasLinesNorthSouth = eastStreet == null || westStreet == null; } if (hasLinesNorthSouth) { var brokenLineXCoordinates = new List <float>(); if (northSouthStreet.isOneWay) { brokenLineXCoordinates.Add(size.x / 2); } else { GameObject centerLine = streetPieces.Instantiate(streetPieces.solidLinePrefab, gameObject); centerLine.transform.localScale = new Vector3(1, 1, size.y); centerLine.transform.localPosition = new Vector3 { x = size.x / 2 }; } for (int i = 2; i < northSouthStreet.lanesCount; i += 2) { float sideOffset = City.sidewalkWidth + City.laneWidth * (i / 2); brokenLineXCoordinates.Add(sideOffset); brokenLineXCoordinates.Add(size.x - sideOffset); } foreach (float xCoordinate in brokenLineXCoordinates) { GameObject laneLine = streetPieces.Instantiate(streetPieces.brokenLinePrefab, gameObject); laneLine.transform.localScale = new Vector3(1, 1, size.y); laneLine.transform.localPosition = new Vector3 { x = xCoordinate }; StreetPieces.ChangeBrokenLineTiling(laneLine); } } if (hasLinesEastWest) { var brokenLineZCoordinates = new List <float>(); if (eastWestStreet.isOneWay) { brokenLineZCoordinates.Add(size.y / 2); } else { GameObject centerLine = streetPieces.Instantiate(streetPieces.solidLinePrefab, gameObject); centerLine.transform.localScale = new Vector3(1, 1, size.x); centerLine.transform.localRotation = Quaternion.Euler(0, 90, 0); centerLine.transform.localPosition = new Vector3 { z = size.y / 2 }; } for (int i = 2; i < eastWestStreet.lanesCount; i += 2) { float sideOffset = City.sidewalkWidth + City.laneWidth * (i / 2); brokenLineZCoordinates.Add(sideOffset); brokenLineZCoordinates.Add(size.y - sideOffset); } foreach (float zCoordinate in brokenLineZCoordinates) { GameObject laneLine = streetPieces.Instantiate(streetPieces.brokenLinePrefab, gameObject); laneLine.transform.localScale = new Vector3(1, 1, size.x); laneLine.transform.localRotation = Quaternion.Euler(0, 90, 0); laneLine.transform.localPosition = new Vector3 { z = zCoordinate }; StreetPieces.ChangeBrokenLineTiling(laneLine); } } // Place buildings in 4 corners. void CreateBuilding(float x, float z, float width = City.minBuildingLength, float depth = City.minBuildingLength) { GameObject building = streetPieces.Instantiate(streetPieces.buildingPrefab, gameObject); building.transform.localScale = new Vector3(width, City.buildingHeights[1], depth); building.transform.localPosition = new Vector3(x, 0, z); } CreateBuilding(-City.minBuildingLength, -City.minBuildingLength); CreateBuilding(-City.minBuildingLength, size.y); CreateBuilding(size.x, -City.minBuildingLength); CreateBuilding(size.x, size.y); // Place buildings in directions where there is no street. if (northStreet == null) { CreateBuilding(0, size.y, width: size.x); } if (southStreet == null) { CreateBuilding(0, -City.minBuildingLength, width: size.x); } if (eastStreet == null) { CreateBuilding(size.x, 0, depth: size.y); } if (westStreet == null) { CreateBuilding(-City.minBuildingLength, 0, depth: size.y); } }
public void Generate(City city) { // Create the street game object as a child of Streets. gameObject = new GameObject(); gameObject.transform.parent = city.transform.Find("Streets"); // Calculate size and position in the game world. Vector2 startIntersectionHalfSize = startIntersection.GetSize() / 2; Vector2 endIntersectionHalfSize = endIntersection.GetSize() / 2; float roadWidth = lanesCount * City.laneWidth; width = roadWidth + 2 * City.sidewalkWidth; Vector3 boundsOrigin; Vector3 boundsSize; if (orientation == StreetOrientation.EastWest) { gameObject.name = $"Street ({startIntersection.position.x}-{startIntersection.position.x}, {endIntersection.position.y})"; length = endIntersection.position.x - startIntersection.position.x - startIntersectionHalfSize.x - endIntersectionHalfSize.x; gameObject.transform.localPosition = new Vector3 { x = startIntersection.position.x + startIntersectionHalfSize.x, z = startIntersection.position.y + width / 2 }; // Rotate the road so the local Z axis goes in the positive global X direction. gameObject.transform.localRotation = Quaternion.Euler(0, 90, 0); boundsOrigin = gameObject.transform.localPosition; boundsOrigin.z -= width; boundsSize = new Vector3(length, City.boundsHeight, width); } else { gameObject.name = $"Street ({startIntersection.position.x}, {startIntersection.position.y}-{endIntersection.position.y})"; length = endIntersection.position.y - startIntersection.position.y - startIntersectionHalfSize.y - endIntersectionHalfSize.y; gameObject.transform.localPosition = new Vector3 { x = startIntersection.position.x - width / 2, z = startIntersection.position.y + startIntersectionHalfSize.y }; boundsOrigin = gameObject.transform.localPosition; boundsSize = new Vector3(width, City.boundsHeight, length); } // Set bounds. bounds = new Bounds { min = boundsOrigin + new Vector3(0, City.boundsBaseY, 0), max = boundsOrigin + boundsSize }; // Place prefabs. StreetPieces streetPieces = city.streetPieces; GameObject road = streetPieces.Instantiate(streetPieces.roadPrefab, gameObject); road.transform.localScale = new Vector3(roadWidth, 1, length); road.transform.localPosition = new Vector3 { x = City.sidewalkWidth }; GameObject sidewalkLeft = streetPieces.Instantiate(streetPieces.sidewalkPrefab, gameObject); sidewalkLeft.transform.localScale = new Vector3(City.sidewalkWidth, 1, length); GameObject sidewalkRight = streetPieces.Instantiate(streetPieces.sidewalkPrefab, gameObject); sidewalkRight.transform.localScale = new Vector3(City.sidewalkWidth, 1, length); sidewalkRight.transform.localPosition = new Vector3 { x = width - City.sidewalkWidth }; // Place lane division lines. var brokenLineXCoordinates = new List <float>(); if (isOneWay) { brokenLineXCoordinates.Add(width / 2); } else { GameObject centerLine = streetPieces.Instantiate(streetPieces.solidLinePrefab, gameObject); centerLine.transform.localScale = new Vector3(1, 1, length); centerLine.transform.localPosition = new Vector3 { x = width / 2 }; } for (int i = 2; i < lanesCount; i += 2) { float sideOffset = City.sidewalkWidth + City.laneWidth * (i / 2); brokenLineXCoordinates.Add(sideOffset); brokenLineXCoordinates.Add(width - sideOffset); } foreach (float xCoordinate in brokenLineXCoordinates) { GameObject laneLine = streetPieces.Instantiate(streetPieces.brokenLinePrefab, gameObject); laneLine.transform.localScale = new Vector3(1, 1, length); laneLine.transform.localPosition = new Vector3 { x = xCoordinate }; StreetPieces.ChangeBrokenLineTiling(laneLine); } GameObject CreateStopLine() { GameObject stopLine = streetPieces.Instantiate(streetPieces.solidLinePrefab, gameObject); float lineLength = roadWidth; if (!isOneWay) { lineLength /= 2; } stopLine.transform.localScale = new Vector3(1, 1, lineLength); return(stopLine); } // Place intersection stop lines. if (endIntersection.HasStopLineForStreet(this)) { GameObject stopLine = CreateStopLine(); stopLine.transform.localRotation = Quaternion.Euler(0, 90, 0); stopLine.transform.localPosition = new Vector3 { x = City.sidewalkWidth, z = length - City.lineWidth / 2 }; } if (startIntersection.HasStopLineForStreet(this)) { GameObject stopLine = CreateStopLine(); stopLine.transform.localRotation = Quaternion.Euler(0, 270, 0); stopLine.transform.localPosition = new Vector3 { x = width - City.sidewalkWidth, z = City.lineWidth / 2 }; } // Place buildings. void CreateBuilding(float x, float z, float depth, int heightIndex) { GameObject building = streetPieces.Instantiate(streetPieces.buildingPrefab, gameObject); building.transform.localScale = new Vector3(City.buildingWidth, City.buildingHeights[heightIndex], depth); building.transform.localPosition = new Vector3(x, 0, z); } void PlaceBuildings(float z, float depth) { CreateBuilding(-City.buildingWidth, z, depth, Random.Range(0, City.buildingHeights.Length)); CreateBuilding(width, z, depth, Random.Range(0, City.buildingHeights.Length)); } void PlaceBuildingsInRange(float minZ, float maxZ) { // See if we could put 2 or more buildings in this range. if (maxZ - minZ < City.minBuildingLength * 2) { // No, this should be 1 building. PlaceBuildings(minZ, maxZ - minZ); } else { // Yes, split into two parts. float midZ = Random.Range(minZ + City.minBuildingLength, maxZ - City.minBuildingLength); PlaceBuildingsInRange(minZ, midZ); PlaceBuildingsInRange(midZ, maxZ); } } PlaceBuildingsInRange(City.minBuildingLength, length - City.minBuildingLength); }