Add independent review report for Minimap system Round 7
- Validate fixes from Round 6 and identify new issues - Document findings including UX defects, editor integration flaws, and code quality concerns - Propose solutions and prioritize issues based on severity - Evaluate against standards of mature 2D Metroidvania games
This commit is contained in:
11
Assets/_Game/Scripts/World/Map/IPinService.cs.meta
Normal file
11
Assets/_Game/Scripts/World/Map/IPinService.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96f79378a72e0884eb67abdec7cedd2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f10ab54d55ebf14a8c93cca7164230c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
Assets/_Game/Scripts/World/Map/MapGridConstants.cs.meta
Normal file
11
Assets/_Game/Scripts/World/Map/MapGridConstants.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8bb8a918cea77d4097634a071a13b4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
Assets/_Game/Scripts/World/Map/MapInputHandler.cs.meta
Normal file
11
Assets/_Game/Scripts/World/Map/MapInputHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4868a5b10a549ea43826ff162ecc6b5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
Assets/_Game/Scripts/World/Map/MapRoomCellUI.cs.meta
Normal file
11
Assets/_Game/Scripts/World/Map/MapRoomCellUI.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0c5d13ad97e89a4b8f49b35620789c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -94,7 +94,7 @@ namespace BaseGames.World.Map
|
||||
private void OnValidate() => _index = null; // 编辑器中修改 AllRooms 后强制重建索引
|
||||
|
||||
// ── 配置验证 ──────────────────────────────────────────────────────────
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// 检查数据库中的常见配置错误(RoomId 重复、格子重叠、出口悬空)。
|
||||
/// 编辑器侧调用;运行时不应调用(有 O(N²) 开销)。
|
||||
@@ -152,5 +152,6 @@ namespace BaseGames.World.Map
|
||||
|
||||
return errors;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/_Game/Scripts/World/Map/MapServiceExtensions.cs.meta
Normal file
11
Assets/_Game/Scripts/World/Map/MapServiceExtensions.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a93d2e2dddd51740807bd2ceebb68c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -42,6 +42,11 @@ namespace BaseGames.World.Map
|
||||
// 复用 List 避免 RefreshView 每次分配临时 List(GC 友好)
|
||||
private readonly List<string> _toRemove = new List<string>(8);
|
||||
|
||||
// 空间索引:格子坐标 → 房间 ID,将 RefreshView step② 的 O(N) 遍历降至 O(viewRadius²)
|
||||
private Dictionary<Vector2Int, string> _spatialIndex;
|
||||
// 复用 HashSet 避免 RefreshView 每次分配(GC 友好)
|
||||
private readonly HashSet<string> _roomsInViewBuffer = new HashSet<string>(32);
|
||||
|
||||
private Vector2Int _currentCenter;
|
||||
private string _lastDotRoomId;
|
||||
private Vector2 _lastDotNormPos;
|
||||
@@ -53,6 +58,8 @@ namespace BaseGames.World.Map
|
||||
_mapSvc = ServiceLocator.GetOrDefault<IMapService>();
|
||||
_playerProvider = ServiceLocator.GetOrDefault<IPlayerPositionProvider>();
|
||||
|
||||
BuildSpatialIndex(_mapSvc?.Database);
|
||||
|
||||
if (_playerProvider != null)
|
||||
_playerProvider.OnRoomChanged += OnRoomChanged;
|
||||
|
||||
@@ -72,6 +79,7 @@ namespace BaseGames.World.Map
|
||||
_lastDotRoomId = null;
|
||||
_mapSvc = null;
|
||||
_playerProvider = null;
|
||||
_spatialIndex = null;
|
||||
}
|
||||
|
||||
private void ClearAllCells()
|
||||
@@ -81,6 +89,24 @@ namespace BaseGames.World.Map
|
||||
_cells.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建格子坐标 → 房间 ID 的哈希映射。
|
||||
/// 将 RefreshView step② 从 O(allRooms) 全量遍历降至 O(viewRadius²) 范围格点查询。
|
||||
/// 数据库变更时(如热更)应再次调用。
|
||||
/// </summary>
|
||||
private void BuildSpatialIndex(MapDatabaseSO db)
|
||||
{
|
||||
_spatialIndex = new Dictionary<Vector2Int, string>();
|
||||
if (db?.AllRooms == null) return;
|
||||
foreach (var room in db.AllRooms)
|
||||
{
|
||||
if (room == null) continue;
|
||||
for (int x = 0; x < room.GridSize.x; x++)
|
||||
for (int y = 0; y < room.GridSize.y; y++)
|
||||
_spatialIndex[new Vector2Int(room.GridPosition.x + x, room.GridPosition.y + y)] = room.RoomId;
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
UpdatePlayerDot();
|
||||
@@ -133,16 +159,30 @@ namespace BaseGames.World.Map
|
||||
}
|
||||
foreach (var id in _toRemove) _cells.Remove(id);
|
||||
|
||||
// ② 实例化新进入范围的格子
|
||||
foreach (var room in db.AllRooms)
|
||||
// ② 用空间索引替代 O(N) 全量遍历,在可视范围格点上查询所属房间
|
||||
// 复杂度:O(viewRadius²) 替代 O(allRooms),大地图下效果显著
|
||||
_roomsInViewBuffer.Clear();
|
||||
if (_spatialIndex != null)
|
||||
{
|
||||
if (room == null || _cells.ContainsKey(room.RoomId)) continue;
|
||||
if (!RoomInView(room, minX, maxX, minY, maxY)) continue;
|
||||
for (int x = minX; x <= maxX; x++)
|
||||
for (int y = minY; y <= maxY; y++)
|
||||
{
|
||||
if (_spatialIndex.TryGetValue(new Vector2Int(x, y), out var rId))
|
||||
_roomsInViewBuffer.Add(rId);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var roomId in _roomsInViewBuffer)
|
||||
{
|
||||
if (_cells.ContainsKey(roomId)) continue;
|
||||
var room = db.GetRoom(roomId);
|
||||
if (room == null) continue;
|
||||
|
||||
var cell = Instantiate(_cellPrefab, _cellContainer);
|
||||
cell.Setup(room, _mapSvc.GetVisibility(room.RoomId), null);
|
||||
cell.SetColors(_colorExplored, _colorMapped, _colorUnknown);
|
||||
_cells[room.RoomId] = cell;
|
||||
PlaceCell(cell, room); // 立即设置正确的中心相对坐标,避免 Setup 默认偏移被 step③ 覆盖
|
||||
_cells[roomId] = cell;
|
||||
}
|
||||
|
||||
// ③ 重定位所有格子(中心发生变化时)
|
||||
|
||||
11
Assets/_Game/Scripts/World/Map/MinimapHUD.cs.meta
Normal file
11
Assets/_Game/Scripts/World/Map/MinimapHUD.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02879db752b9f0b4bb1b0c9834ad4d84
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user