地图系统
This commit is contained in:
76
Assets/_Game/Scripts/World/Map/RegionRegistrySO.cs
Normal file
76
Assets/_Game/Scripts/World/Map/RegionRegistrySO.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BaseGames.World.Map
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局区域注册表 SO。
|
||||
///
|
||||
/// 设计原则:<see cref="MapRoomDataSO.RegionId"/> 是房间归属的单一权威来源。
|
||||
/// 本 SO 持有所有 <see cref="RegionDefinitionSO"/> 资产引用,运行时从
|
||||
/// <see cref="MapDatabaseSO"/> 惰性构建 SceneName → Region 缓存,
|
||||
/// 消除了原 RegionDefinitionSO.roomSceneNames 与 MapRoomDataSO.RegionId 的双重冗余。
|
||||
///
|
||||
/// 资产路径:Assets/_Game/Data/Map/RegionRegistry.asset
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "BaseGames/Map/RegionRegistry", fileName = "RegionRegistry")]
|
||||
public class RegionRegistrySO : ScriptableObject
|
||||
{
|
||||
[Tooltip("项目中所有 RegionDefinitionSO 资产。新增区域 SO 时同步添加到此数组。")]
|
||||
[SerializeField] private RegionDefinitionSO[] _regions;
|
||||
|
||||
[Tooltip("地图数据库,用于从 MapRoomDataSO.RegionId 构建 SceneName → Region 缓存(单一权威来源)。")]
|
||||
[SerializeField] private MapDatabaseSO _mapDatabase;
|
||||
|
||||
private Dictionary<string, RegionDefinitionSO> _regionById;
|
||||
private Dictionary<string, RegionDefinitionSO> _sceneToRegion;
|
||||
|
||||
/// <summary>根据场景名(MapRoomDataSO.RoomId)查找所属区域;未找到返回 null。</summary>
|
||||
public RegionDefinitionSO FindBySceneName(string sceneName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sceneName)) return null;
|
||||
BuildCacheIfNeeded();
|
||||
_sceneToRegion.TryGetValue(sceneName, out var region);
|
||||
return region;
|
||||
}
|
||||
|
||||
/// <summary>根据 regionId 直接查找;未找到返回 null。</summary>
|
||||
public RegionDefinitionSO FindById(string regionId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(regionId)) return null;
|
||||
BuildCacheIfNeeded();
|
||||
_regionById.TryGetValue(regionId, out var region);
|
||||
return region;
|
||||
}
|
||||
|
||||
private void BuildCacheIfNeeded()
|
||||
{
|
||||
if (_sceneToRegion != null) return;
|
||||
|
||||
// Step 1: regionId → RegionDefinitionSO
|
||||
_regionById = new Dictionary<string, RegionDefinitionSO>(System.StringComparer.OrdinalIgnoreCase);
|
||||
if (_regions != null)
|
||||
foreach (var r in _regions)
|
||||
if (r != null && !string.IsNullOrEmpty(r.regionId))
|
||||
_regionById[r.regionId] = r;
|
||||
|
||||
// Step 2: sceneName → RegionDefinitionSO,以 MapRoomDataSO.RegionId 为权威来源
|
||||
_sceneToRegion = new Dictionary<string, RegionDefinitionSO>(System.StringComparer.OrdinalIgnoreCase);
|
||||
if (_mapDatabase?.AllRooms == null) return;
|
||||
|
||||
foreach (var room in _mapDatabase.AllRooms)
|
||||
{
|
||||
if (room == null || string.IsNullOrEmpty(room.RoomId) || string.IsNullOrEmpty(room.RegionId))
|
||||
continue;
|
||||
if (_regionById.TryGetValue(room.RegionId, out var def))
|
||||
_sceneToRegion[room.RoomId] = def;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
_sceneToRegion = null;
|
||||
_regionById = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user