fix(csharp): SpatialGridCs 网格常量/坐标偏移对齐 GDScript 外壳(激活陷阱)
休眠的 C# 内核 SpatialGridCs 与权威外壳 spatial_grid.gd 三处不一致, 一旦按 ADR-L1 激活即塌: - 网格尺寸 64×64 → 128×128(覆盖 4096²→8192²,与 GDScript 一致) - 补 GridOffset=4096:Insert / QueryCircle 的格映射改为 (coord±radius+4096)/64, 修复负坐标实体全塌到 0 格、覆盖范围减半的问题。 两骨架 BulletManagerCs/EnemyManagerCs 仅读 _active_count 打计时,无 SoA 常量对齐问题。 dotnet build 通过(0 警告 0 错误)。保持休眠(_cs_node 仍恒 null,GDScript fallback 运行)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,9 +9,12 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
public partial class SpatialGridCs : Node
|
public partial class SpatialGridCs : Node
|
||||||
{
|
{
|
||||||
|
// ⚠️ 必须与 GDScript 外壳 spatial_grid.gd 的 CELL_SIZE / GRID_COLS / GRID_ROWS / GRID_OFFSET
|
||||||
|
// 逐一对齐;否则激活 C# 内核后两条路径格子映射不一致(负坐标塌陷 + 覆盖范围减半)。
|
||||||
private const int CellSize = 64;
|
private const int CellSize = 64;
|
||||||
private const int GridWidth = 64; // 64 格×64 格 = 4096×4096 像素覆盖范围
|
private const int GridWidth = 128; // 128×128 格 × 64px = 8192×8192 覆盖范围
|
||||||
private const int GridHeight = 64;
|
private const int GridHeight = 128;
|
||||||
|
private const int GridOffset = 4096; // 世界中心映射到网格中心(支持负坐标)
|
||||||
private const int GridTotal = GridWidth * GridHeight;
|
private const int GridTotal = GridWidth * GridHeight;
|
||||||
|
|
||||||
// 网格主体:一维数组模拟二维,直接索引 grid[x + y * GridWidth]
|
// 网格主体:一维数组模拟二维,直接索引 grid[x + y * GridWidth]
|
||||||
@@ -39,8 +42,8 @@ public partial class SpatialGridCs : Node
|
|||||||
// 插入或更新实体位置(由 EnemyManager 每帧调用)
|
// 插入或更新实体位置(由 EnemyManager 每帧调用)
|
||||||
public void Insert(int entityId, Vector2 pos)
|
public void Insert(int entityId, Vector2 pos)
|
||||||
{
|
{
|
||||||
int cx = Mathf.Clamp((int)(pos.X / CellSize), 0, GridWidth - 1);
|
int cx = Mathf.Clamp((int)((pos.X + GridOffset) / CellSize), 0, GridWidth - 1);
|
||||||
int cy = Mathf.Clamp((int)(pos.Y / CellSize), 0, GridHeight - 1);
|
int cy = Mathf.Clamp((int)((pos.Y + GridOffset) / CellSize), 0, GridHeight - 1);
|
||||||
int cellIdx = cx + cy * GridWidth;
|
int cellIdx = cx + cy * GridWidth;
|
||||||
|
|
||||||
if (_entityCell.TryGetValue(entityId, out int oldCell))
|
if (_entityCell.TryGetValue(entityId, out int oldCell))
|
||||||
@@ -61,10 +64,10 @@ public partial class SpatialGridCs : Node
|
|||||||
// ADR-L1 规厙1:内层 foreach 内禁止 Call()
|
// ADR-L1 规厙1:内层 foreach 内禁止 Call()
|
||||||
public int[] QueryCircle(Vector2 center, float radius)
|
public int[] QueryCircle(Vector2 center, float radius)
|
||||||
{
|
{
|
||||||
int minCx = Mathf.Clamp((int)((center.X - radius) / CellSize), 0, GridWidth - 1);
|
int minCx = Mathf.Clamp((int)((center.X - radius + GridOffset) / CellSize), 0, GridWidth - 1);
|
||||||
int maxCx = Mathf.Clamp((int)((center.X + radius) / CellSize), 0, GridWidth - 1);
|
int maxCx = Mathf.Clamp((int)((center.X + radius + GridOffset) / CellSize), 0, GridWidth - 1);
|
||||||
int minCy = Mathf.Clamp((int)((center.Y - radius) / CellSize), 0, GridHeight - 1);
|
int minCy = Mathf.Clamp((int)((center.Y - radius + GridOffset) / CellSize), 0, GridHeight - 1);
|
||||||
int maxCy = Mathf.Clamp((int)((center.Y + radius) / CellSize), 0, GridHeight - 1);
|
int maxCy = Mathf.Clamp((int)((center.Y + radius + GridOffset) / CellSize), 0, GridHeight - 1);
|
||||||
|
|
||||||
var result = new List<int>(32);
|
var result = new List<int>(32);
|
||||||
float radSq = radius * radius;
|
float radSq = radius * radius;
|
||||||
|
|||||||
Reference in New Issue
Block a user