I did the conversion from square to hex grid before watching this bonus section, to challenge my understanding. This led me to a different CalculateDistance instead of the heuristic version in the course.
It’s based on the triangle/cone where a change in X doesn’t add to the distance, which widens for larger absolute values of Z. Integer division rounding down handles whether the destination GridPosition is on an odd or even row. I thought it was a fairly neat solution, so I thought I’d share it:
// in Pathfinding class
public int CalculateDistance(GridPosition gridPositionA, GridPosition gridPositionB)
{
int zDistance = Mathf.Abs(gridPositionB.z - gridPositionA.z);
int xDifference = gridPositionB.x - gridPositionA.x;
int xDistance;
// Starting row (z) is even
if (gridPositionA.z % 2 == 0)
{
if (xDifference < 0)
{
xDistance = Mathf.Max(-xDifference - (zDistance + 1) / 2, 0);
}
else
{
xDistance = Mathf.Max(xDifference - zDistance / 2, 0);
}
}
else // Starting row (z) is odd
{
if (xDifference < 0)
{
xDistance = Mathf.Max(-xDifference - zDistance / 2, 0);
}
else
{
xDistance = Mathf.Max(xDifference - (zDistance + 1) / 2, 0);
}
}
return (zDistance + xDistance) * MOVE_COST;
}
I used similar code in the GridPosition class to get GridPositions in a range (including neighbors, range=1). It doesn’t check for validity, I handle that afterwards.
// in GridPosition class
public static List<GridPosition> GetGridPositionsInRange(GridPosition gridPosition, int range, bool includeSelf=true)
{
List<GridPosition> gridPositionsInRange = new List<GridPosition>();
bool startingRowOdd = gridPosition.z % 2 == 1;
for (int z = 0; z <= range; z++)
{
int xMin = -(range - (z + (startingRowOdd ? 1 : 0)) / 2);
int xMax = range - (z + (startingRowOdd ? 0 : 1)) / 2;
for (int x = xMin; x <= xMax; x++)
{
if (!includeSelf && z == 0 && x == 0)
continue;
gridPositionsInRange.Add(new GridPosition(gridPosition.x + x, gridPosition.z + z));
if (z == 0)
continue;
gridPositionsInRange.Add(new GridPosition(gridPosition.x + x, gridPosition.z - z));
}
}
return gridPositionsInRange;
}