I'm currently working on a 2D tile-based side-scroller (similar to Terraria). I am using Unity's TileMap feature to draw tiles onto the screen and have my player collide with them as if they were blocks. A 2-dimensional array of ints (8000 on a side for a total of 64M values) is generated to signify tile values, and tiles are placed in the world corresponding to this array at runtime. I have also implemented a rudimentary chunk system which loads tiles in 10x10 areas at runtime relative to the player's position. I'm using Unity 2019.1.0f2 Personal (the latest build of Unity at the time of posting this.)

Whilst attempting to optimize my game's performance, I noticed that the "Physics2D.TilemapColliderTileUpdate" function is causing extreme lag spikes in the game whenever I load in new tiles. This is expected, as adding new tiles will cause the tilemap to recalculate its collider shape. But this is taking up way too much CPU for my needs. In the profiler picture shown, my game runs at a solid 700-1000 FPS normally, but shoots down to 5-20 FPS when new chunk(s) are loaded (the orange lag spikes are where the collider update function is called.) This causes an extreme amount of stutter, and is even more present in an executable build where the unity editor is not in the way of things (in build, FPS jumps down to 2-6 FPS.) I know that this is the case since I can disable the tilemap collider, and of course, there is no more issues. But obviously I wish to have this collider, so that solution will not work.

I was just wondering if there is any way to calculate a tilemap collision shape or different collider system entirely in order to make the game more playable? I can't seem to find any resources on this subject, and am more towards the intermediate side of things when it comes to coding experience. I have attached a picture of some profiling I did when running the game (the CPU usage graph shows a far more tame result as opposed to the usual bad performance), as well as a link to the project folder for my game so the project can be ran an assessed (all of my world generation and chunk management is done in the World.cs script, FYI.) Thank you for your help!

Project folder link: https://drive.google.com/open?id=14YSvDviZ2_KpZAflaCXZ2JYM-kxSiIu_

Profiling Picture

  • \$\begingroup\$ How many Grids do you have active in the scene? I would expect one per 10x10 chunk. If you only have one, then when youre adding tiles to a grid that starts 10x10, you're forcing the engine to resize the grid as 10x20, 20x20, etc. which causes it to have to recalce the collider. I suspect most of your performance hit is going to come from that activity. If you load them as separate Grids, youll end up only processing one 10x10 at a time, so if you have 4 on the screen, that's 25% the hit. \$\endgroup\$ – Stephan May 2 at 18:14
  • \$\begingroup\$ @Stephan I do only have one grid active in the scene. However, wouldn't making more grids create more tilemaps, and thus a much more confusing scene? And if not, how might I go about creating grids through scripts? Thank you for your reply! I'll see what I can do in the mean time. \$\endgroup\$ – Ben Mroz May 3 at 19:33
  • \$\begingroup\$ Tilemaps are conceptually a layer of tiles within a grid. If you treat the grid as your chunk, you should see better performance, as the grids change event will only hit 100 tiles vs however many you're keeping in the grid at a time. Grids are just like any other game object. While the information is still thin on how to use them, there are questions on how to instantiate them from code. Check the examples in the demo github \$\endgroup\$ – Stephan May 3 at 20:44

Your Answer

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

Browse other questions tagged or ask your own question.