You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#全屏网格Chunk拖拽系统世界坐标异常问题求助

全屏Chunk网格拖拽系统异常修复方案

问题背景

基于C#实现全屏16x16尺寸的Chunk网格系统,支持鼠标拖拽平移:当拖拽偏移超过16单位时重置偏移,并将超出屏幕的Chunk重定位到对侧。目前在var worldPosition = new long2(nx + totalOffset.x, ny + totalOffset.y);行存在两处异常:

  • 同Y轴的Chunk世界坐标Y值混乱(如从-32变为-48再到-64)
  • 拖拽到左上区域正常,但右下区域无反应

异常1:同Y轴Chunk世界坐标Y值错乱

根源分析

  1. ToInt方法负数计算逻辑错误:处理负数偏移时,Mathf.CeilToInt(f.y / r) * (int)r的计算逻辑会导致偏移量计算偏差。例如f.y=-17、r=16时,计算结果为-16,但实际应该是-32(偏移超过16单位,需向下取整到下一个Chunk边界)。
  2. 世界坐标计算未绑定Chunk网格位置:当前用屏幕重定位后的nx/ny加totalOffset计算世界坐标,未结合Chunk在原始网格中的行列位置,导致同Y轴Chunk因屏幕位置不同,世界坐标出现差异。

修复代码

  • 修正ToInt方法,统一用FloorToInt保证正负偏移计算一致:
public static Vector2Int ToInt(this Vector2 f, float r)
{
    var x = Mathf.FloorToInt(f.x / r) * (int)r;
    var y = Mathf.FloorToInt(f.y / r) * (int)r;
    return new Vector2Int(x, y);
}
  • 基于Chunk原始网格行列计算世界坐标,替代原屏幕位置的计算方式:
// 替换原worldPosition计算行
var worldX = (x * ChunkSize) + totalOffset.x;
var worldY = (y * ChunkSize) + totalOffset.y;
var worldPosition = new long2(worldX, worldY);

异常2:拖拽右下区域无反应

根源分析

  1. 偏移重置触发条件过严:Mathf.Abs(co.x) > ChunkSize的判断,当偏移刚好等于16时不会触发重置,导致右下方向拖拽时无法触发Chunk重定位。
  2. 取模运算负数处理错误:@new.x % screenWidth在@new.x为负数时结果为负,导致nx超出屏幕范围,uiRect.Contains判断错误,Chunk无法正确重定位到右下区域。
  3. 拖拽偏移更新逻辑冗余:HandleDragEvent中CurrentOffset += position - lastPosition的冗余计算可能引入精度问题,且未做边界约束。

修复代码

  • 调整偏移重置触发条件为大于等于ChunkSize:
var bx = Mathf.Abs(co.x) >= ChunkSize;
var by = Mathf.Abs(co.y) >= ChunkSize;
  • 修正取模运算,确保结果为正:
// 替换原nx、ny计算行
var nx = (@new.x % screenWidth + screenWidth) % screenWidth;
var ny = (@new.y % screenHeight + screenHeight) % screenHeight;
  • 简化拖拽偏移更新逻辑,避免冗余计算:
private bool HandleDragEvent(bool changed)
{
    if (Event.current.type == EventType.MouseDrag &&
        (Event.current.button == 0 && Event.current.modifiers == EventModifiers.Alt ||
         Event.current.button == 2))
    {
        var delta = Event.current.delta;
        CurrentOffset -= delta * dragForce;
        _zoomCoordsOrigin = CurrentOffset;
        changed = delta != Vector2.zero;
        Event.current.Use();
    }
    return changed;
}

额外优化

  • 确保totalOffset累计正确:在偏移重置时,将计算出的offset累加到totalOffset中,保证世界坐标的全局偏移累计准确:
if (resetDelta)
{
    var x = co.x;
    var y = co.y;

    if (bx)
        x = 0;

    if (by)
        y = 0;

    ui.CurrentOffset = new Vector2(x, y);
    totalOffset += offset; // 新增:累计全局偏移
}

内容的提问来源于stack exchange,提问作者z3nth10n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:11:03