0
\$\begingroup\$

after year of development and week of unsuccessful optimization I turn for a help from you, guys.

So, my game is turn-based strategy with hexagon map. One hexagon consists of one texture for hexagon tile type and seven subtiles, which carry spriterenderer with graphics like piece of town. So if soldier steps on the subtile, the graphics of subtile hide.

haxegon with subtiles

On good machines like mine, if I zoom out maximally (45 orthographic size) on 1920x1080 and have visible around 18x16 tiles I get solid 160-200 FPS at MAX details, but on my laptop I barely get 25FPS on 1280x720 and LOW details. Each tile has resolution of 636x499.

I have tried:

  • Simple shader on SpriteRenderer supporting transparency, just merging texture with color (This had those best results of 160-250FPS at HIGH-END and 25FPS on LOW-END)
  • Creating separate material for each subtile and replacing SpriteRenderer with Quad mesh, so those subtiles are statically batched or GPU batched (but I guess they did not batch at all, because frame debugger showed that sometimes more fo the same pieces got rendered and then sometimes just one)

    enter image description here

So this is just the 50x50 game, when I start large map, like 120x100, it's not really that worse, so I think the problem is just in the graphics and not in the amount of objects.

What are your suggestions I should try to get better performance on LOW-END devices? Do you think that manual GPU-instancing would make it faster? I think, there would be a lot of trouble maintaining which graphic to render and which not.

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

Without seeing any code, we'll have to guess at what is going on or things that could be attempted. This set of solutions assumes the problem IS the number of things:

  • Some of your textures could be combined it seems. My guess is each of those trees is an individual sprite, even though you clearly put them in exact places. You can potentially draw that type of sprite to a hex-type programmatically and draw the hex as a single flat texture.
  • Similar to the above, it doesn't seem like this needs to be redrawn each time. Were you to take the drawn scene and save it you could simply be treating it as a background until it needs being updated.

Note: these may not be possible in Unity; but any framework that you manually perform double-buffering would be one that you could essentially double-double buffer, storing only what repeats in the second buffer.

This set of solutions assumes the problem is RAM:

  • A likely problem is that you're probably storing too many references or pieces of data. Start changing your doubles to floats, your longs to ints, and consider not using data structures like Dictionaries wherever you can. Self-expanding Data structures tend to increase by orders of 2, meaning they are going to average on about 75% memory efficiency.
  • Stop storing redundant references. A technique I often use is store the references in an array and then store an enum that indexes me into the correct place of the array.

This set of solutions assumes issues in the drawing code:

  • You may consider batching the objects yourself before passing them to the sprite batcher. I'm not sure how efficient the sprite batcher is here.
  • You should check to make sure you're not performing the same projection over-and-over somewhere. If, for example, when you go to select a unit with a mouse you project everything to the screen first, you're doing a HUGE number of matrix multiplies when you could simply cast your mouse to world space.

Those are the best suggestions I have with my morning coffee ;)

\$\endgroup\$
  • \$\begingroup\$ Thanks for you suggestion, I will take even deeper look into it. \$\endgroup\$ – Pepa Gazdoš May 4 '18 at 8:59

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.