Question C# Plugin - Make TextField initially hidden?

Sally Whitemane

Well-known member
Featured Contributor
Messages
263
Reactions
943
Points
93
Patreon
sallyw
I have a Toggle that is (and must be) unchecked by default.
The nearby TextField visility/active-state must be tied to the Toggle state.

Problem: the TextField stays visible.

C#:
JSONStorableBool jbShowBands;
UIDynamicTextField bandInfoText;

// inside Init() ...
jbShowBands = Utils.SetupToggle(this, "Show Bands", false); // Toggle checkbox off by default (MacGruber Utils)
jbShowBands.setCallbackFunction += ToggleShowBands;
jsBandInfoText = new JSONStorableString("BandInfoText", "myText");
bandInfoText = CreateTextField(jsBandInfoText);
bandInfoText.height = 300f;
// does not hide TextField if called in Init(), does hide TextField if called in Update()
bandInfoText.gameObject.SetActive(false);

// Toggle Callback
private static void ToggleShowBands(bool b)
{
    spectrum.showBands = b;
    bandInfoText.gameObject.SetActive(b);
}

By adding this to Update() it does work:
C#:
if (!spectrum.showBands)
   bandInfoText.gameObject.SetActive(false);
But I don't like that it's being checked every frame. :unsure:

Any Ideas how to hide the TextField properly from Init() or based on a event?
 
Last edited:
i don't know about proper but maybe add it in start() not init()? Or in init after UIUpdate(). If not, on discord you'll definitely find answers, people don't use the forum that much here
 
Upvote 0
I've finally figure out a way to properly do this with the native UI of VaM. Because it was driving me nuts, I did several implementations.
  1. Toggling the gameobject will not work because the method behind VaM's UI re-enables them no matter what you do. And you have actually zero solution to override the UI properly and force the deactivation after calling the parent method.
  2. The only remaining solution is to change the styles. But you end up having some weird spacing / padding if you try to tweak the height of the RectTransform
So I tried tons of other things, and ended up with the perfect solution :

Make an array of UIDynamic elements
C#:
UIDynamic[] OptionList;

Add your UI elements to the array
C#:
OptionList = new UIDynamic[1];
// Create your element
OptionList[0] = CreateSlider(Something, true);

After all your elements are created, set their default state
C#:
ToggleOptionsCallback(false);

Write a function handling the hide/show system
C#:
        protected void ToggleOptionsCallback( bool show ) {
            foreach( UIDynamic uidElem in OptionList ) {
                if( show == true ) {
                    uidElem.GetComponent<LayoutElement>().transform.localScale = new Vector3(1,1,1);
                    uidElem.GetComponent<LayoutElement>().ignoreLayout = false;
                } else {
                    uidElem.GetComponent<LayoutElement>().transform.localScale = new Vector3(0,0,0);
                    uidElem.GetComponent<LayoutElement>().ignoreLayout = true;
                }
            }
        }

You could obviously pass your UI array to the function and make it a generic one. But you get the idea.

To explain :
  • ignoreLayout makes the UI "floating" outside of the UI flow. If you don't rescale, you will see it stacking on top of previous fields
  • transform.localScale obviously scales it to nothing to make it invisible.

You could argue that this technic is not super nice for drawcalls, which is true. I even (in another project) noticed that rescaling UI to "nothing" doubles the draw calls for this particular element. But the UI of VaM is so intensive that one or two drawcall will not make a big difference while you are setting a few options.
Knowing that, as soon as the UI closes, the gameobjects are disabled so the drawcall issue vanishes.

If you wanted to do some additional treatments to a group of UIDynamic elements, you could also either override InitUI or InitUIAlt.

You can find an implementation of this in VAMMoan with the advanced options of the pelvic slap settings.
 
Upvote 0
Back
Top Bottom