HexCore is a library to perform various operations with a hexagonal grid, such as finding shortest paths from one cell to another, managing terrains and movement types, maintaining the grid state, finding various ranges, neighbors, various coordinate systems and converters between them, and some more stuff you may want to do with a hex grid.
HexCore is designed with performance in mind: it is a zero runtime heap allocation library.
HexCore achieves zero runtime allocations by using an object pool with preallocated lists.
Pass any list returned by the library to the Graph#ReturnListToPool
method after you no longer need it, and it will be recycled without any memory allocation.
- Open the terminal, go to the Assets directory of your Unity project
- Run
git clone https://github.com/antouhou/HexCore.git
(orgit submodule add https://github.com/antouhou/HexCore.git
if you're already using git in your project) - Go to the
HexCore
directory that was created on step 2 and deleteHexCore.Tests
directory (This directory contains unit tests, and will prevent Unity from building the project)
The library can be installed from NuGet. Run from the command line dotnet add package HexCore
in your project or use your IDE of choice.
For the detailed explanations please see the docs.
using System.Collections.Generic;
using HexCore;
namespace HexCoreTests
{
public class QuickStart
{
public static void Demo()
{
var ground = new TerrainType(1, "Ground");
var water = new TerrainType(2, "Water");
var walkingType = new MovementType(1, "Walking");
var swimmingType = new MovementType(2, "Swimming");
var movementTypes = new MovementTypes(
new[] {ground, water},
new Dictionary<MovementType, Dictionary<TerrainType, int>>
{
[walkingType] = new Dictionary<TerrainType, int>
{
[ground] = 1,
[water] = 2
},
[swimmingType] = new Dictionary<TerrainType, int>
{
[ground] = 2,
[water] = 1
}
}
);
var graph = new Graph(new List<CellState>
{
new CellState(false, new Coordinate2D(0, 0, OffsetTypes.OddRowsRight), ground),
new CellState(false, new Coordinate2D(0, 1, OffsetTypes.OddRowsRight), ground),
new CellState(true, new Coordinate2D(1, 0, OffsetTypes.OddRowsRight), water),
new CellState(false, new Coordinate2D(1, 1, OffsetTypes.OddRowsRight), water),
new CellState(false, new Coordinate2D(1, 2, OffsetTypes.OddRowsRight), ground)
}, movementTypes);
var pawnPosition = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight).To3D();
// Mark pawn's position as occupied
graph.BlockCells(pawnPosition);
const int pawnMovementPoints = 3;
var pawnMovementRange = graph.GetMovementRange(
pawnPosition, pawnMovementPoints, walkingType
);
var pawnGoal = new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D();
var theShortestPath = graph.GetShortestPath(
pawnPosition,
pawnGoal,
walkingType
);
// When moving pawn, unblock old position and block the new one.
graph.UnblockCells(pawnPosition);
pawnPosition = pawnGoal;
graph.BlockCells(pawnGoal);
var expectedMovementRange = new List<Coordinate3D>
{
new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D(),
new Coordinate2D(1, 1, OffsetTypes.OddRowsRight).To3D(),
new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D()
};
var expectedPath = new List<Coordinate3D>
{
new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D(),
pawnGoal
};
}
}
}
The resulting graph would look like this:
⬡⬡
⬡⬡⬡
The two cells on top would have terrain type "ground", the two cells in the second row would represent our first lake, and the first water cell would be not passable - we can imagine that there's a sharp rock in the lake at that spot.
For the detailed explanations please see the docs.
Everyone is welcome to contribute in any way of form! For the further details, please read CONTRIBUTING.md
See also the list of contributors who participated in this project.
This project is licensed under the MIT License - see the LICENSE.md file for details