3
\$\begingroup\$

I am making a rimworld-like procedurally generated 2D game using Unity's tilemap system.

Just like tiles, I also have to procedurally generate grass and trees. Each grass instance should have logic inside that keeps track of it's growth progress and update the grass size appropriately.

The downside is, I have to have maps as big as 400x400. That could be THOUSANDS of grass instances and each of them having their own GameObject seems ridiculous and like the game would lag.

How can instantiate those grass sprites without creating new gameobjects for each one while still being able to control the growth and similar things?

(Come to think of it, the DOTS / ECS system in Unity would be perfect for this, however it is nowhere near ready and many things I want to do are just not supported.)

\$\endgroup\$
1
3
\$\begingroup\$

Create a TileMap with 400x400 tiles for your grass tiles. Tiles on a TileMap aren't full-fledged gameObjects. They are very lightweight. A 400x400 tilemap is absolutely no problem.

Then create one gameObject. Let's call it GrassManager and put a script with the same name on it. That script internally has a tile[400][400] array and a reference to that TileMap. Those array entries contain structs with all the data related to the grass growth of each tile. Like whether or not it has grass at all, its current growth progress, any tile properties which influence grass growth (moisture? temperature? fertility?) and when it was last updated.

Then Implement its Update method to go through all those tiles and update their growth status. When that Update-function notices that a grass tile has reached its next growth stage, then you update that tile of the tilemap. Note that you likely do not need to process all the grass tiles on every single update. It is likely completely sufficient for your use-case to do staggered updates where you only process a small chunk of all tiles in each Update-call.

\$\endgroup\$
4
  • \$\begingroup\$ This seems like it would work! So because Tilemaps are so lightweight, I'd create a new tilemap for grass, new tilemap for trees, rocks and so on? \$\endgroup\$ – jolefull96 Feb 14 at 7:04
  • \$\begingroup\$ Also, should GrassManager only update grass or should it increment Tree growth as well? \$\endgroup\$ – jolefull96 Feb 14 at 7:05
  • \$\begingroup\$ @jolefull96 That depends. When trees and grass are mechanically identical, then you could use a general PlantGrowthManager. When they have notable mechanical differences, then it might make sense to separate them. How many tilemaps you would use depends on how many objects there can be on a tile. Can there be grass AND a tree on the same tile? Then you need two separate tilemaps for grass and trees. Can there be only a tree OR a rock on a tile? Then those can be on one "objects" tilemap. Are trees/rocks interactable objects with behavior? Then they might have to be full-fledged game objects. \$\endgroup\$ – Philipp Feb 14 at 10:49
  • \$\begingroup\$ I'm not sure what would be considered an "interactable object". For example, grass can be cut down, so that makes it interactable, but I don't think it should be a full-fledged gameobject. All I have to do is remove it from the grass[400][400] array and update that tile. Other than that, I think I understand everything you said and this will be a great solution. \$\endgroup\$ – jolefull96 Feb 14 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.