ProjectZ/Assets/Scripts/Level/BuildModules/ProceduralGeneration.cs

123 lines
4.4 KiB
C#
Raw Normal View History

2024-03-19 21:51:11 +03:00
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);
}
}
}
}