Hide/Show properties dynamically in inspector.

Here’s the thing.

How do I hide/show items in the inspector tab dinamically, like iTween? When I select ‘MoveBy’, it loads all the properties available to the ‘MoveBy’ function. When I change it to something else, it unloads the properties (hides them from the inspector), and shows the properties available to the newly selected function.

I’m doing something like that, but I’m completely lost. I’ve read the ‘Extending the Editor’ section, and tried [ExecuteInEditMode], but I just don’t know how to change the property display status on the Update() function.

I know it’s super necro post but I’ve got cool attribute to share. It allows to conditionally display field inspector based on some other values, like values of other fields.

ConditionalFieldAttribute.cs

public bool WanderAround;
[ConditionalField("WanderAround")] public float WanderDistance = 5;

public AIState NextState = AIState.None;
[ConditionalField("NextState", AIState.Idle)] public float IdleTime = 5;

alt text

You need to create a Custom Editor for your script. Then you show the fields based on the internal state of the object being edit. Eg:

public class MyScript : MonoBehaviour
{
  public bool flag;
  public int i = 1;
}

[CustomEditor(typeof(MyScript))]
public class MyScriptEditor : Editor
{
  void OnInspectorGUI()
  {
    var myScript = target as MyScript;

    myScript.flag = GUILayout.Toggle(myScript.flag, "Flag");
    
    if(myScript.flag)
      myScript.i = EditorGUILayout.IntSlider("I field:", myScript.i , 1 , 100);

  }
}

In the example the Inspector will show a slider only if flag is set to true.

The Inspector can be customized by creating a Custom Editor for your script. In your Custom Editor you can then disable fields using EditorGUI.DisabledScope, or hide them completely using FadeGroupScope.

Creating a Custom Editor

First I create my actual game script:

using UnityEngine;

public class MyScript : MonoBehaviour
{
    public bool hideBool;
    public bool disableBool;
    public string someString;
    public Color someColor = Color.white;
    public int someNumber = 0;
}

To create our Custom Editor, we create another script with the exact same name, with “Editor” appended to the end. Open and initialize the Editor script:

using UnityEngine;
using UnityEditor;
using System;

[CustomEditor(typeof(MyScript))]
public class MyScriptEditor : Editor
{
    override public void OnInspectorGUI()
    {
    }
}

It will need to be using UnityEditor, and the class (MyScriptEditor) has to derive from Editor (as opposed to the default MonoBehaviour). The CustomEditor attribute informs Unity which component it should act as an editor for. In this case, it is the script MyScript.

Since we want to replace what displays by default in the Inspector, we add the function override public void OnInspectorGUI(). If we look at the Inspector for our game object now we can see that it is completely blank and we can set it up from scratch exactly how we want.

Hiding and disabling fields

Here is an example showing both disabling and hiding fields. I will explain what it is doing below:

using UnityEngine;
using UnityEditor;
using System;

[CustomEditor(typeof(MyScript))]
public class MyScriptEditor : Editor
{
    override public void OnInspectorGUI()
    {
        var myScript = target as MyScript;

        myScript.hideBool = EditorGUILayout.Toggle("Hide Fields", myScript.hideBool);

        using (var group = new EditorGUILayout.FadeGroupScope(Convert.ToSingle(myScript.hideBool)))
        {
            if (group.visible == false)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PrefixLabel("Color");
                myScript.someColor = EditorGUILayout.ColorField(myScript.someColor);
                EditorGUILayout.PrefixLabel("Text");
                myScript.someString = EditorGUILayout.TextField(myScript.someString);
                EditorGUILayout.PrefixLabel("Number");
                myScript.someNumber = EditorGUILayout.IntSlider(myScript.someNumber, 0, 10);
                EditorGUI.indentLevel--;
            }
        }

        myScript.disableBool = GUILayout.Toggle(myScript.disableBool, "Disable Fields");

        using (new EditorGUI.DisabledScope(myScript.disableBool))
        {
            myScript.someColor = EditorGUILayout.ColorField("Color", myScript.someColor);
            myScript.someString = EditorGUILayout.TextField("Text", myScript.someString);
            myScript.someNumber = EditorGUILayout.IntField("Number", myScript.someNumber);
        }
    }
}

First we target our script. Then we decide which fields from that script to display, and how.

The first field I display is hideBool, using EditorGUILayout.Toggle. This creates a toggle that displays similarly to how the Inspector shows a bool field by default.

Next I will create a group of fields that I can hide depending on the value of hideBool using FadeGroupScope. The example of this function in the Unity scripting reference shows it being used with an AnimBool to animate the opening and closing, however the Paint() method does not work in their example and I didn’t feel like figuring that out as I don’t actually want an animation, I simply want the fields to instantly appear or disappear. The reason this is important is the FadeGroupScope is expecting a float value between 0 and 1 to be passed in to determine exactly how open or closed it should be, as opposed to a bool. I used Convert.ToSingle() to convert my bool to a 0 or 1.

Inside this function are some examples of ways you can display your fields which I pulled from the script reference.

After all of this, I display my disableBool using GUILayout.Toggle. This is another way of displaying a toggle with some different options, which by default shows the checkbox on the left.

Next we set up the DisabledScope, which is simply passed a bool and will disable and grey out any fields inside of it.

This is how it looks once done:

Options unchecked:
85744-inspectorfieldswitheditorscript-visible.png

Options checked:
85745-inspectorfieldswitheditorscript-hidden.png

Since you’re overriding a public method ( OnInspectorGUI() ) of the Editor class, the signature of the overriding method should look like

override public void OnInspectorGUI()

Why do you bother with hidin and showing. Split your behaviours into separate components, you will have these components ready for editing in the inspector, your main behaviour will just switch these additional components (they might derive from same base class, or you can use interface)

Here is a deep tutorial

I was able to do this right off the bat with this :

public enum SpawningMethod
    {
        Instantanious,
        Delay
    }

[SerializeField] private SpawningMethod spawnMethod;

[ConditionalField(nameof(spawnMethod), false,SpawningMethod.Delay)]
[SerializeField] private float delayBetweenSpawns;

When putting ‘spawnMethod’ in the inspector on “Delay”, the “delayBetweenSpawns” field appear.

You can use my UPM Attributes package to do this.
Also, there are other cool atributes.

It’s free!