- Home /
Is UI ruining my fps on some of android devices?
Hi guys.
My game is very small, but have a lot of UI objects, I have somewhere 13-21 drawcalls in my game. Low triangles, using low textures, etc.
The game runs perfectly fine on Galaxy S7 (60FPS), but Nexus 10 tablet is unplayable (around 10-15 FPS)
I have now learned that some people after upgrading to Unity 5.x experience low FPS in their android games when using Canvas and UI elements.
The problem is my game is solely based on UI. I have one canvas and a lot of children to it. 90% of them are disabled at a time (GameObject.SetActive(false)) and when they are needed I enable them.
Could be this causing the problem? Last time I run the profiler - memory allocation was about for object count 32 MB.
EDIT: I found out that performace was improved by assigning a material with Sprites/Default shader to each UI Image (otherwise Unity would use standard shader, which is too heavy for mobile) - preformance on phones - galaxy s7, galaxy Grand Prime is awesome, but Nexus 10 tablet is not as good (it may be due to its too high resolution). I believe I can still improve it by choosing the right shaders. What are the cheapest shaders for mobile - one very basic 2d and one with transparency?
Answer by xpavelos · Feb 16, 2017 at 09:54 AM
I have finally solved the problem. Low performance in case of my game was caused by a few basic mistakes I made:
the most important one: I used to have several full screen images (some of them were used as a "flash" effect) - when they were needed their alpha was changing from 0-255. When their alpha was 0 I did not turn the gameObject off. This caused serious performance drop (they were invisible and they had to be rendered anyway and transparency is very expensive).
around 5 fps improvement when I turned off 9-slice sprite only on one button (with transparency).
leaving images material property empty - unity used default shader, which was much heavier for mobile
By fixing those issues I was able to increase performace up from 10-15 fps to 60 on Nexus 10 tablet (other devices were fine).
About first mistake: why don't you use CanvasGroup for fade ui graphics? When alpha goes to 0 it automatically excludes all children from render list (and from calculating dynamic batches) so you dont need to turn the gameObject off. Also if you dont want to use CanvasGroup it is better to turn off CanvasRenderer component ins$$anonymous$$d all gameObject.
Well, it seems I lack a lot of knowledge. I didn't even know that CanasGroup can control alpha. This is great. Thanks for pointing that out!
I want to add an information about that. I was using CanvasGroup for more than 15 menus and then I noticed that this is a mistake. It creates huge FPS problem, I just make an animation to closing menu by using alpha and then turn off the Object and it's working much more better now.
Answer by steo · Feb 13, 2017 at 04:52 PM
How often do you enable/disable gameObjects inside canvas? Note that canvas caches batches and it is so expensive to recalculate batches. Every time when you enable/disable gameObjects or change their transform or Image/Text properties, canvas recalculate ALL children. Try to separate you game between two or three canvases.
Note that not only dynamic batches count is important. It is also important how many CPU ticks are spend to calculating these batches. Try to profile your game. Who of two: CPU or GPU spend more time for each frame?
Raycast target
also expensive. Try to disable it where you don't need input.
@steo Thanks for your answer. I don't enable/disable them very often. The reason I have so many children is because they are different screens in my game (like, menu, game, help, etc). Would it be better if I split each game screen into other canvases or even scenes (I don't want to lose on loading times)? Raycast target is disabled on all items (except the ones I need), also Rich Text is disabled, etc...
But anyway - I found out this wasn't the reason of poor performance - it's the images that do not have any material assigned - in this case Unity will use standard shader which is too heavy for mobile. So I created material and gave it Sprites/Default shader. Performance increased, but tablet (Nexus 10, which has I believe 2k resolution) could be better. I think it's because mobile doesn't like UI Images, especially when they are resized to fullscreen.
What can I do? Use better shader? Which one (I need transparency)? What to do with images?
Unfortunatly I have not Nexus 10 for tests but high resolution may be a problem. You can download Sprites-Default shader sources and remove all what you don't need in it. Every line you remove will improve performance. You can download default shaders there.
You can also check overdraw on your scene (in sceneView at left-top corner select overdraw
). $$anonymous$$aybe you can reduce overdrawed squares?
@steo I could reduce overdraw only by a tiny little bit, I still don't think this is the case, because the game runs perfectly on other devices. I need to learn shader program$$anonymous$$g in order to edit their code. Thanks!
Your answer
Follow this Question
Related Questions
On Android. How many lights can you have in a Scene or the total game? 1 Answer
Great FPS Dilemma Even With Low Tris & Low Batches 0 Answers
Fixing fill rate issue on Android - best approach? 0 Answers
[Android] Significantly Worse performance on better device - 64bit CPU problematic? 0 Answers
Profiling PostLateUpdate.FinishFrameRendering Causes Major Spikes in Performance for Android Game 0 Answers