Sure, moving with Physics has all of those problems, and locking axis and joints don’t quite solve them. It takes lots of code-driven babysitting. But I’ve done lots of raycasting and it works just great. Without waiting for a new frame you can change or resize a collider, move around, repeatedly raycast and overlap-check. No whacky surprises beyond all the math (and the rule you can’t hit something you start inside). The OP’s plan to use raycasting should work.
That’s not really an issue. Either way you’re going to want the hexes to have colliders to detect where the player taps. In the old days we’d use pure math, but today making a collider for each square is simpler. With a pure raycasting approach you simply add that single-hex collider to each piece. Do it in code even. Make it a trigger if you still want the pieces to roll around sometimes.
That’s messier – I’d only do it for a game with free-movement – but it’s completely workable.
It does work. Everything since is just discussion of alternatives.
Note: This is just random musings. If your solution works for your game, you don’t need any of this.
To handle hexes you just need a more complicated data structure. However you are going to encapsulate everything inside some sort of HexagonalArray class, so the extra complexity won’t really matter. Hex arrays aren’t bad to work with, because they are actually still regular 2D arrays, its just the adjacency which changes.
A few random tricks I’ve learnt from working with non standard for tiles collections:
- Create a class to represent each position. That way once you have a specific position, you can pass the instance around without caring about the exact way its coordinates are represented in the collection. I normally call this class Cell.
- Add as many utility methods to the Cell as you need. Each cell should know its contents, world position, neighbours and so on.
- Create a method to convert from world and screen positions to a grid position. The math for this can be tricky, so you don’t want to be copy pasting it all over the show. Instead do the math once and bake it into the collection.
- Create an enum for all of the possible directions in your collection. hexMove.left, hexMove.leftUp, … This makes it dramatically easier to move a piece or ask for a Cells neighbours.
I’ve used this approach to create all sorts of wonderfully odd shaped maps that have the same board game like feel.
Also using a grid memory approach can also limit your game, to a fixed size, two dimensions, only grid based movement…
Without that early limitation maybe your game can evolve and grow in ways that a grid based game cannot.
If your starting out with a prototypical game would you not be better off without the grid-memory constraints?
The complaints about physics being used assume you cannot use a kinematic version of a rigidbody. For a hex grid raycasting is easier for beginner programmers. The vector is derived from 60 degree increments. Resizing is easy to handle. Just let the distance between cell centers be the raycast length.
I wasn’t aware the OP was detecting player taps, I missed that.
Hexes are a skewed square grid.

I mean that it will keep working if they add other board-game-like features: different types of pieces, saving, placing a new piece in any square, or pre-placing pieces.
About the word “alternatives”, it seems people are being clear that a 2D grid in memory is the superior solution, even for hexes. If you want to make a game. If you want to use Unity with your kid the best way is to use stuff that makes sense to them.
None of this is true, either. Custom data structures are something programmers are taught pretty early on, and that’s all that’s needed here. All the stuff you mentioned is easily managed there.
So are adjacency rules, which I neglected in my earlier description.
And we’re not talking super advanced stuff. First year programming courses cover this.
Which is exactly why I’m not advocating for it to be implemented in this case.
No. Arrays can be resized by creating a temporary array, transferring the data to it, destroying and recreating the original, and moving the data back. Arrays can have more than just two dimensions. Finally nothing is preventing you from having board locations occupy more than one cell.
A real world example of the first is C++'s vector class. It’s simply an array with advanced logic surrounding it to make it easier to work with. For the third you can look at a game like Diablo with a slot-based inventory system where large items occupy more than one slot.
I pretty much always wrap my arrays. Especially the ones relating world position to simulation position. That way you can change the simulation array however you like.
An odd choice since C# also has that but calls it List.
But I think it’s about the limitations of each a piece being in a certain square. If you want to move off the board, you can’t. You can’t easily be partly in several spaces. You can’t have a piece that takes 22% ,ore space than normal. All true, but they’re true on purpose. If you’re making a game on a grid, you want it on a grid. It’s a very popular genre. Disgaea is on a grid – great game.
Simplest solution is to just not have the player directly tied to the board data. Just because you’re storing an array that represents each board location doesn’t mean the player has to be stored in that manner too.
There are also “sparse grids” which are maps (Dictionary in C#) based on grid coordinates. Those can represent very large grids without allocating memory for every cell.
I don’t understand why any of those things are “limitations”, though. You can do any of that stuff if you want. You’re literally making the rules, you can make them whatever you want.
You need to know how to program it, but that’s true anyway.
And arguably they can be handled better. If you want offsets to be handled differently for pieces at the edge of the board, well, you simply check “if x == 0 || x == gridWidth”. If you want offsets for pieces next to one another, such that they’d be overlapping with one another, you can do another “if Cell ContainsAgent” and treat it differently (for horizontal neighbors, shift the vertical offset for the two pieces, and visa versa).
And since I’m jumping in on this, to address something I saw a couple posts ago: conceptually and literally, I don’t see how a raycast “makes more sense” to a kid than representing a board with a data structure. When you look at a physical board game and decide if a piece can be moved to another location, you’re not putting your finger next to the piece and pointing it towards the target location and seeing if it hits anything (or doing that mentally), that’s just ridiculous. You’re mentally transforming that visual of the board into an abstract-ish thing with distinct spaces, and checking if the target space is filled.
If the raycast version works, it works. But the more I think about it I don’t see how it isn’t worse in literally every single way.
It depends how much practice you have with abstract thinking.
Working with a simulated physical board you can easily ask tangible questions, such as “if I drew a line from here to here, would it hit anything?” and “What is the distance between those places?” The things they can directly see in the Editor are the actual data they’re operating on, so nothing* is abstracted away. In short, most people have a lot more practice thinking like this, and Unity’s Editor lets us apply that pretty directly in many cases.
For the data structure (eg: grid) approach to work, the designer has to be able to hold the idea of the grid in their mind and then think about the possibilities of cells being filled or not and what you should do in each case. In short, it requires thinking about what would happen to an imaginary board. Programmers practice that kind of thinking a lot, so we get really good at it and think it comes naturally, but it doesn’t.
So yes, if you’ve got practice with that kind of thinking the data structure based approach becomes the easier of the two, by far. But if someone hasn’t got that practice yet then they should go ahead and use whatever tools work for them currently. The practice will come, and as long as they’re broadly aware of this stuff they’ll get to it when they’re ready for it. There’s oodles to learn, and no reason they have to learn this particular thing right this instant.
- Well… nothing except the comparatively huge amount of work the computer is doing to make that stuff happen. But in this context that’s not a problem.
I’d argue that your data structure criticism is less about concept and more about implementation.
Again, if you have a board game in front of you and you ask a kid if your red checkers piece can move forward into the space that already holds the black checkers piece, they will look at the board, mentally distinguish each cell as separate, note the existence of the black checkers piece in the target cell, and point that out. You could use a raycast-type explanation but that’s not how they’re evaluating things mentally unless they’re like 3. And when you start getting into jumping over pieces, or say a knight in chess, the raycast process falls apart completely.
…all that said, from a game dev perspective you’re right. The concern is implementation as much or more than anything else.
When we say a technique or approach has limitations we’re saying it’s not especially good at some of the things one might be considering. Not that they’re impossible.
But again, despite the grammar begin fine, the idea that “an in-memory grid has limitations” is the problem. The OP is making a game on a board. That’s a very standard, very common and popular thing. No one is considering non-board stuff like moving off the edge or having off-center pieces affect play. A grid has no limitations fro anything you’d want a game on a grid to do.