Unity中如何将世界坐标转为自定义尺寸点顶六边形网格坐标?
点顶1x1六边形网格:世界坐标转立方体坐标方案
核心逻辑
你遇到的问题本质是常规算法基于标准六边形比例(宽√3、高2),而你的自定义1x1比例需要重新推导换算系数。下面是适配你需求的完整实现:
步骤拆解与代码实现
- 坐标预处理
先把世界坐标转换成相对网格原点的局部坐标(忽略Z轴,因为是2D六边形网格):
Vector2 localPos = new Vector2(worldPos.x - origin.x, worldPos.y - origin.y);
origin是你网格原点对应的世界坐标(比如TileMap的左下角位置)。
- 计算浮点立方体坐标
针对点顶布局,用调整后的系数计算三个分量:
float q = (Mathf.Sqrt(3)/3 * localPos.x) - (1f/3 * localPos.y); float r = (2f/3 * localPos.y); float s = -q - r;
这里的系数完全适配1x1单元格尺寸,替代了常规算法中的半径相关参数。
- 取整并修正
立方体坐标要求q + r + s = 0,取整后可能出现误差,需要修正:
int qInt = Mathf.RoundToInt(q); int rInt = Mathf.RoundToInt(r); int sInt = Mathf.RoundToInt(s); float qDiff = Mathf.Abs(q - qInt); float rDiff = Mathf.Abs(r - rInt); float sDiff = Mathf.Abs(s - sInt); if (qDiff > rDiff && qDiff > sDiff) qInt = -rInt - sInt; else if (rDiff > sDiff) rInt = -qInt - sInt; else sInt = -qInt - rInt;
完整Unity C#方法
public static Vector3Int WorldToCubePointyTop(Vector3 worldPos, Vector3 origin) { // 转局部坐标 Vector2 localPos = new Vector2(worldPos.x - origin.x, worldPos.y - origin.y); // 计算浮点立方体坐标 float q = (Mathf.Sqrt(3)/3 * localPos.x) - (1f/3 * localPos.y); float r = (2f/3 * localPos.y); float s = -q - r; // 取整 int qInt = Mathf.RoundToInt(q); int rInt = Mathf.RoundToInt(r); int sInt = Mathf.RoundToInt(s); // 修正总和为0 float qDiff = Mathf.Abs(q - qInt); float rDiff = Mathf.Abs(r - rInt); float sDiff = Mathf.Abs(s - sInt); if (qDiff > rDiff && qDiff > sDiff) qInt = -rInt - sInt; else if (rDiff > sDiff) rInt = -qInt - sInt; else sInt = -qInt - rInt; return new Vector3Int(qInt, rInt, sInt); }
测试建议
- 找几个已知位置的六边形单元格,比如原点对应的立方体坐标(0,0,0),右上角相邻单元格对应的世界坐标,代入方法验证结果是否正确
- 如果你的TileMap有锚点偏移,只需要调整
origin参数即可
内容的提问来源于stack exchange,提问作者LT.DAN
相关产品推荐
相关产品推荐

