Files
Gen_Hack-and-Slash-Roguelite/Client/Assets/Scripts/Map/Dimension.cs

124 lines
4.3 KiB
C#
Raw Normal View History

using System.Threading.Tasks;
using Data;
using Managers;
using UnityEngine;
namespace Map
{
/// <summary>
/// 表示游戏中的一个维度或场景区域。
/// 实体管理器将根据此维度来组织和管理实体。
/// </summary>
public class Dimension : MonoBehaviour
{
[SerializeField] private bool defaultOpen = false;
2025-08-28 16:20:24 +08:00
[SerializeField]
[Tooltip("此维度的唯一标识符。如果为空将使用GameObject的名称。")]
private string _dimensionId;
[SerializeField] public Landform landform;
2025-08-28 16:20:24 +08:00
public Vector3 cameraPosition = new(0, 0, -10);
public Entity.Entity focusEntity;
public string mapGeneratorId;
public DimensionDef dimensionDefinition;
public Vector2Int DimensionSize { get;private set; }
public event System.Action<Dimension> OnDimensionLoaded;
/// <summary>
/// 获取此维度的唯一标识符。
/// </summary>
public string DimensionId
{
get
{
if (string.IsNullOrEmpty(_dimensionId))
{
_dimensionId = gameObject.name; // 如果未设置默认使用GameObject名称
}
return _dimensionId;
}
// 内部设置器允许在Awake中初始化或编辑器中赋值
private set => _dimensionId = value;
}
/// <summary>
/// 此维度下所有实体的根Transform。用于组织场景层级。
/// </summary>
public Transform DimensionRoot { get; private set; }
private void Awake()
{
// 1. 确保 DimensionId 已初始化,这会触发 DimensionId 属性的 getter 逻辑
var id = DimensionId;
// 2. 创建一个用于存放此维度下所有实体的根GameObject方便管理
var rootObj = new GameObject($"_Entities_{id}");
rootObj.transform.SetParent(this.transform); // 将其作为Dimension对象的子对象
DimensionRoot = rootObj.transform;
Program.Instance.RegisterDimension(this);
landform.Init();
if (defaultOpen)
{
Program.Instance.SetFocusedDimension(_dimensionId);
}
mapGeneratorId = Configs.ConfigManager.Instance.GetValue<string>(DimensionId);
if (!string.IsNullOrEmpty(mapGeneratorId))
{
dimensionDefinition=DefineManager.Instance.FindDefine<DimensionDef>(mapGeneratorId);
if (dimensionDefinition != null)
{
_=ApplyDimensionDef(dimensionDefinition);
}
}
}
private void OnDestroy()
{
// 当 Dimension 对象被销毁时(例如,场景卸载),从 Program 和 EntityManage 注销
if (Program.Instance != null) // 检查单例是否仍然存在
{
Program.Instance.UnregisterDimension(this);
}
}
private async Task ApplyDimensionDef(DimensionDef def)
{
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;
foreach (var defMapGenerator in def.mapGenerators)
{
await TileManager.Instance.ApplyMapGenerator(defMapGenerator.defName, landform);
}
}
OnDimensionLoaded.Invoke(this);
}
}
}