Пример #1
0
        private void Awake()
        {
            streetPieces = GetComponent <StreetPieces>();

            // Generate the Wellington layout.
            streetLayout = new Levels.Wellington();
            Generate();
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
        }