How can I make one condition visible in the inspector window if another is true and hidden if false? For example, if isLightON = true
then isLightBright
should be visible else if isLightON = false
then isLightBright
should be hidden. I know this is suppose to be done using editor coding but not sure exactly how it is to be done.
-
\$\begingroup\$ After a 10 seconds Google search: link1, link2, link3, link4 (should I continue?) \$\endgroup\$– HelliumCommented Apr 4, 2018 at 14:52
-
\$\begingroup\$ @Hellium no, but maybe try not to be a jerk. Posting the links is fine, but treating new members poorly is just very, very poor form. \$\endgroup\$– 3DaveCommented Apr 4, 2018 at 22:59
1 Answer
The links Hellium shared seem to all go about this by defining a custom editor to draw the whole inspector view for the object. This certainly works, but it can get a bit laborious for more complicated components. If you want to use these hidden attributes on a bunch of different types, then you end up re-writing and maintaining a lot of boilerplate.
I wanted to find something I could just slap on when I wanted something hidden. Something like...
public bool isLightOn = false;
[ConditionalProperty("isLightOn")]
public float brightness;
The idea is we'll pass to ConditionalPropertyAttribute
the name of the bool that should control this property's visibility, then use that to decide whether to draw the control. (If you wanted to get really fancy, we could extend this to support expressions, like "myIntValue > 5" or "valueA != valueB")
Here I've defined a custom property attribute to mark the sometimes-drawn fields and store the criteria we'll use to decide whether to draw them:
public class ConditionalPropertyAttribute : PropertyAttribute {
public string condition;
public ConditionalPropertyAttribute(string condition) {
this.condition = condition;
}
}
And then, in an Editor\
folder, created a custom property drawer to control how fields with this attribute are dawn (or not):
using UnityEditor;
[CustomPropertyDrawer(typeof(ConditionalPropertyAttribute))]
public class ConditionalPropertyDrawer : PropertyDrawer {
// Determine whether this field should be visible.
// (We could probably do some caching here...)
bool ShouldShow(SerializedProperty property) {
var conditionAttribute = (ConditionalPropertyAttribute)attribute;
string conditionPath = conditionAttribute.condition;
// If this property is defined inside a nested type
// (like a struct inside a MonoBehaviour), look for
// our condition field inside the same nested instance.
string thisPropertyPath = property.propertyPath;
int last = thisPropertyPath.LastIndexOf('.');
if (last > 0) {
string containerPath = thisPropertyPath.Substring(0, last + 1);
conditionPath = containerPath + conditionPath;
}
// Get the SerializedProperty representing the field that is our criterion.
var conditionProperty = property.serializedObject.FindProperty(conditionPath);
// For now, we'll only support bool criteria, and default to visible if there's a problem.
if (conditionProperty == null || conditionProperty.type != "bool")
return true;
// Use the condition property's boolean value to drive visibility.
return conditionProperty.boolValue;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
if(ShouldShow(property))
EditorGUI.PropertyField(position, property, label, true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
if (ShouldShow(property)) {
// Provision the normal vertical spacing for this control.
return EditorGUI.GetPropertyHeight(property, label, true);
} else {
// Collapse the unseen derived property.
return -EditorGUIUtility.standardVerticalSpacing;
}
}
}
What I like about this approach is I only need to write the above attribute & drawer once, and they work for any number of hidden fields in any number of types, and the fields I'm hiding can be of any type the Inspector knows how to draw, including elements of arrays. So the maintenance for adding/changing scripts is much lower than writing custom editors for every type that wants to hide some things.
-
\$\begingroup\$ could you please take a look at this question gamedev.stackexchange.com/questions/157213/… \$\endgroup\$ Commented Apr 11, 2018 at 7:30
-
\$\begingroup\$ I think my question is kinda related gamedev.stackexchange.com/questions/158710/… \$\endgroup\$– BaneCommented May 16, 2018 at 12:02