Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
17
Question by pedronaroga · Dec 07, 2011 at 06:37 PM · inspectorhidepropertiesexecuteineditmode

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.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

6 Replies

· Add your reply
  • Sort: 
avatar image
29
Best Answer

Answer by luizgpa · Dec 07, 2011 at 09:04 PM

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.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Linmst · Jan 21, 2014 at 11:28 PM 0
Share

var myScript = target as $$anonymous$$yScript;

↑ This line helps me a lot! Thanks man :D I'm a new guy in Custom Editor and I'm learning this with the basic tutorial on the official website. But somehow it told us to use "target.variable" directly and it doesn't work anyway until I add the line in your script.

avatar image jnt · Apr 20, 2015 at 08:45 PM 0
Share

Doesn't work for me at all... :( alt text

inspectortoggle1.jpg (22.5 kB)
inspectortoggle2.jpg (24.1 kB)
avatar image noemis · Nov 08, 2016 at 02:19 PM 3
Share

the answer should be edited, it works only if Campusanis answer is also considered. just add:

override public void OnInspectorGUI()

avatar image
66

Answer by Deadcow_ · Mar 16, 2018 at 06:07 AM

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

Comment
Add comment · Show 27 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image piratekittycat · Mar 23, 2018 at 03:03 AM 2
Share

I love this approach, but I think you are using some custom extensions that aren't included in your code. In ConditionalFieldAttributeDrawer.cs I had to rewrite PropertyToCheck.IsNullOrEmpty() as string.IsNullOrEmpty(PropertyToCheck) and had to extract the enum name from the SerializedProperty manually (I assume AsStringValue() is an extension method.)

avatar image Deadcow_ piratekittycat · Mar 23, 2018 at 05:16 AM 0
Share

Yep, it's true. This attribute is part of my library. There is more lovely stuff there, although most of it is not documented

avatar image peterpan2022 piratekittycat · May 03, 2018 at 07:13 AM 0
Share

Could you share how you extracted the enum name? I went with:

 if (conditionProperty.propertyType == SerializedPropertyType.Enum) {
     int index = conditionProperty.enumValueIndex;
     conditionPropertyStringValue = conditionProperty.enumDisplayNames[index].ToUpper();
 }
 

avatar image Deadcow_ peterpan2022 · May 03, 2018 at 07:32 AM 0
Share

Yep, I do the same. There is my extension method for Serialized Properties:

 /// <summary>
 /// Get string representation of serialized property, even for non-string fields
 /// </summary>
 public static string AsStringValue(this SerializedProperty property)
 {
     switch (property.propertyType)
     {
         case SerializedPropertyType.String:
             return property.stringValue;
             case SerializedPropertyType.Character:
         case SerializedPropertyType.Integer:
             if (property.type == "char") return System.Convert.ToChar(property.intValue).ToString();
             return property.intValue.ToString();
             case SerializedPropertyType.ObjectReference:
             return property.objectReferenceValue != null ? property.objectReferenceValue.ToString() : "null";
             case SerializedPropertyType.Boolean:
             return property.boolValue.ToString();
             case SerializedPropertyType.Enum:
             return property.enumNames[property.enumValueIndex];
             default:
             return string.Empty;
     }
 }
avatar image qua11q7 · May 07, 2018 at 10:57 AM 0
Share

Thanks for that great extension! It is really easy to use but i am having problems with array properties. I have only added "ConditionalFieldAttribute.cs" and "ConditionalFieldAttributeDrawer.cs" scripts to my project. When i add a ConditionalField attribute to an array, it doesn't hide the properties in the inspector. I am using 2017.4.1f1 edition of unity and i couldn't get it to working. Thanks!

avatar image Deadcow_ qua11q7 · May 07, 2018 at 11:00 AM 0
Share

Yey. Like, 14 days ago I fixed this issue. Check my latest commit and this method specifically

https://github.com/Deadcows/$$anonymous$$yBox/blob/master/Attributes/Editor/ConditionalFieldAttributeDrawer.cs#L50

avatar image qua11q7 Deadcow_ · May 07, 2018 at 11:26 AM 0
Share

I am indeed using the latest version. I've added two images below to show what i did. alt text alt text

