Be the first to post for 'Writing Custom Editors'!

If you’re reading this, there probably aren’t very many posts yet. But don’t worry, you can be the first! Either create a new post or just reply to this one to say ‘hi’.

Wouldn’t the ideal solution here to have drag and drop layers like the default Unity Layers interface?

Hypothetically, mid-development you receive feedback that the priorities are causing issues with players and you need to tweak the order or add a layer(s) to fine tune it. To change one layer could require manually changing several other layers, greatly increasing the chance of error.

I don’t know if there’s a way to ignore the first X number of items in an array (e.g. 1 - 7 default layers) but if there is, wouldn’t that be the way to go instead of reinventing the wheel with a custom editor interface?

We’ll keep iterating this until we get a great solution, it’s worth people being dragged through the mud a little to see the process of critiquing solutions, and converging on a great one.

I agree! Knowing why you don’t do it one way can be just as important as knowing why you should do it another way.

1 Like

I have to say, this one got me mentally turned around. Custom editor scripting seems super useful though, so I’m going to try to look into it more after I’m done with the course.

EDIT: Aaaaaand this is directly addressed in the next video. Haha. Whoops.

1 Like

Hi,

First of all, nice video about editors!

I have one question though. How can you make sure that the stringToPrint starts with the default value that you defined as: “new string”? In the video it starts with an empty value :slight_smile:

Thanks, Willem

Hi,

I know this is a bit late(as the last reply here was in August) but would it not be a good idea to use “DrawDefaultInspector();” in the Editor Scripts and only manually paint the inspector fields you need by using the “[HideInInspector]” Tag before the declaration.
That way you can have Unity painting everything that looks good already and you only need to repaint the fields you choose with the Tag.

Greetings from Austria and i have to say, i love the course soo far!

I just want to add a bit to this. I parameterised the two methods used in the script for more generic layer arrays, as I was using an extra list of layers as part of my process to fade intervening objects. So my OnInspectorGUI is now like this:

public override void OnInspectorGUI()
{
    serializedObject.Update(); // Serialize cameraRaycaster instance

    isLayerPrioritiesUnfolded = EditorGUILayout.Foldout(isLayerPrioritiesUnfolded, "Layer Priorities");
    if (isLayerPrioritiesUnfolded)
    {
        EditorGUI.indentLevel++;
        {
            BindArraySize("layerPriorities");
            BindArrayElements("layerPriorities", "Layer");
        }
        EditorGUI.indentLevel--;
    }

    isUnFadableLayersUnfolded = EditorGUILayout.Foldout(isUnFadableLayersUnfolded, "Unfadable Layers");
    if (isUnFadableLayersUnfolded)
    {
        EditorGUI.indentLevel++;
        {
            BindArraySize("unFadableLayers");
            BindArrayElements("unFadableLayers", "Layer");
        }
        EditorGUI.indentLevel--;
    }

    serializedObject.ApplyModifiedProperties(); // De-serialize back to cameraRaycaster (and create undo point)
}

and the two methods…:

void BindArraySize(string fieldName)
{
    int currentArraySize = serializedObject.FindProperty(fieldName + ".Array.size").intValue;
    int requiredArraySize = EditorGUILayout.IntField("Size", currentArraySize);
    if (requiredArraySize != currentArraySize)
    {
        serializedObject.FindProperty(fieldName + ".Array.size").intValue = requiredArraySize;
    }
}

void BindArrayElements(string fieldName, string subFieldName)
{
    int currentArraySize = serializedObject.FindProperty(fieldName + ".Array.size").intValue;
    for (int i = 0; i < currentArraySize; i++)
    {
        var prop = serializedObject.FindProperty(string.Format(fieldName + ".Array.data[{0}]", i));
        prop.intValue = EditorGUILayout.LayerField(string.Format(subFieldName + " {0}:", i), prop.intValue);
    }
}

However, I still have an enum in the Utility script - used for something completely different to layers. But I can’t help thinking that there must be a better way to store definitions like this that are to be used in multiple scripts…
For my case I introduced the concept of enemies moving in formation - with a formation gameobject, containing positions - which spawned enemies at each position at the start. But the formation is using an ‘Orders’ enum to issue orders to the individual enemies within that formation to control their behaviour.
So… is there a better way than having an enum in the utility script to control the valid orders? Is this something that the aforementioned ‘property drawers’ could handle?

Ta.

You are actually not saving the value with the code you have at the end of the video, if you click away from the gameobject and back, the value is gone.

You forget a couple of lines of code to save it back into the serialized object. Something like this.

if(currentString != requiredString)
    {
        serializedObject.FindProperty("stringToPrint").stringValue = requiredString;
        
    }

Wanted to say thank you for teaching this. I felt it was really straightforward. While I’m aware of the new content, I appreciate this kind of detail only because editor inspector workflow is very powerful but at the start can be very intimidating given how specific to Unity the whole setup is. There’s plenty of docs but it’s easy to get lost on all the info. This makes things much clearer. Thank you!

Privacy & Terms