How to disable (hide) UI elements without disabling them

Hi

I have an issue where I want to hide certain elements without actually disabling them.

So if I have a toggle that turns another UI element on and off, how can I achieve this without changing the active state of the target element?

The issue for me is that if the target element has a script attached and I want the element to start hidden (disabled), it also disables the attached script which I don’t want to happen.

In DFGUI this was handled by giving UI elements a ‘Visible’ toggle so you could change the visibility rather than the active state. An invisible object also allowed raycasts through.

I did try adding a Canvas Group component and toggling the alpha, however even when alpha = 0 the elements were still being interacted with. For instance, if the element was a toggle and even when it was hidden (alpha = 0), I could still click where the toggle was and it would change the toggle state.

Thanks

3 Likes

+1, this is super annoying and requires hacky workarounds.

I have started a couple of other posts on this topic already…

3 Likes

Disable the component? GetComponent(Text).enabled = false;

–Eric

4 Likes

Hi Mikeysee, curious as to what the workarounds you found are. Easiest one I can think of is to move items out of the canvas range instead of toggling their active state.

Eric, I don’t think that will work - my elements contain child elements made up of different items (toggles, text, images etc) which won’t always be the same amount - your way would involve specifying every sub item right? And hard coding them all into the solution which wouldn’t work if more items are added / removed.

The functionality in DFGUI works where the element and all child elements are hidden if the ‘visible’ checkbox is unticked. Essentially it performs the same way as setting the element as inactive, except that it’s still active (just hidden).

EDIT: The best solution would be too make the UI non-interactable (pass through raycasts / clicks / touches) when a Canvas Group is added and alpha set to 0.

1 Like

I’ve just successfully tested another workaround that changes the scale of the Rect Transform to 0,0,0 when the element should be hidden - this keeps it hidden when it needs to be while staying active and not having to worry about moving things around.

Still not ideal though…

2 Likes

Imo canvas renderer should work like mesh renderer where u could disable them in editor and via scripting… im really suprised that actual canvas renderer is counter intuitive compared to mesh renderer

As another workaround you probably could override OnFillVBO and add bool parameter to every script where u need hiding functionality but not ideal too

1 Like

I had a run in with a similar problem, however for me the solution was to disable the hidden elements (which are complex nested panels in my case) and reinitialize their them to the correct state when enabling (this may need some refactoring separating “presenation” from “logic”), as invisible/non-interactable/non-blocking canvasgroups are still being rendered/meshed it seems, and this can affect performance in a big way (especially in the webplayer, but i suspect this is the case on mobile too)

I’m just moving them to a non-canvas GameObject by changing their parent (I remembered from the vids that GUI objects only get rendered if they’re under a canvas). Then I can make them visible again by moving them back into the canvas, though sometimes I have to check their positioning.

1 Like

Hmm, I did forget about draw calls actually… using my hack of changing the scale to 0,0,0, it actually increases(!) draw calls when the object is ‘hidden’ (scale 0,0,0).

So, this solution probably won’t work.

Any Unity devs here with an idea? Should I submit a bug?

1 Like

If I have understood what is being asked, I have had success with…

CanvasGroup cg = MyRectTransform.GetComponent();
cg.interactable= false;
cg.alpha = 0;

Edit: Don’t forget to clear the BlockRaycasts on any overlaid RectTransforms.

5 Likes

Unless I’m confused also then CanvasGroup should be the solution.

3 Likes

Yep, it seems to work fine now - I can only assume there was an issue with it in previous betas, or I’m just a numpty… One thing though - is it possible for completely hidden (alpha = 0) CanvasGroup elements to not be drawn? ie - even when something is hidden it still seems to take up draw calls.

3 Likes

Maybe try [gameObject.SetActive](http://docs.unity3d.com/ScriptReference/GameObject.SetActive.html)(false); for the relevant object?
That works for me in a quick test.

Hey there,

If you have a bunch of elements mixed in that you want to turn on and off you could take advantage of camera layers. Group all elements that need to be toggled into their own layer and with code you could toggle the camera to not draw that layer. I am 80% sure you could do the same for the input module to stop input on that layer. (I am on my phone so it’s slow to google)

Regards

Learned something new when I got home. This will not work. uGUI does not care about layers. Seems weird.

Being able to disable the CanvasRenderer just like we can disable a Mesh Renderer to hide an individual object would be nice. Using a Canvas Group and setting Alpha to 0 doesn’t provide control over each individual object within that Canvas Group plus there is additional processing required to alter the vertex colors of all those UiVertex?

As far as I know disabling a Mesh Renderer was the most efficient way to make an object disappear.

3 Likes

I ran into a very odd bug (that only appeared on certain Android devices) relative to enabling/disabling UI items. Moving to using a .alpha on a CanvasGroup worked around the issue, but there are way more draw calls that route. I would really like a way to hide without draw calls or side effects to my scripts.

maybe u can try
UI.Graphic.CrossFadeAlpha

+1 for needing to disable the component, not the object.

This worked for me, and I setup the script to be Universal; meaning, it can be used by any Game Object for any Tag. Here you go:

// Variables
GameObject popUp1;
Vector3 currentPosition;
public string tagName = “”;

// Use this for initialization
void Start () {
// Let’s hide the pop-up for now
popUp1 = GameObject.FindWithTag (tagName);
currentPosition = popUp1.transform.localPosition;
popUp1.transform.localPosition = new Vector3 (1000, 1000);
}

// Method for showing the pop-up
void PopUp () {
popUp1.transform.localPosition = currentPosition;
}

1 Like