Is there something that i am doing wrong? I've put your "ConditionalFieldAttribute.cs" in Assets folder and "ConditionalFieldAttributeDrawer.cs" file to Assets/Editor folder. It works with normal fields but it doesn't hide arrays. Thanks for the help!

conditionalfield.png (2.6 kB)
conditionalfieldresukt.png (5.3 kB)
Show more comments
avatar image YD_JMysior · May 19, 2018 at 11:13 AM 1
Share

This sounds and looks super convenient. However when I pasted this two scripts into my poject, I get the following errors:

 ConditionalFieldAttributeDrawer.cs(9,49): error CS1644: Feature `expression bodied members' cannot be used because it is not part of the C# 4.0 language specification
     
 ConditionalFieldAttributeDrawer.cs(11,36): error CS1644: Feature `expression bodied members' cannot be used because it is not part of the C# 4.0 language specification
         
 ConditionalFieldAttributeDrawer.cs(13,33): error CS1644: Feature `expression bodied members' cannot be used because it is not part of the C# 4.0 language specification
         
 ConditionalFieldAttributeDrawer.cs(33,57): error CS1644: Feature `null propagating operator' cannot be used because it is not part of the C# 4.0 language specification

Visual Studio says these are not available in C# 4 and that I should use language version 6 or greater. Any ideas?

avatar image Deadcow_ YD_JMysior · May 19, 2018 at 06:00 PM 0
Share

You need to enable C#6 compatibility in Unity

In the Unity editor, go to Edit->Project Settings->Player Set the "Api Compatibility Level" to .NET 4.6

avatar image rd1349 · Oct 05, 2018 at 11:09 AM 0
Share

Hey sorry to necro but I guess it's in the same spirit hahah. I'm trying to use this, it's really nice but I'm having one problem, I'm trying to get it to hide Enums as well but this code is a bit beyond me. Do you have any idea how that would be done? Thanks in advance

avatar image drorriov · May 25, 2019 at 09:27 PM 0
Share

Would it be possible to do something like:

 public bool InstantiateLevelPrefab;
 [ConditionalField("InstantiateLevelPrefab",true)]
 public int StartFromLevel = 0;
 [ConditionalField("InstantiateLevelPrefab", false)]
 public GameObject PrefabLevelToDebug;

Like if`InstantiateLevelPrefab`is true show option 1 and if it is false to show option 2.

avatar image Deadcow_ drorriov · May 27, 2019 at 06:58 AM 0
Share

Sure :)! This code should work as intended

avatar image drorriov Deadcow_ · May 27, 2019 at 07:09 PM 0
Share

Right, it worked after updating version. thanks.

Show more comments
avatar image
23

Answer by DarthKarki · Jan 11, 2017 at 08:52 PM

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: alt text

Options checked: alt text


inspectorfieldswitheditorscript-hidden.png (6.3 kB)
inspectorfieldswitheditorscript-visible.png (8.6 kB)
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image PavolP · Aug 19, 2020 at 11:31 AM 0
Share

Wow, that was one seriously nice answer.

Not only did I learn thanks to your explanation the basics of creating a custom inspector, but you also made me look up the using keyword

avatar image ProbePLayer PavolP · Aug 29, 2020 at 11:41 AM 0
Share

Yeah this is one of those answers that restores my faith in humanity haha

avatar image
5

Answer by Campusanis · Dec 04, 2015 at 10:47 AM

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()
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
4

Answer by misher · May 07, 2018 at 11:24 AM

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)

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image qua11q7 · May 07, 2018 at 11:33 AM 0
Share

According to the selected enum value, i am changing the logic of the script. Different properties will be used with different enum values. Interface makes sense but sadly doesn't applicable in my case. It is just for ease of use for the user. I will just hide the properties that user won't use.

avatar image misher qua11q7 · May 07, 2018 at 11:50 AM 0
Share

That is exactly what i tryed to explain, different properties/values/behaviour should go to different classes, try to look from OOP and unity's components point of view, in other words: use composition whenever you can

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

27 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

setting the properties in the inspector 1 Answer

Shaders - hiding property in inspector 2 Answers

How can I hide a MonoBehaviour from the Inspector? (or make it extremely thin or compact) 1 Answer

Why do Public Variables overwrite a Scripts Default Value 2 Answers

Public variable not appearing in the inspector (C#) 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges