Search code examples
c#unity-game-enginegridtileisometric

Best way to implement a 2D hex-based/isometric grid system in Unity (for complex tiles)?


I'm trying to create a grid system for a 2D game. Not completely sure if I'll go with a hexagon-grid or isometric, but which shouldn't matter too much here. Basically, I'm trying to create a tower defense game where you deploy units instead of towers, and can move those as if you were playing a tactical game. The problem is that the tiles themselves are gonna be complex - there will be different types of terrain. Some units can only be deployed in X, and can't go through Y, that kind of thing. I also need the ability to add some logic to these tiles at will - who knows, maybe I want a special tile to give extra attack range to units above it, that kind of thing. The game must also "feel" like a grid - making things snap to the center of the tiles, as well as highlighting the tiles on hover and when moving/attacking.

Isometric example Hex-grid example

Okay, this leads me to a pretty obvious route: I can create prefabs for the different types of tiles I need, add all the proprieties and logic as script components and create a grid class that instantiates each tile in the world. This works great, cause this way I have full control over everything - I can do whatever I want with the tiles, and I can also create a 2d matrix for their positions as I instantiate them. This way I can call tile[3, 6] for example, which sounds like a huge deal for pathing, highlighting and such. I can also link whatever gameobject is on top of it to the tile itself, so I could call something like tile[6, 2].ObjectOnTop.~WhateverInfoINeedFromIt, which also sounds super handy for overall logic.

But the shortcomings are also terrible - how do I even design and deploy different levels designs? The only way I can think of it is to figure out a way to do it all by hand, export that info somehow to a json file, and have the grid class that instantiates everything select which tile will be instantiated where based on the json info. I not only have no idea how to actually implement that, but I also think it would be an absurd amount of work for something that is supposed to be natural. I'm also not sure if a gameobject for each tile is a good idea in terms of performance. The biggest problem? It's easy to create such a grid if it's a simple squared tiles grid - but when we start talking about hexagons and isometric grids... it's not nearly as easy, honestly. The complex shapes make it so difficult to work with this kind of thing. For example, how do I even convert the mouse position into the equivalent tile? It's super easy for squares... not so much for the rest. It also kind of sucks that the grid is only really deployed when the game runs (is this generally considered a bad thing that I should avoid, btw?).

But don't worry, cause I've found the solution: tilemaps! Of course! It fixes all the problems I have, right? Supposedly yes, but it also removes all the power I had from having prefabs. Now I can't have any logic with tiles... They can't store any properties... so I'm doomed, I guess. I've read a bit on ways to overcome this (prefab brushes, custom classes inherenting from Tile, making a tilemap for each tile type), but they are honestly extremely niche and just don't feel right.

It's so weird, a generic grid system like this was supposed to be so simple and common. But I can barely find any information at all. It's like I'm missing this pretty obvious tool that no one seems to mention cause it's that obvious. So here I am, struggling to start a project cause I can't even figure out how to implement the basic structure of the game. Everything I see online leads me to tilemaps - but they only work for very basic stuff, from what I understood. I won't work for this kind of game, I think. I have no idea what to do at this point - there must be an optimal way to solve everything, the one that is likely used for all the devs that work on this kind of game. And honestly, there are a ton of them.

So, please, shed me some light. And thanks a lot in advance!

(Here's someone that posted an extremely similar question: Per Tilemap Tile Data Storage & Retrieval)


Solution

  • convert mouse position to tile position can be done different ways, simplest would be to raycast the mouse and see if it hits a tile

    probably easiest to make a 2dimensional array of tiles of class 'Tile', even if its hex break it down into a 2d array and offset , setup the tiles dynamically in code

    for pathing and such djikstra algorithm is pretty useful

    https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm