using System; using System.Threading.Tasks; using Configs; using Data; using Managers; using UnityEngine; using UnityEngine.Tilemaps; namespace Map { /// /// 表示游戏中的一个维度或场景区域。 /// 实体管理器将根据此维度来组织和管理实体。 /// public class Dimension : MonoBehaviour { [SerializeField] private bool defaultOpen; [SerializeField] [Tooltip("此维度的唯一标识符。如果为空,将使用GameObject的名称。")] private string _dimensionId; [SerializeField] public Landform landform; public Vector3 cameraPosition = new(0, 0, -10); public Entity.Entity focusEntity; public TileBase airWall; public DimensionDef dimensionDefinition; public Vector2Int DimensionSize { get; private set; } /// /// 获取此维度的唯一标识符。 /// public string DimensionId { get { if (string.IsNullOrEmpty(_dimensionId)) _dimensionId = Guid.NewGuid().ToString(); return _dimensionId; } // 内部设置器,允许在Awake中初始化或编辑器中赋值 private set => _dimensionId = value; } /// /// 此维度下所有实体的根Transform。用于组织场景层级。 /// public Transform DimensionRoot { get; private set; } private void Awake() { if (!airWall) airWall = Resources.Load("Tile/AirWall"); var id = DimensionId; // 确保 DimensionId 已初始化 var rootObj = new GameObject($"_Entities_{id}"); rootObj.transform.SetParent(transform); DimensionRoot = rootObj.transform; Program.Instance.RegisterDimension(this); if (defaultOpen) Program.Instance.SetFocusedDimension(_dimensionId); var mapGeneratorId = ConfigManager.Instance.GetValue(DimensionId); if (!string.IsNullOrEmpty(mapGeneratorId)) { dimensionDefinition = DefineManager.Instance.FindDefine(mapGeneratorId); if (dimensionDefinition != null) _ = ApplyDimensionDef(dimensionDefinition); } } private void OnDestroy() { if (Program.Instance != null) // 检查单例是否仍然存在 Program.Instance.UnregisterDimension(this); } public event Action OnDimensionLoaded; /// /// 应用维度定义,生成地图并设置边界。 /// /// 要应用的维度定义。 public async Task ApplyDimensionDef(DimensionDef def) { dimensionDefinition = def; landform.Clear(); var maxWidth = DimensionSize.x; var maxHeight = DimensionSize.y; if (def.mapGenerators != null) { foreach (var defMapGenerator in def.mapGenerators) { var workClass = TileManager.Instance.GetMapGeneratorWorkClass(defMapGenerator.defName); if (workClass == null) continue; var requiredSize = workClass.GetSize(); maxWidth = Mathf.Max(maxWidth, requiredSize.x); maxHeight = Mathf.Max(maxHeight, requiredSize.y); } DimensionSize = new Vector2Int(maxWidth, maxHeight); cameraPosition = new Vector3(DimensionSize.x / 2f, DimensionSize.y / 2f, -10) + transform.position; landform.InitEntityCollisionArray(DimensionSize, new Vector2Int()); foreach (var defMapGenerator in def.mapGenerators) await TileManager.Instance.ApplyMapGenerator(defMapGenerator.defName, landform); } var size = landform.GetSize(); var origin = landform.GetOrigin(); var minX = origin.x; var minY = origin.y; var maxX = origin.x + size.x - 1; var maxY = origin.y + size.y - 1; const int borderWidth = 1; var airWallZ = origin.z; // 绘制上下边界 for (var x = minX - borderWidth; x <= maxX + borderWidth; x++) { landform.SetBaseTile(airWall, new Vector3Int(x, maxY + borderWidth, airWallZ)); landform.SetBaseTile(airWall, new Vector3Int(x, minY - borderWidth, airWallZ)); } // 绘制左右边界 for (var y = minY - borderWidth + 1; y <= maxY + borderWidth - 1; y++) { landform.SetBaseTile(airWall, new Vector3Int(minX - borderWidth, y, airWallZ)); // 左侧 landform.SetBaseTile(airWall, new Vector3Int(maxX + borderWidth, y, airWallZ)); // 右侧 } OnDimensionLoaded?.Invoke(this); } } }