Search Unity

2D world & physics - 3D assets (and tiles)

Discussion in 'General Discussion' started by Deornoth, Mar 27, 2023.

  1. Deornoth

    Deornoth

    Joined:
    Oct 8, 2021
    Posts:
    10
    Hello,

    I'm making a 2D platform game, with destructible ground (perhaps closest to Terraria); however, I would like to use 3D assets for characters, and for tiles.
    • It'll be using hex tiles.
    • I'd like to leverage unity's great editor support for things like tile palettes, rule tiles, tile painting etc
    • I'd like to have 3D assets (rendered in 3D, not just pre-rendered) for tiles
    • I'd like to use 2D physics
    • The world will be very large (several million tiles)
    • It will be "side-on" - like Terraria, or Starbound
    How would you recommend I do this?

    My thoughts so far: do everything in 2D, including making "placeholder" 2D tiles, so that I can use all of the existing tilemap features in the Unity editor. Then, write some code which places the correctly corresponding 3D tiles on top of the 2D tiles, and hide the 2D tiles. This could potentially be done per frame (depending on what is performant), and only for the tiles visible on the screen.

    Any other suggestions?

    If my approach is the best approach (or at least, a reasonable one), then perhaps you could share some tips/details on how to do it with good performance? E.g. it would be nice if it was possible to do it without having to create an object for every tile (which will be expensive and probably slow) but rather, effectively re-render each tile of the same type.
     
    Last edited: Mar 27, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,981
    You should look into what I'm doing. Link is in my signature. ;)

    It is currently too early to recommend for production use, and won't support hex tiles for a while. But the way you plan to create tile worlds is exactly why I'm creating ProTiler: to allow for large, streaming 3D tile worlds without having tens of thousands of game objects in the scene AND supporting millions of tiles in the world.

    Because several 10 thousand game objects in a scene will already cause severe slowdowns in the editor and runtime performance. So you will be looking at streaming game objects within the visible range. It should be sufficient to have a single pool with enough game objects as there are visible tiles, even if that means calling dozens to hundreds of Instantiate per frame - it is still running smoothly as you can see in my webgl demo (the occasional hiccups are not caused by the streaming approach). And even that could be further optimized to have a pool of tiles for each tile in the tileset so that Instantiate may not even be necessary at all.

    Unity's tilemap tools also allow you to draw gameobjects but like I said, once you go over several 10k tiles you'll kill performance. But you should also check if 2d tiles won't have that same issue. Try filling a gigantic 2d map the size you wish to create and see if editing is still smooth, if scene size gets bloated, if build times and size are increasing, if runtime speed is still okay. If not, then those built-in tilemaps won't cut it. In fact I just made myself a task to check out 2d tilemap workflows. :)

    As to physics I would recommend using 3D physics because it will be difficult to merge 3D tiles (3d meshes, 3d colliders) with just 2D physics. Instead, you can lock position & rotation of 3d physics to 2 axis. But I have a hard time imagining how that would work, like every physics body can only move along X and Z but not up (Y). That seems very limiting in a 3d world, so I would just go for full 3d physics if possible.
     
    oscarAbraham likes this.
  3. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,571
    Is it top down or isometric view? If the view is isometric, you'll need to use 3d physics.
     
  4. Deornoth

    Deornoth

    Joined:
    Oct 8, 2021
    Posts:
    10
    Thanks.

    Yes, I also have concerns about how the built-in tilemap system scales. I will be doing a load test soon.

    For my game, I definitely want to stick to 2D physics. Everything about the gameplay will be 2D, apart from the visuals. It would feel like a major hack to use 3D physics. I don't see any issues with 3D vs 2D physics. There won't be any 3D colliders: think of the 3D tiles as "visual sugar" on top of 2D polygons. Same goes for other things like characters and enemies.

    I like the idea of pooling 3d tiles, and then dynamically "placing" them (or as you say, streaming) as needed as they appear on the screen. I would definitely want to eliminate all instantiation per frame. It's a shame there's no way to take the same object and render it in multiple positions; though perhaps this is not a major issue, as pooling multiple tiles per type could solve this (although a little more memory hungry than I would like).

    Thanks for the ideas, and good luck with your engine. :)
     
  5. Deornoth

    Deornoth

    Joined:
    Oct 8, 2021
    Posts:
    10
    It will be "side-on" - like Terraria, or Starbound. It definitely won't need 3D physics.
     
  6. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,571
    Alright, my mistake. For some reason I assumed Hex tiles.
     
  7. Deornoth

    Deornoth

    Joined:
    Oct 8, 2021
    Posts:
    10
    It will be side-on and have hex tiles. Slightly nuts, I know, but there is a really good reason for this that is fundamental to the game.
     
  8. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,571
    Well, battle for wesnoth exists, so why not.
     
  9. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,981
    I did a load test myself and I can say it does not scale well. Every tile is a GameObject instance - even though you won't see those in the scene. That means a map of 100x100 in size is already creating 10,000 game objects. While this runs well at runtime since you only see a small portion of it on the screen, it can be excrutiating to edit such a map in the editor because depending on the edit operation / selected tool, you will notice lags, short freezes and even progress bars appearing.

    You can try it out yourself really quickly by setting up a tilemap with a single tile, then select the fill tool and drag out a rectangle. You can disable the preview drawing which makes the fill process faster, but after you painted about 150x150 tiles or more you will start to notice slowdowns in the editor, including progress bars when saving. You can still paint tiles just fine but the box fill tool can take a long time to show results.

    Also, this quickly bloats scene files. My test scene grew to over 750 MB (!) just by drawing once with the fill tool where it got to the point that I had to wait several seconds for the preview to update while dragging. That map I created that way is 2,000 by 1,400 tiles, or 2.8 million tiles altogether, and it now takes 15-20s to save or load in the editor. I can still paint fine but I get frequent split second freezes, which is annoying to say the least, and the fill tool prompts one to get a drink while waiting for it to complete. Editor memory usage however still sits at a comfortable 2.7 GB, I was actually expecting more.