using System.Collections.Generic; using UnityEngine; using System.Linq; public class MapGenManager : MonoBehaviour { [Header("Room Prefabs")] [SerializeField] private List mapPrefab = new List(); [SerializeField] private GameObject StartPoint; [SerializeField] private GameObject EndPoint; [Header("Player")] [SerializeField] private GameObject Player; [Header("Corridor Prefabs")] [SerializeField] private GameObject CorridorStraight; [SerializeField] private GameObject CorridorStraightUnlit; [SerializeField] private GameObject DoorCorridor; /*[SerializeField] private GameObject CorridorL; [SerializeField] private GameObject CorridorT; [SerializeField] private GameObject CorridorCross; [SerializeField] private GameObject CorridorEnd;*/ [Header("Generation Settings")] [SerializeField] private int RoomDistance = 3; [SerializeField] private int minRoomsNumber = 3; [SerializeField] private int maxRoomsNumber = 7; private List roomPositions = new List(); private List placedRooms = new List(); void Start() { MapGen(); } private void MapGen() { // Clear previous rooms and positions roomPositions.Clear(); placedRooms.Clear(); // Add Start Point Vector3 startPos = new Vector3(0, 0, 0); GameObject startPoint = Instantiate(StartPoint, startPos, Quaternion.identity, transform); roomPositions.Add(startPos); placedRooms.Add(startPoint); startPoint.GetComponent().SetEntrances(false, false, true, false); // Instantiate the player at the starting position GameObject player = Instantiate(Player, new Vector3(startPos.x, 1, startPos.z - 5), Quaternion.identity, transform); // Generate a random number of rooms int roomCount = Random.Range(minRoomsNumber, maxRoomsNumber); // Place Generate Rooms for (int i = 0; i < roomCount; i++) { GameObject roomPrefab = mapPrefab[Random.Range(0, mapPrefab.Count)]; Vector3 roomPos = GetGridPosition(roomPrefab); GameObject room = Instantiate(roomPrefab, roomPos, Quaternion.identity, transform); placedRooms.Add(room); roomPositions.Add(roomPos); room.GetComponent().SetEntrances(false, false, true, true); } // Add End Point GameObject endPoint = Instantiate(EndPoint, GetGridPosition(EndPoint), Quaternion.identity, transform); roomPositions.Add(endPoint.transform.position); placedRooms.Add(endPoint); endPoint.GetComponent().SetEntrances(false, false, false, false); // Create corridors between rooms for (int i = 0; i < roomPositions.Count - 1; i++) { Vector3 startRoomPos = roomPositions[i]; PrefabSize startRoom = placedRooms[i].GetComponent(); Vector3 endRoomPos = roomPositions[i + 1]; PrefabSize endRoom = placedRooms[i + 1].GetComponent(); Vector3 firstCorridorPos = new Vector3( startRoomPos.x, startRoomPos.y, startRoomPos.z + startRoom.prefabSize.y / 2 ); Vector3 lastCorridorPos = new Vector3( endRoomPos.x, endRoomPos.y, endRoomPos.z - endRoom.prefabSize.y / 2 ); CreateCorridor(firstCorridorPos, lastCorridorPos); } } private Vector3 GetGridPosition(GameObject roomPrefab) { Vector3 lastRoomPos = roomPositions[roomPositions.Count - 1]; PrefabSize lastRoom = placedRooms[placedRooms.Count - 1].GetComponent(); PrefabSize roomSize = roomPrefab.GetComponent(); Vector3 roomPos = new Vector3( lastRoomPos.x, lastRoomPos.y - 0.01f, lastRoomPos.z + lastRoom.prefabSize.y / 2f + roomSize.prefabSize.y / 2f + RoomDistance ); return roomPos; } private void CreateCorridor(Vector3 start, Vector3 end) { // Calculate the distance float distance = Vector3.Distance(start, end); PrefabSize corridorSize = CorridorStraight.GetComponent(); PrefabSize corridorUnlitSize = CorridorStraightUnlit.GetComponent(); PrefabSize doorSize = DoorCorridor.GetComponent(); // Calculate the number of corridors needed int corridorCount = Mathf.FloorToInt(distance / corridorSize.prefabSize.y); Debug.Log($"Creating {corridorCount} corridors from {start} to {end}"); // Create corridors //Start with door if (corridorCount > 0) { Vector3 doorPos = new Vector3( start.x, start.y, start.z + doorSize.prefabSize.y * 0.5f ); Quaternion doorRotation = Quaternion.Euler(0, 0, 0); GameObject doorCorridor = Instantiate(DoorCorridor, doorPos, doorRotation, transform); doorCorridor.GetComponent().OpenDoor(); for (int i = 1; i < corridorCount; i++) { if (i % 2 != 0) { // Create straight corridor Vector3 pos = new Vector3( start.x, start.y, start.z + i * corridorSize.prefabSize.y + corridorSize.prefabSize.y * 0.5f ); Quaternion rotation = Quaternion.Euler(0, 0, 0); GameObject corridor = Instantiate(CorridorStraight, pos, rotation, transform); } else { // Create unlit corridor Vector3 pos = new Vector3( start.x, start.y, start.z + i * corridorUnlitSize.prefabSize.y + corridorUnlitSize.prefabSize.y * 0.5f ); Quaternion rotation = Quaternion.Euler(0, 0, 0); GameObject corridorUnlit = Instantiate(CorridorStraightUnlit, pos, rotation, transform); } } } // If there is not enough space to create corridors, throw an exception else throw new System.Exception("Not enough space to create corridors"); } }