2025-10-03 00:31:34 +08:00
|
|
|
|
using System;
|
2025-09-19 08:26:54 +08:00
|
|
|
|
using System.Threading.Tasks;
|
2025-10-10 14:08:23 +08:00
|
|
|
|
using Configs;
|
2025-09-19 08:26:54 +08:00
|
|
|
|
using Data;
|
|
|
|
|
|
using Managers;
|
2025-08-27 19:56:49 +08:00
|
|
|
|
using UnityEngine;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
using UnityEngine.Tilemaps;
|
2025-08-27 19:56:49 +08:00
|
|
|
|
|
|
|
|
|
|
namespace Map
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 表示游戏中的一个维度或场景区域。
|
|
|
|
|
|
/// 实体管理器将根据此维度来组织和管理实体。
|
2025-08-27 19:56:49 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class Dimension : MonoBehaviour
|
|
|
|
|
|
{
|
2025-10-03 00:31:34 +08:00
|
|
|
|
[SerializeField] private bool defaultOpen;
|
2025-08-27 19:56:49 +08:00
|
|
|
|
|
2025-10-10 14:08:23 +08:00
|
|
|
|
[SerializeField] [Tooltip("此维度的唯一标识符。如果为空,将使用GameObject的名称。")]
|
2025-08-27 19:56:49 +08:00
|
|
|
|
private string _dimensionId;
|
|
|
|
|
|
|
2025-09-28 15:02:57 +08:00
|
|
|
|
[SerializeField] public Landform landform;
|
2025-08-28 16:20:24 +08:00
|
|
|
|
|
2025-09-28 15:02:57 +08:00
|
|
|
|
public Vector3 cameraPosition = new(0, 0, -10);
|
2025-09-03 19:59:22 +08:00
|
|
|
|
|
|
|
|
|
|
public Entity.Entity focusEntity;
|
2025-10-10 14:08:23 +08:00
|
|
|
|
public TileBase airWall;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
|
2025-09-19 08:26:54 +08:00
|
|
|
|
public DimensionDef dimensionDefinition;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
|
|
|
|
|
|
public Vector2Int DimensionSize { get; private set; }
|
|
|
|
|
|
|
2025-08-27 19:56:49 +08:00
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 获取此维度的唯一标识符。
|
2025-08-27 19:56:49 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string DimensionId
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
if (string.IsNullOrEmpty(_dimensionId)) _dimensionId = Guid.NewGuid().ToString();
|
2025-08-27 19:56:49 +08:00
|
|
|
|
|
|
|
|
|
|
return _dimensionId;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 内部设置器,允许在Awake中初始化或编辑器中赋值
|
|
|
|
|
|
private set => _dimensionId = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 此维度下所有实体的根Transform。用于组织场景层级。
|
2025-08-27 19:56:49 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Transform DimensionRoot { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
if (!airWall) airWall = Resources.Load<TileBase>("Tile/AirWall");
|
2025-09-28 15:02:57 +08:00
|
|
|
|
|
2025-10-03 00:31:34 +08:00
|
|
|
|
var id = DimensionId; // 确保 DimensionId 已初始化
|
2025-08-27 19:56:49 +08:00
|
|
|
|
var rootObj = new GameObject($"_Entities_{id}");
|
2025-10-03 00:31:34 +08:00
|
|
|
|
rootObj.transform.SetParent(transform);
|
2025-08-27 19:56:49 +08:00
|
|
|
|
DimensionRoot = rootObj.transform;
|
|
|
|
|
|
|
2025-09-28 15:02:57 +08:00
|
|
|
|
Program.Instance.RegisterDimension(this);
|
2025-10-10 14:08:23 +08:00
|
|
|
|
if (defaultOpen) Program.Instance.SetFocusedDimension(_dimensionId);
|
2025-08-27 19:56:49 +08:00
|
|
|
|
|
2025-10-10 14:08:23 +08:00
|
|
|
|
var mapGeneratorId = ConfigManager.Instance.GetValue<string>(DimensionId);
|
2025-09-19 08:26:54 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(mapGeneratorId))
|
|
|
|
|
|
{
|
2025-10-03 00:31:34 +08:00
|
|
|
|
dimensionDefinition = DefineManager.Instance.FindDefine<DimensionDef>(mapGeneratorId);
|
2025-10-10 14:08:23 +08:00
|
|
|
|
if (dimensionDefinition != null) _ = ApplyDimensionDef(dimensionDefinition);
|
2025-09-19 08:26:54 +08:00
|
|
|
|
}
|
2025-08-27 19:56:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDestroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Program.Instance != null) // 检查单例是否仍然存在
|
|
|
|
|
|
Program.Instance.UnregisterDimension(this);
|
|
|
|
|
|
}
|
2025-09-19 08:26:54 +08:00
|
|
|
|
|
2025-10-10 14:08:23 +08:00
|
|
|
|
public event Action<Dimension> OnDimensionLoaded;
|
|
|
|
|
|
|
2025-10-03 00:31:34 +08:00
|
|
|
|
/// <summary>
|
2025-10-10 14:08:23 +08:00
|
|
|
|
/// 应用维度定义,生成地图并设置边界。
|
2025-10-03 00:31:34 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="def">要应用的维度定义。</param>
|
|
|
|
|
|
public async Task ApplyDimensionDef(DimensionDef def)
|
2025-09-19 08:26:54 +08:00
|
|
|
|
{
|
2025-10-10 14:08:23 +08:00
|
|
|
|
dimensionDefinition = def;
|
2025-10-03 00:31:34 +08:00
|
|
|
|
landform.Clear();
|
|
|
|
|
|
var maxWidth = DimensionSize.x;
|
|
|
|
|
|
var maxHeight = DimensionSize.y;
|
2025-09-28 15:02:57 +08:00
|
|
|
|
|
2025-09-19 08:26:54 +08:00
|
|
|
|
if (def.mapGenerators != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var defMapGenerator in def.mapGenerators)
|
|
|
|
|
|
{
|
2025-09-28 15:02:57 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2025-10-03 00:31:34 +08:00
|
|
|
|
|
2025-09-28 15:02:57 +08:00
|
|
|
|
DimensionSize = new Vector2Int(maxWidth, maxHeight);
|
2025-10-03 00:31:34 +08:00
|
|
|
|
cameraPosition = new Vector3(DimensionSize.x / 2f, DimensionSize.y / 2f, -10) + transform.position;
|
2025-10-10 14:08:23 +08:00
|
|
|
|
landform.InitEntityCollisionArray(DimensionSize, new Vector2Int());
|
2025-09-28 15:02:57 +08:00
|
|
|
|
foreach (var defMapGenerator in def.mapGenerators)
|
|
|
|
|
|
await TileManager.Instance.ApplyMapGenerator(defMapGenerator.defName, landform);
|
2025-09-19 08:26:54 +08:00
|
|
|
|
}
|
2025-09-28 15:02:57 +08:00
|
|
|
|
|
2025-10-03 00:31:34 +08:00
|
|
|
|
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);
|
2025-09-19 08:26:54 +08:00
|
|
|
|
}
|
2025-08-27 19:56:49 +08:00
|
|
|
|
}
|
2025-10-10 14:08:23 +08:00
|
|
|
|
}
|