using System.Collections.Generic; using System.Numerics; using Unity.Mathematics; using UnityEngine; using UnityEngine.Serialization; using Quaternion = UnityEngine.Quaternion; using Random = UnityEngine.Random; using Vector3 = UnityEngine.Vector3; public class ProceduralGeneration : MonoBehaviour { [FormerlySerializedAs("PrefabsList")] public List prefabsList = new(); private readonly Dictionary> _buildModules = new(); public GameObject outerWall; public int maxX = 6; public int maxZ = 6; void Start() { FillDictionary(); SpawnOuterWalls(); Spawn(ModuleType.Floor); Spawn(ModuleType.Wall); } private void FillDictionary() { foreach (var prefab in prefabsList) { BoxCollider boxCollider = prefab.GetComponent(); BuildModuleType buildModuleType = prefab.GetComponent(); if (boxCollider != null || buildModuleType != null) { ModuleType moduleType = buildModuleType.moduleType; Vector3 size = buildModuleType.dimensions == Vector3.zero ? boxCollider.size : buildModuleType.dimensions; Vector3 dimensions = new Vector3(math.floor(size.x), math.floor(size.y), math.floor(size.z)); BuildModule buildModule = new BuildModule(dimensions, buildModuleType.offset, prefab); print("Prefab dimensions: " + prefab.name + ": x - " + dimensions.x + "m, y - " + dimensions.y + "m, z - " + dimensions.z + "m"); AddBuildModule(moduleType, buildModule); } else { Debug.LogWarning("Prefab " + prefab.name + " does not have a Renderer component"); } } } private void AddBuildModule(ModuleType type, BuildModule module) { if (!_buildModules.ContainsKey(type)) { _buildModules[type] = new List(); } _buildModules[type].Add(module); } private void Spawn(ModuleType type) { int x = 0; int z = 0; if (_buildModules.ContainsKey(type)) { List buildModules = _buildModules[type]; for (int i = 0; i < (maxX * maxZ); i++) { if (type != ModuleType.Wall || (x > 0 && x < maxX - 1 && z > 0 && z < maxZ - 1)) { BuildModule buildModule = buildModules[Random.Range(0, buildModules.Count)]; Vector3 position = new Vector3(buildModule.Dimensions.x * x, 0, buildModule.Dimensions.z * z) + buildModule.Offset; Quaternion rotation = Quaternion.identity; if (type == ModuleType.Wall) { int randomRotation = Random.Range(0, 2); rotation = Quaternion.Euler(0, 90 * randomRotation, 0); } Instantiate(buildModule.Prefab, position, rotation); } x++; if (x >= maxZ) { x = 0; z++; } } } } private void SpawnOuterWalls() { for (int i = 1; i <= 2; i++) { var wallCount = i == 1 ? maxX : maxZ; var oppositeWallCount = i == 1 ? maxZ : maxX; var axis = i == 1 ? Vector3.forward : Vector3.right; var oppositeAxis = i == 1 ? Vector3.right : Vector3.forward; var angle = i == 1 ? 0f : 90f; for (int j = 0; j < wallCount; j++) { Vector3 wallPosition = axis * j * 6f; Quaternion wallRotation = Quaternion.Euler(0, angle, 0); Instantiate(outerWall, wallPosition, wallRotation); Instantiate(outerWall, wallPosition + oppositeAxis * oppositeWallCount * 6f, wallRotation); } } } }