Search Results for

    Show / Hide Table of Contents

    Using IControlContainer

    Sometimes you may want to have a control being able to manage additional controls under it, for example you want a control that will show another control if its property value is above a certain threshold.

    This would technically be possible by just checking the value change in the inspector and enabling/disabling the controls that should be affected, but that requires to write code to handle that for every occasion, and we want it to be automatic.

    To do that we will need to use the IControlContainer interface.

    Let's take our custom control template and implement the IControlContainer interface:

    using System.Collections.Generic;
    using UnityEditor;
    using VRLabs.SimpleShaderInspectors;
    
    namespace TestControlNamespace
    {
        public class MyCustomControl : PropertyControl, IControlContainer
        {
            public MyCustomControl(string propertyName) : base(propertyName)
            {
            }
    
            protected override void ControlGUI(MaterialEditor materialEditor)
            {
            }
    
            public void AddControl(SimpleControl control)
            {
            }
    
            public IEnumerable<SimpleControl> GetControlList()
            {
            }
        }
    }
    

    The implement the interface you need to implement the AddControl and GetControlList methods in you class.

    The first method is generally used in the generated chainable methods to add a new control under this one, meanwhile the second one is used when the inspector fetches properties.

    How you store those controls is up to you, in this case we will use a list.

    And in the meantime, we also add a simple range property and get the control to do something:

    using System.Collections.Generic;
    using UnityEditor;
    using VRLabs.SimpleShaderInspectors;
    
    namespace TestControlNamespace
    {
        public class MyCustomControl : PropertyControl, IControlContainer
        {
            public List<SimpleControl> Controls { get; set; }
    
            public MyCustomControl(string propertyName) : base(propertyName)
            {
                Controls = new List<SimpleControl>();
            }
    
            protected override void ControlGUI(MaterialEditor materialEditor)
            {
                EditorGUI.BeginChangeCheck();
                materialEditor.RangeProperty(Property, Content.text);
                HasPropertyUpdated = EditorGUI.EndChangeCheck();
            }
    
            public void AddControl(SimpleControl control) => Controls.Add(control);
    
            public IEnumerable<SimpleControl> GetControlList() => Controls;
        }
    }
    

    Only notable mentions are the 2 methods implementation being done in an unusual way, this is for the most part just a "shortcut" that can be done when the method implementation consist in only one operation (if you're not confortable with it, you can just write it like you're used to, the result is the same). Also the RangeProperty method for some reason doesn't have an overload that accepts a GUIContent, so we had to pass just the text string of it (unity pls fix this thanks).

    Now our control properly displays any float property that is being given to it, but if you add any control to this one they will simply not display, that's cause it's our responsibility to handle that:

        materialEditor.RangeProperty(Property, Content.text);
        HasPropertyUpdated = EditorGUI.EndChangeCheck();
        if (Property.floatValue > 0.5f)
        {
            foreach (SimpleControl control in Controls)
            {
                control.DrawControl(materialEditor);
            }
        }
    }
    

    We first check if the property has its value above 0.5 and cycle all controls inside our list to draw them.

    If you try to move the slider around you will see that other controls added to this control will show up as soon as you surpass 0.5.

    Tip

    As you probably noticed, we use the DrawControl method to display a control's content, but we usually override ControlGUI when deciding what to display in our controls. This is cause DrawControl internally calls ControlGUI, but it also does additional checks, like checking if the control should be visible to begin with, or if should be in a disabled state.

    Finished example class

    using System.Collections.Generic;
    using UnityEditor;
    using VRLabs.SimpleShaderInspectors;
    
    namespace TestControlNamespace
    {
        public class MyCustomControl : PropertyControl, IControlContainer
        {
            public List<SimpleControl> Controls { get; set; }
    
            public MyCustomControl(string propertyName) : base(propertyName)
            {
                Controls = new List<SimpleControl>();
            }
    
            protected override void ControlGUI(MaterialEditor materialEditor)
            {
                EditorGUI.BeginChangeCheck();
                materialEditor.RangeProperty(Property, Content.text);
                HasPropertyUpdated = EditorGUI.EndChangeCheck();
                if (Property.floatValue > 0.5f)
                {
                    foreach (SimpleControl control in Controls)
                    {
                        control.DrawControl(materialEditor);
                    }
                }
            }
    
            public void AddControl(SimpleControl control) => Controls.Add(control);
    
            public IEnumerable<SimpleControl> GetControlList() => Controls;
        }
    }
    
    In This Article
    Back to top Copyright © VRLabs.
    Generated by DocFX