123 lines
4.4 KiB
C#
123 lines
4.4 KiB
C#
|
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<GameObject> prefabsList = new();
|
||
|
private readonly Dictionary<ModuleType, List<BuildModule>> _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<BoxCollider>();
|
||
|
BuildModuleType buildModuleType = prefab.GetComponent<BuildModuleType>();
|
||
|
|
||
|
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<BuildModule>();
|
||
|
}
|
||
|
|
||
|
_buildModules[type].Add(module);
|
||
|
}
|
||
|
|
||
|
private void Spawn(ModuleType type)
|
||
|
{
|
||
|
int x = 0;
|
||
|
int z = 0;
|
||
|
|
||
|
if (_buildModules.ContainsKey(type))
|
||
|
{
|
||
|
List<BuildModule> 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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|