public static Vector2 IndexToWorldPosition(int mapX, int mapY, float tileWidth, float tileHeight)
{
float x = (mapX - mapY) * tileWidth / 2f;
float y = (mapX + mapY) * tileHeight / 2f;
return new Vector2(x, y);
}
瓷砖宽度和高度分别为1和0.5世界单位。布局按预期工作,给我典型的钻石形状。现在我想反转函数并从世界位置获取正确的地图索引(例如,鼠标转换为世界空间)。
public static IntVector2 WorldPositionToIndex(Vector2 mouseWorld, float tileWidth, float tileHeight)
{
float x = mouseWorld.x / tileWidth + mouseWorld.y / tileHeight;
float y = mouseWorld.y / tileHeight - mouseWorld.x / tileWidth;
return new IntVector2(Mathf.FloorToInt(x), Mathf.FloorToInt(y));
}
第二个功能似乎是错误的。在测试时,只有靠近网格原点的世界位置报告正确的索引,更远的地方变得越来越不准确,但我似乎无法找出问题所在。我还尝试用 Ceil 和 Round 替换 FloorToInt ,但它只增加或减少了已经不正确的偏移量。此外,我已确保报告的世界鼠标位置正确。我还编写了一个具有固定输入和预期输出值的单元测试,并且它报告说,第二个函数确实没有正确地反转第一个函数。
任何人都可以发现错误或指出我正确的方向如何正确反转第一个功能?
补充:以下是我对这两个功能的单元测试:
[TestCase(0, 0, 0, 0)]
[TestCase(0, 1, -0.5f, -0.25f)]
[TestCase(0, 2, -1f, -0.5f)]
[TestCase(1, 0, 0.5f, -0.25f)]
[TestCase(1, 1, 0f, -0.5f)]
[TestCase(1, 2, -0.5f, -0.75f)]
[TestCase(2, 0, 1f, -0.5f)]
[TestCase(2, 1, 0.5f, -0.75f)]
[TestCase(2, 2, 0f, -1f)]
public void Conversion_Works(int mapX, int mapY, float expectedX, float expectedY)
{
UnityEngine.Vector2 result = DimetricLayout.CoordinateToWorldPosition(mapX, mapY, 1f, 0.5f);
Assert.AreEqual(expectedX, result.x);
Assert.AreEqual(expectedY, result.y);
}
[TestCase(0, 0, 0, 0)]
[TestCase(0, 1, -0.5f, -0.25f)]
[TestCase(0, 2, -1f, -0.5f)]
[TestCase(1, 0, 0.5f, -0.25f)]
[TestCase(1, 1, 0f, -0.5f)]
[TestCase(1, 2, -0.5f, -0.75f)]
[TestCase(2, 0, 1f, -0.5f)]
[TestCase(2, 1, 0.5f, -0.75f)]
[TestCase(2, 2, 0f, -1f)]
public void Conversion_Mouse(int expectedX, int expectedY, float mouseX, float mouseY)
{
IntVector2 result = DimetricLayout.WorldPositionToCoordinate(new UnityEngine.Vector2(mouseX, mouseY), 1f, 0.5f);
Assert.AreEqual(expectedX, result.x);
Assert.AreEqual(expectedY, result.y);
}