| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using Unity.Mathematics;
- using UnityEngine;
- using Random = UnityEngine.Random;
- public class MapGenerator : MonoBehaviour
- {
- public MapConfigSO mapConfig1;
- public MapConfigSO mapConfig2;
- public MapConfigSO mapConfig3;
- public Room roomPrefab;
- public LineRenderer linePrefab;
- private MapConfigSO mapConfig;
- private float screenHeight;
- private float screenWidth;
- private float columnWidth;
- public float border;
- private float distanceToCamera;
-
- private List<Room> rooms = new();
- private List<LineRenderer> lines = new();
- [Header("学习参数")] public int studyAbility = 1;
- private void Awake()
- {
- Camera cam = Camera.main;
- ChooseMap();
- // 计算当前物体所在平面到相机的距离
- distanceToCamera = Mathf.Abs(cam.transform.position.z - transform.position.z);
- // 根据透视相机计算可视范围
- screenHeight = 2f * distanceToCamera * Mathf.Tan(cam.fieldOfView * 0.5f * Mathf.Deg2Rad);
- screenWidth = screenHeight * cam.aspect;
- // 修复:考虑边框,计算实际可用宽度和列间距
- int columnCount = mapConfig.roomBlueprints.Count;
- float availableWidth = screenWidth - (border * 2); // 减去左右边框占用的宽度
- columnWidth = availableWidth / (columnCount + 1); // 这里+1是为了在首尾也留出边距
- }
- private void Start()
- {
- CreateMap();
- }
- public void ChooseMap()
- {
- if(studyAbility <= 5)
- {
- mapConfig = mapConfig1;
- }else if(studyAbility <= 10)
- {
- mapConfig = mapConfig2;
- }
- else
- {
- mapConfig = mapConfig3;
- }
- }
- public void CreateMap()
- {
- List<Room> previousColumnRooms = new();
- float left = -screenWidth / 2f;
- float top = screenHeight / 2f;
- for (int column = 0; column < mapConfig.roomBlueprints.Count; column++)
- {
- var blueprint = mapConfig.roomBlueprints[column];
- int amount = Random.Range(blueprint.min, blueprint.max);
- float roomGapY = screenHeight / (amount + 1);
- // 修复:重新计算x坐标,确保所有列都在可视范围内
- // 使用插值方式,第一列在左边距+border处,最后一列在右边距-border处
- float t = (float)column / (mapConfig.roomBlueprints.Count - 1); // 0到1之间的比例
- float x = left + border + (screenWidth - border * 2) * t;
-
- List<Room> currentColumnRooms = new();
- for (int i = 0; i < amount; i++)
- {
- float y = top - roomGapY * (i + 1);
- Vector3 pos = new Vector3(
- x,
- y,
- transform.position.z
- );
-
- var room = Instantiate(roomPrefab, pos, Quaternion.identity, transform);
- currentColumnRooms.Add(room);
- rooms.Add(room);
- }
- if (previousColumnRooms.Count > 0)
- {
- CreateConnections(previousColumnRooms,currentColumnRooms);
- }
-
- previousColumnRooms = currentColumnRooms;
- }
- }
- private void CreateConnections(List<Room> column1, List<Room> column2)
- {
- HashSet<Room> connectedColumn2Rooms = new();
- foreach (var room in column1)
- {
- var targetRoom = ConnectToRandomRoom(room,column2);
- connectedColumn2Rooms.Add(targetRoom);
- }
- foreach (var room in column2)
- {
- if (!connectedColumn2Rooms.Contains(room))
- {
- ConnectToRandomRoom(room,column1);
- }
- }
- }
- private Room ConnectToRandomRoom(Room room, List<Room> column2)
- {
- Room targetRoom;
- targetRoom = column2[Random.Range(0, column2.Count)];
-
- var line = Instantiate(linePrefab, transform);
- line.SetPosition(0, room.transform.position);
- line.SetPosition(1, targetRoom.transform.position);
-
- lines.Add(line);
- return targetRoom;
- }
- [ContextMenu("ReGenerateRoom")]
- public void ReGenerateRoom()
- {
- ChooseMap();
- foreach (var room in rooms)
- {
- Destroy(room.gameObject);
- }
- foreach (var line in lines)
- {
- Destroy(line.gameObject);
- }
-
- rooms.Clear();
- lines.Clear();
- CreateMap();
- }
- }
|