0
votes

I'm working on a 2D app with multiple menus and I would like them to slide transition into each other (current menu goes left while new menu comes in from the right, for example).

My first attempt I wrote a script that would enable the parent GameObject for a menu and move the menu (lerp) across the screen. All menus were under the one canvas which was set to Screen Space - Overlay, but a different GameObject for each menu. This achieved the desired effect but when I ran in on my Android test phone the framerate would drop for 60 fps to 25 fps during the transition. I figured moving the menu GameObjects with all their elements was too much.

This led to attempt two where I made the GameObjects stay still and slide (lerp) the camera past the canvas instead. I made the canvas world space and scaled it to fit the camera perfectly. However, when testing again on mobile I found the framerate dropped to around 20 fps consistently. Not just during transitions but on menus too, even when not interacting with the menus.

Is there any way to keep the GameObjects still and move the Game View, if the canvas is set to Screen Space - Overlay or ScreenSpace - Camera? Is there any way to do simple menu transitions without slowing my app down like nobodies business?

1
moving a menu shouldnt take that many fps, your bottleneck is somewhere else - Lestat
one thing you can see in your project quality settings is what quality setting you have for your standard shader. (project settings-> graphics). you can turn them low for every setting and the canvas can be faster. other stuff you could do, would be to render the menus to a rendertexture and replace it with that for duration of the animation. that would get you max fps, but is a little bit of extra work unless you already have the code to do that(it's a little bit fiddly but that approach can be used to optimize canvas quite a lot). - Lassi Kinnunen
@LassiKinnunen I changed the graphics settings to little avail. I'm now working on your rendertexture suggestion. I can't get the image looking nearly right, no shaders that I've tried have had the right sort of colour pallet and none of them have supported the image masks I use in my scene. Do you have any suggestions? - Phedg1
if you already managed to render it(your canvas or the subobject in the canvas) into a rendertexture, just put that texture in a rawimage in the canvas you're moving(mat none), and disable the "real" elements? I'm not sure if I explained properly. but what I had been doing was to render some complex canvas elements into textures(via rendertexture, but reusing the same rendertexture for different elements) and grabbing those and using those instead of the more complex canvas elements. of course now that I think about it, you could use rendertex to just avoid redraw of canvas when moving. - Lassi Kinnunen
Both RenderTexture and the Texture.PixelRead methods were giving me bad textures. Both had a really low resolution upper left corner with a weird, inconsistent alpha in the same corner, for a display that is normally entirely opaque, and neither were rendering my ScrollRects with their content or their masks intact. (the content of the rect, once unmasked, would cover up most if not all of my screen) - Phedg1

1 Answers

-2
votes

In both methods, from the camera point of view, all the elements moved. This will trigger a redraw of the whole UI in every frame. This drawing can be slow, especially if you have many transparent elements on top of each other. There is no magic way to make things faster, but the manual addresses this issue in a complete section, which might be worth reading to identify what could be improved in your specific case:

UI Best Practices