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

如何定位Hexgrid中心并将六边形网格移至地图原点?

六边形网格居中对齐原点解决方案

要让Godot中生成的六边形网格中心对齐(0,0,0),直接用gridSize.X/2或gridSize.Y/2做偏移是无效的——因为六边形网格的奇偶行/列存在偏移,导致整体边界并非对称的矩形。正确做法是先计算网格的实际坐标边界,再以边界中心为基准偏移所有tile。


方法一:预遍历计算边界(通用直观)

先遍历所有网格坐标,获取X、Z轴的最小/最大值,以此计算网格中心,再将每个tile的坐标减去中心值实现居中。

修改后的GenerateGrid代码:

public void GenerateGrid()
{
    // 先遍历所有坐标,获取网格的实际边界范围
    float minX = float.MaxValue;
    float maxX = float.MinValue;
    float minZ = float.MaxValue;
    float maxZ = float.MinValue;

    for (int y = 0; y < gridSize.Y; y++)
    {
        for (int x = 0; x < gridSize.X; x++)
        {
            Vector3 pos = GetPositionFromCurrentHex(new Vector2(x, y));
            minX = Mathf.Min(minX, pos.X);
            maxX = Mathf.Max(maxX, pos.X);
            minZ = Mathf.Min(minZ, pos.Z);
            maxZ = Mathf.Max(maxZ, pos.Z);
        }
    }

    // 计算网格的中心坐标
    float centerX = (minX + maxX) / 2f;
    float centerZ = (minZ + maxZ) / 2f;

    // 生成tile并偏移到中心对齐原点
    for (int y = 0; y < gridSize.Y; y++)
    {
        for (int x = 0; x < gridSize.X; x++)
        {
            Vector3 newPos = GetPositionFromCurrentHex(new Vector2(x, y));
            Node3D generator_scene = (Node3D)ResourceLoader.Load<PackedScene>(tilePath).Instantiate();
            // 用原始坐标减去中心坐标,实现居中
            generator_scene.Position = new Vector3(newPos.X - centerX, newPos.Y, newPos.Z - centerZ);
            
            if (isFlatTopped)
            {
                generator_scene.RotateY(Mathf.DegToRad(90));
            }
            AddChild(generator_scene);
        }
    }
}

方法二:直接推导边界(性能优化)

如果网格尺寸较大,不想预遍历所有坐标,可以根据六边形类型(点向上/扁向上)直接推导边界范围,再计算中心:

public void GenerateGrid()
{
    float centerX = 0f;
    float centerZ = 0f;
    float size = outerSize;

    // 根据六边形类型直接计算中心
    if (!isFlatTopped)
    {
        float width = Mathf.Sqrt(3) * size;
        float verticalDistance = 2f * size * 3f/4f;
        // 点向上网格的X最大边界:列数间距 + 奇数行的额外偏移
        float maxX = (gridSize.X - 1) * width + (gridSize.Y % 2 == 1 ? width/2 : 0);
        float maxZ = (gridSize.Y - 1) * verticalDistance;
        centerX = maxX / 2f;
        centerZ = maxZ / 2f;
    }
    else
    {
        float height = Mathf.Sqrt(3f) * size;
        float horizontalDistance = 2f * size * 3f/4f;
        float maxX = (gridSize.X - 1) * horizontalDistance;
        // 扁向上网格的Z最小边界:奇数列的额外偏移
        float minZ = -(gridSize.X % 2 == 1 ? height/2 : 0);
        float maxZ = (gridSize.Y - 1) * height;
        centerX = maxX / 2f;
        centerZ = (minZ + maxZ) / 2f;
    }

    // 生成tile并偏移
    for (int y = 0; y < gridSize.Y; y++)
    {
        for (int x = 0; x < gridSize.X; x++)
        {
            Vector3 newPos = GetPositionFromCurrentHex(new Vector2(x, y));
            Node3D generator_scene = (Node3D)ResourceLoader.Load<PackedScene>(tilePath).Instantiate();
            generator_scene.Position = new Vector3(newPos.X - centerX, newPos.Y, newPos.Z - centerZ);
            
            if (isFlatTopped)
            {
                generator_scene.RotateY(Mathf.DegToRad(90));
            }
            AddChild(generator_scene);
        }
    }
}

为什么原方法无效?

六边形网格的坐标计算中,奇偶行(点向上)或奇数列(扁向上)会产生半个tile宽度/高度的偏移,导致整个网格的X/Z范围并非严格的网格尺寸 × 间距。比如点向上的奇数行tile会向右偏移半个宽度,这使得网格实际中心无法用gridSize.X/2简单计算,必须以真实边界的中间值为基准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:00:59