Hello everyone.
I’m quite new to the Custom Editor script and I’m looking for a quick help.
I want to hide some variables using an Enum. And so far I managed to do so.
Problem is, when the variables are inside another class.
To show this, I made those two scripts, the main script and the Editor script:
Inspector image:
JustExample.cs (main script):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class JustExample : MonoBehaviour
{
public enum Selector
{
Green,
Red
}
public Selector selector;
[HideInInspector]
public bool iCanHideThisIfRed;
public Data[] data;
}
[System.Serializable]
public class Data
{
public string text;
public int Green; //need to hide/show this
public int Red; //need to hide/show this
}
The JustExampleEditor.cs (Editor class):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(JustExample))]
public class JustExampleEditor : Editor
{
public override void OnInspectorGUI()
{
JustExample justExample = (JustExample)target;
EditorGUILayout.PropertyField(serializedObject.FindProperty("selector"));
if (justExample.selector == JustExample.Selector.Red)
{
//I want to access the variables inside "data" here, to hide one field
}
else if (justExample.selector == JustExample.Selector.Green)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("iCanHideThisIfRed"));
//I want to access the variables inside "data" here, to hide one field
}
EditorGUILayout.PropertyField(serializedObject.FindProperty("data"));
serializedObject.ApplyModifiedProperties();
//base.OnInspectorGUI();
}
}
The main problem in your case is not with access to fields in another class; the main problem is that the instances of those classes are inside an array. Controlling the drawing of a nested field is relatively easy. The thing is that you want the things that Unity draws around arrays, so we can’t just draw each field from the array manually; we need to let Unity control the drawing of that particular array.
What we can do is create a PropertyDrawer for the Data class. It will let Unity control the drawing of the whole array, but it will let us take control of the drawing of each element drawn inside that array. We’ll need a way to communicate between the Custom Editor and the Property Drawer; we’ll use a static variable for that. Here’s an idea of how the Property drawer would look like:
[CustomPropertyDrawer(typeof(DataDrawer))]
public class DataDrawer : PropertyDrawer
{
// This static field should be set before any DataDrawer is used.
public static JustExample.Selector currentSelector;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// We can't use GUILayout in propery drawers; we need to calculate each field's position.
// The position we received should contain all the fields in our class; it uses the height
// returned by GetPropertyHeight. We'll use it to calculate the position of each field.
var textFieldPosition = position;
textFieldPosition.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(position, property.FindPropertyRelative("text"));
var specialFieldPosition = position;
specialFieldPosition.height = EditorGUIUtility.singleLineHeight;
// The next position is moved in y after the previous one, plus some spacing.
specialFieldPosition.y = textFieldPosition.yMax + EditorGUIUtility.standardVerticalSpacing;
if (currentSelector == JustExample.Selector.Green)
{
EditorGUI.PropertyField(specialFieldPosition, property.FindPropertyRelative("Green"));
}
else if (currentSelector == JustExample.Selector.Red)
{
EditorGUI.PropertyField(specialFieldPosition, property.FindPropertyRelative("Red"));
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
// Here you should return the height needed for the fields displayed for the current mode.
// In this example, we always use two lines for two fields plus a space between them.
return (EditorGUIUtility.singleLineHeight * 2) + EditorGUIUtility.standardVerticalSpacing;
}
}
And here’s how the Custom Editor would communicate with it by setting its static field before drawing the array:
[CustomEditor(typeof(JustExample))]
public class JustExampleEditor : Editor
{
public override void OnInspectorGUI()
{
JustExample justExample = (JustExample)target;
EditorGUILayout.PropertyField(serializedObject.FindProperty("selector"));
if (justExample.selector == JustExample.Selector.Green)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("iCanHideThisIfRed"));
}
// We set the currentSelector field so all the data drawers that will be used when
// drawing the PropertyField for "data" know which fields should be hidden.
DataDrawer.currentSelector = justExample.selector;
EditorGUILayout.PropertyField(serializedObject.FindProperty("data"));
serializedObject.ApplyModifiedProperties();
}
}