Building Placement for a city-builder

I’m working on my first city-builder in unity, and I’m wondering if I can use my ground instead of a grid that the buildings snap to. Each ground block in my game is a seperate gameobject. Would this also be possible with buildings that take up more than one unit (ground block)? Sorry if this question is badly worded or insufficiently described. Ask me to add on, and I’d be glad to.

Try to think of the visual representation of a game, and the logic of a game, as two completely different elements. The visual representation (the avatars on the screen, the ground, the buildings, etc) should be knowledgable about the data they represent, but the core game logic should NOT be knowledgable about the visual representation. The same way a UI button on the screen needs to know what function it’s firing, and where, but nothing in the game needs direct knowledge of the UI- the UI should be entirely discardable, swappable, and the core game systems should keep working just fine as long as it’s getting the right commands.

Once you come to terms with that distinction, it becomes much much easier to design complex systems. In this case, unless you specifically want to support multi-tiered landscapes, I would still store things internally as a simple 2D array (a flat grid). Each time you hover over something, or click somewhere, it should raycast and retrieve the ID for the block, which it should use to get data about that element of the grid, as its been stored internally in your game. Is this an empty piece of land? Is there a building on it? Which building? What’s the height of the block and what are the possible interactions with neighboring blocks?

To answer your specific question though, I would raycast to get the block in question, but also determine from the hit point on that object whether the cursor is more toward the center of the surface, or toward one of the corners. In the case of it being toward one of the corners, this can tell the game logic “consider the center point to be the intersection between these 4 blocks, instead of the center of the block it’s actually on, if the next operation supports that”. This is how games like Sims manage to make clean placements of large objects with even-tile widths/lengths. The system should be able to tell, based on the relative heights and angles of the blocks in question, whether placing the object there is mathematically possible, and react accordingly. I would probably do this by grouping together those blocks (plus an extra perimeter of blocks around them) and making a new temp object that treats those blocks collectively as one unit, to make the process a bit easier.

Using the ground like it’s directly a part of the game data, instead of just representative of that game data, leads to all sorts of difficulties later on. For instance, if you’re not using a logical grid to store object placements internally, then how would you find “neighbors” reliably? Every object would need to store a ton of data about how it relates to nearby objects, and the world as a whole, and each operation could potentially require dozens of independent nearby objects to all have to run new calculations simultaneously.

Hope that makes some kind of sense and is helpful in visualizing your issues. Everyone does things differently, so I won’t pretend like this is the absolute best approach (depends on your design requirements), but too often people fall into a hole of making things much more complicated than they need to be by over-using GameObjects and MonoBehaviours when they should really just be doing most of it in static managers and engine-agnostic systems. In my honest opinion, the core build system for something like this should work identically in a 2D sprite-based city builder and in a 3D one- if it can’t do that, then I personally see the responsibilities as being handled in the wrong places.

Good luck!

It should definitely be possible.

In you drop code, where you are dropping the building onto the grid, determine the block you are dropping it on, and set the transform position to that blocks position.

In the case of a building that takes up more than one block, just find the block that will be the corner position, and set the building transform to that position.

Hope this at least points you in the right direction.
-Larry