Reputation: 2308
I'm developing a 2d menu heavy mobile game, which uses a lot of canvases, panels, popups etc. In the beginning I had all menus active at all times, but only the ones that the user can use lie within the frustum (i.e. the others are just translated out of sight). Then I switched to deactivating the menus that the user can't see, just to increase the game performance. This however causes many inconveniences for me, like e.g. state variables in the Animator component resetting when de- and reactivating a GameObject.
So what is the best way to do this? Is the deactivation of temporarily unused canvases even worth it, or is Unity automatically clipping away the UI that lies out of the frustum, so there's basically no performance cost?
Upvotes: 0
Views: 3599
Reputation: 11953
According to this Unity optimization document, disabling the Canvas (not deactivating its Game Object!) is the best way to hide it.
It's cheap to disable and re-enable the Canvas.
Upvotes: 1
Reputation: 10750
As you said your game is menu heavy, even disabling/enabling can cause overhead. This is something I have faced this in one of my projects in past.
A word of advice is to use Canvas Group on your menu objects and change their alpha (0 = closed, 1 = opened), Interactable and BlockRaycasts parameters.
If you have menu script on every menu/panel just disable/enable that on open/close.
Update:
Typical uses of Canvas Group are:
Other references:
https://www.youtube.com/watch?v=wbmjturGbAQ
https://github.com/Unitarian/Unity-Extensions/tree/master/Menus
Hope this helps
Upvotes: 3
Reputation: 140
How about creating interface like
public interface IOpenable
{
bool IsClosed { get; set; }
void OpenWindow();
}
}
then make every element subscribe to some controller and that controller can handle everything like so
public class MenuController: MonoBehaviour
{
public List<IOpenable> MenuList;
void Awake()
{
MenuList = new List<IOpenable>();
}
public void TryClose(IOpenable sender)
{
foreach (var i in MenuList)
{
if (!i.IsClosed && !sender.Equals(i))
i.OpenWindow();
}
}
}
This way you can try to close all other windows you don't need while opening a new one. This is just a rough idea but it seems clean and fast for me.
Upvotes: 1