Search Unity

Optimizing 2d tile based game

Discussion in '2D' started by manipalsingh, Jul 16, 2016.

  1. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    Hi,
    I'm trying to develop a 2d game in which the map is very large(150x150 tiles) made by using tiles which are all clickable. Since map is very large so at any time some of tiles will be visible(say 50x20 tiles).
    I am trying to dynamically change these visible tiles. Map is panable, so if I pan in some direction tiles, than in that direction some tiles are getting instantiated and in the opposite direction some tiles are getting destroyed.

    Doing this is fine but I'm getting a lot of lag while panning.
    I'm using Tiles as prefabs which are getting generated and destroyed in the run time providing a lot of lag.

    Any method to optimize this would be of great help.
     
  2. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Yes, don't use instanced tiles full stop. give me some idea exactly what the tiles look like or better yet post an image and i can better help you.
     
  3. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    Tiles I'm using are rhombus isometric tiles. I have approx. 40 different tiles.
     

    Attached Files:

  4. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    in that case I would manually create your mesh in code then write a function to change the UV coordinates on each tile to point in an atlas of all your textures. So basically your tiles all become one large mesh.
     
  5. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    So, you suggesting to me use one big image that I will make out of tiles and use that for my map instead of using individual tiles. But how will I be able to click on individual tiles then? Sorry if I got you wrong...
     
  6. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Yes one big mesh. Then ray cast to get the coordinates of where it hits the mesh, divide the cords by the individual tile size in both X and z and that gives you the tile hit.
     
  7. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    I like the idea, but what if each tile has something(say a number written on it) that is going to change during the run-time. I want to say is, map is also dynamic.
     
    Last edited: Jul 16, 2016
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Don't instantiate/destroy; use pooling instead.

    --Eric
     
  9. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    I was thinking about changing Texture of tile instead of instantiate/destroy
    Is pooling better than changing texture?
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Pooling would require changing the texture.

    --Eric
     
  11. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    tell me if I'm wrong, pooling is about disabling and enabling gameobject instead of destroying them.
    How is it related with changing the texture?
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You would have a pool of tiles, and recycle them as needed (which means changing the texture). No disabling.

    --Eric
     
  13. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    Okay, Thanks for the help...:)
     
  14. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    There's no reason you can't do it. You'll just have to rebuild the mesh each time you change tile data. If a map is large enough, it's worth breaking your map into chunks (sections of tiles, say 16x16) each with its own mesh. Then you just rebuild a section of it each time.

    Of course, this depends on your game's needs.
     
  15. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    Using my method he wouldn't have to ever change the mesh once it's created. He would only need a function to change 4 UV coords when he want's to change the texture on a tile. Normally I would pool but he has 22.5k tiles that sounded like the only thing that changed on them was the texture, so I don't see a need to pool. If he wants something extra on some of the tiles like text but not all of them then I would pool these overlays. OR better still just have a shader that has 2 sets of UV coords and 2 atlases. One for the terrain and 1 for the overlays.

    If i had the time I'd knock it up for him, but way too busy.
     
  16. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Arkon and Jason have right approach, this stuff is best done with groups of meshes where only the uvs are changed on demand.
     
  17. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    I found something similar to what I want in games like Vikings: War of clan. In Vikings the kingdom map is very large and some things are getting generated on the fly....How is that happening, using pooling as suggested as @Eric5h5 OR by using big mesh as suggested by @arkon and @JasonBricco ?
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Meshes aren't necessarily the best approach. Using a pooling system like SpriteTile (no, it wouldn't work for this, it's more for square tiles, not 45° angled) allows extremely large maps with minimal RAM usage, good speed, and more flexibility for tiles in terms of rotation/pivot point/overlapping/alpha performance (tight meshes). But I'd use meshes if you have thousands of tiny tiles on-screen at once, since that tends to overwhelm Unity's batching.

    --Eric
     
  19. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    Can you please give me some links (would be better if having some example on how to use pooling in such case.) using which I can get a head start...
    I'm getting a little confused:confused: here....
    Reason I said about Vikings game was that, their map is also changing dynamically, is that done using meshes?since in the map a lot of tiles are visible at any time.
     
  20. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    without looking at the vikings code there will be no way to tell what method they use. As for pooling go on the asset store there is at least one free asset that does this. @Eric5h5 is right when he says if they are ever going to be all on screen at once then the only way to go is a mesh, if you are always going to be zoomed in and only showing a subset of the map then pooling is the way to go.

    All Pooling is in a nutshell is never disabling objects, they just get reused, which usually involves moving the unseen ones and changing their attributes like what they look like, etc. So if in your case all 22.5k are in view you are still going to have to instantiate all of them in one go and thats going to be slow.

    I'm telling you know as I've been where you are, the mesh is the way to go, you will regret it and probably end up re writing the core of your game towards the end of your project when you see the performance on Mobile and especially Android.
     
  21. manipalsingh

    manipalsingh

    Joined:
    Apr 29, 2016
    Posts:
    12
    I changed some things, changed maximum number of tiles that will be visible at any time to 200. I tried using pooling but still fps is very low(varying b/w 5 to 250). Any suggestions for such low fps....!!

    @arkon would you suggest using large mesh for 200 tiles?

    Is there any other way because I really want game to be smooth, no lag.
     
  22. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    200 should be ok, archive up your assets directory and stick it on drop box and I will take a look for you.