| using UnityEngine; |
|
|
| namespace UnityAgent |
| { |
| |
| |
| |
| |
| |
| public class CityGenerator : MonoBehaviour |
| { |
| [Header("Grid")] |
| public int gridX = 8; |
| public int gridZ = 8; |
| public float blockSpacing = 30f; |
|
|
| [Header("Buildings")] |
| public int buildingsPerBlock = 1; |
| public float minBuildingHeight = 8f; |
| public float maxBuildingHeight = 40f; |
| public float buildingFootprint = 8f; |
| public Color wallColor = new Color(0.4f, 0.4f, 0.42f); |
| public Color windowColor = new Color(1.0f, 0.85f, 0.4f); |
|
|
| [Header("Street Lights")] |
| public bool spawnStreetLights = true; |
| public float lightSpacing = 15f; |
| public Color lightColor = new Color(1.0f, 0.85f, 0.5f); |
| public float lightIntensity = 1.5f; |
| public float lightRange = 15f; |
|
|
| private readonly System.Collections.Generic.List<Light> _lights = new System.Collections.Generic.List<Light>(); |
|
|
| private void Start() |
| { |
| Generate(); |
| } |
|
|
| public void Generate() |
| { |
| Material wallMat = BuildingGenerator.MakeWallMaterial(wallColor); |
| Material winMat = BuildingGenerator.MakeWindowMaterial(windowColor); |
|
|
| float totalX = (gridX - 1) * blockSpacing; |
| float totalZ = (gridZ - 1) * blockSpacing; |
| Vector3 origin = transform.position - new Vector3(totalX * 0.5f, 0f, totalZ * 0.5f); |
|
|
| for (int x = 0; x < gridX; x++) |
| { |
| for (int z = 0; z < gridZ; z++) |
| { |
| Vector3 block = new Vector3(origin.x + x * blockSpacing, 0f, origin.z + z * blockSpacing); |
| SpawnBlock(block, wallMat, winMat); |
| } |
| } |
|
|
| if (spawnStreetLights) SpawnStreetLights(origin, totalX, totalZ); |
| } |
|
|
| private void SpawnBlock(Vector3 center, Material wallMat, Material winMat) |
| { |
| for (int i = 0; i < buildingsPerBlock; i++) |
| { |
| float h = Random.Range(minBuildingHeight, maxBuildingHeight); |
| Vector3 size = new Vector3(buildingFootprint, h, buildingFootprint); |
| Vector3 pos = center + new Vector3( |
| Random.Range(-4f, 4f), 0f, Random.Range(-4f, 4f)); |
| BuildingGenerator.Generate($"Building_{center.x}_{center.z}_{i}", pos, size, wallMat, winMat); |
| } |
| } |
|
|
| private void SpawnStreetLights(Vector3 origin, float totalX, float totalZ) |
| { |
| Material poleMat = BuildingGenerator.MakeWallMaterial(new Color(0.1f, 0.1f, 0.1f)); |
|
|
| for (float x = origin.x; x <= origin.x + totalX + 0.1f; x += lightSpacing) |
| { |
| for (float z = origin.z; z <= origin.z + totalZ + 0.1f; z += lightSpacing) |
| { |
| SpawnStreetLight(new Vector3(x, 0f, z), poleMat); |
| } |
| } |
| } |
|
|
| private void SpawnStreetLight(Vector3 pos, Material poleMat) |
| { |
| GameObject pole = GameObject.CreatePrimitive(PrimitiveType.Cylinder); |
| pole.name = "StreetLight"; |
| pole.transform.SetParent(transform, false); |
| pole.transform.position = pos + Vector3.up * 4f; |
| pole.transform.localScale = new Vector3(0.2f, 4f, 0.2f); |
| pole.GetComponent<MeshRenderer>().sharedMaterial = poleMat; |
|
|
| GameObject bulb = GameObject.CreatePrimitive(PrimitiveType.Sphere); |
| bulb.transform.SetParent(pole.transform, false); |
| bulb.transform.localPosition = Vector3.up * 0.9f; |
| bulb.transform.localScale = Vector3.one * 0.4f; |
| bulb.GetComponent<MeshRenderer>().sharedMaterial = BuildingGenerator.MakeWindowMaterial(lightColor); |
|
|
| Light l = bulb.AddComponent<Light>(); |
| l.type = LightType.Point; |
| l.color = lightColor; |
| l.intensity = lightIntensity; |
| l.range = lightRange; |
| _lights.Add(l); |
| } |
|
|
| public Light[] StreetLights => _lights.ToArray(); |
| } |
| } |
|
|