using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class RoomType
{
public string name;
public int amount;
public GameObject roomPrefab;
}
public class GridGeneration : MonoBehaviour
{
public int gridWidth = 5;
public int gridHeight = 5;
public float cellSize = 1.0f;
public float cellSeparation = 0.1f;
public float gridYPosition = 0.0f;
public GameObject emptyCellPrefab;
public List<RoomType> roomTypes;
private string[,] grid;
private Dictionary<string, GameObject> placedRooms = new Dictionary<string, GameObject>();
private Dictionary<string, Color> roomColors = new Dictionary<string, Color>();
void Start()
{
grid = new string[gridWidth, gridHeight];
GenerateGrid();
StartCoroutine(PlaceRoomsFromListCoroutine());
StartCoroutine(VisualizeGridCoroutine());
}
void GenerateGrid()
{
for (int row = 0; row < gridHeight; row++)
{
for (int col = 0; col < gridWidth; col++)
{
grid[col, row] = "empty";
}
}
}
IEnumerator PlaceRoomsFromListCoroutine()
{
foreach (RoomType room in roomTypes)
{
if (!roomColors.ContainsKey(room.name))
{
roomColors[room.name] = new Color(Random.value, Random.value, Random.value);
}
for (int i = 0; i < room.amount; i++)
{
bool placed = false;
for (int attempt = 0; attempt < 100 && !placed; attempt++) // Limit retries
{
int randomCol = Random.Range(0, gridWidth);
int randomRow = Random.Range(0, gridHeight);
if (grid[randomCol, randomRow] == "empty")
{
for (int rotation = 0; rotation < 4; rotation++) // Try all rotations
{
if (CanPlaceRoom(randomCol, randomRow, room.roomPrefab, rotation))
{
PlaceRoom(randomCol, randomRow, room.roomPrefab, rotation, room.name);
placed = true;
break;
}
}
}
}
if (!placed)
{
Debug.LogWarning($"Skipped placing room {room.name} after multiple attempts.");
}
yield return null; // Wait for next frame
}
}
}
bool CanPlaceRoom(int col, int row, GameObject roomPrefab, int rotation)
{
GameObject tempRoom = Instantiate(roomPrefab, Vector3.zero, Quaternion.Euler(0, rotation * 90, 0));
RoomValidator validator = tempRoom.GetComponent<RoomValidator>();
if (validator == null)
{
Debug.LogError($"RoomPrefab '{roomPrefab.name}' is missing a RoomValidator component!");
Destroy(tempRoom);
return false;
}
bool valid = true;
foreach (Transform opening in validator.openings)
{
Vector3 worldPos = tempRoom.transform.TransformPoint(opening.localPosition);
Vector3Int gridPos = WorldToGrid(worldPos);
if (!IsValidGridPosition(gridPos) || grid[gridPos.x, gridPos.z] != "empty")
{
valid = false;
break;
}
}
foreach (Transform wall in validator.walls)
{
Vector3 worldPos = tempRoom.transform.TransformPoint(wall.localPosition);
Vector3Int gridPos = WorldToGrid(worldPos);
if (IsValidGridPosition(gridPos) && grid[gridPos.x, gridPos.z] != "empty")
{
valid = false;
break;
}
}
Destroy(tempRoom);
return valid;
}
void PlaceRoom(int col, int row, GameObject roomPrefab, int rotation, string roomName)
{
Vector3 position = GridToWorld(col, row);
GameObject room = Instantiate(roomPrefab, position, Quaternion.Euler(0, rotation * 90, 0));
// Scale the room based on the cell size (instead of using Renderer)
room.transform.localScale = new Vector3(cellSize, cellSize, cellSize); // Adjust XYZ as needed
grid[col, row] = roomName;
placedRooms[$"{col},{row}"] = room;
}
Vector3Int WorldToGrid(Vector3 worldPosition)
{
float startX = transform.position.x - (gridWidth * 0.5f * (cellSize + cellSeparation));
float startZ = transform.position.z - (gridHeight * 0.5f * (cellSize + cellSeparation));
int col = Mathf.RoundToInt((float)((worldPosition.x - startX) / (cellSize + cellSeparation))); // Explizites Casting auf float
int row = Mathf.RoundToInt((float)((worldPosition.z - startZ) / (cellSize + cellSeparation))); // Explizites Casting auf float
return new Vector3Int(col, 0, row);
}
Vector3 GridToWorld(int col, int row)
{
float startX = transform.position.x - (gridWidth * 0.5f * (cellSize + cellSeparation));
float startZ = transform.position.z - (gridHeight * 0.5f * (cellSize + cellSeparation));
float x = startX + col * (cellSize + cellSeparation);
float z = startZ + row * (cellSize + cellSeparation);
return new Vector3(x, gridYPosition, z);
}
bool IsValidGridPosition(Vector3Int gridPos)
{
return gridPos.x >= 0 && gridPos.x < gridWidth && gridPos.z >= 0 && gridPos.z < gridHeight;
}
IEnumerator VisualizeGridCoroutine()
{
// Create a copy of the dictionary values or keys to avoid modifying the collection while iterating
var rooms = new List<GameObject>(placedRooms.Values);
foreach (var room in rooms)
{
// If you need any other visualization, you can directly modify the room transform here
// For example, you could add a Debug.Log or change the position/scale dynamically
yield return null;
}
}
}
using UnityEngine;
using System.Collections.Generic;
public class RoomValidator : MonoBehaviour
{
public List<Transform> openings; // Points for door connections
public List<Transform> walls; // Points for wall collision checks
}
this is my current script
rn its such a mess, it either says it cant place rooms or just places them facing wall to opening, looking forward to an reply
like fr im lost, pls help