Michael Francis
Michael Francis

Reputation: 8747

EditorGUILayout.EnumPopup resetting value in custom editor

I have an editor script which is supposed to allow me to change the texture of a tile (I'm making a game board). It works by creating a drop down menu with different "tile types", and then when I select a new tile type from the menu it will change the texture to the appropriate type.

[CustomEditor(typeof(Tile))]
public class TileEditor : Editor {

    enum Type {
        Blank,
        Portal
    }

    // Represents the type of tile this is
    Type type;

    public override void OnInspectorGUI() {
        Tile tile = (Tile)target;

        // Create a dropdown list of tile types
        type = (Type)EditorGUILayout.EnumPopup ("Type", type);

        switch (type) {
        case Type.Blank:
            tile.GetComponent<Renderer> ().material = Resources.Load ("Materials/Blank Tile", typeof(Material)) as Material;
            break;
        case Type.Portal:
            tile.GetComponent<Renderer> ().material = Resources.Load("Materials/Portal Tile", typeof(Material)) as Material;
            break;
        }
    }
}

If I remove the lines where I set the materials, the drop down menu works as expected, but with those lines included, when I select Portal from the drop down it will change the texture for just a moment, and then both the texture and the menu will reset themselves back to the first item in the enum (Blank).

What is going on here, and how do I make my selections persist?

Edit

I've narrowed down the issue slightly. When I select the Portal type it executes the Type.Portal case, but then immediately type changes back to Type.Blank and it executes the Type.Blank case. So it seems something is changing my type variable between calls to OnInspectorGUI().

Upvotes: 1

Views: 3234

Answers (1)

Programmer
Programmer

Reputation: 125325

There are just two problems:

It resets to the first enum right away and when you save the scene and load it, it also resets to the first enum when you select the GameObject Tile script is attached to.

Solution 1:

Make Type type static. Simply change Type type; to static Type type;. This should fix the problem I described above.

But then, you will realize that when you save and re-load your project, the enum is not saved. It resets to index 0 (Type.Blank).

Solution 2:

I hardly work on Editor scripts but to my understanding, the type variable should be declared in the Tile script instead of the TileEditor script. Also, you should re-name that Type enum to something else. Type is part of C# standard API from the System namespace. Re-name it to something like TileType so that you won't confuse yourself in the future.

Declaring it in the Tile script should solve all your problems.

Tile script:

public class Tile : MonoBehaviour
{
    public TileType type;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
}

TileEditor script:

[CustomEditor(typeof(Tile))]
public class TileEditor : Editor
{
    public override void OnInspectorGUI()
    {
        Tile tile = (Tile)target;

        // Create a dropdown list of tile types
        tile.type = (TileType)EditorGUILayout.EnumPopup("TileType", tile.type);

        Debug.Log("OnInspectorGUI");

        switch (tile.type)
        {
            case TileType.Blank:
                tile.GetComponent<Renderer>().material = Resources.Load("Materials/Blank Tile", typeof(Material)) as Material;
                Debug.Log("Blank");
                break;
            case TileType.Portal:
                tile.GetComponent<Renderer>().material = Resources.Load("Materials/Portal Tile", typeof(Material)) as Material;
                Debug.Log("Portal");
                break;
        }
    }
}

public enum TileType
{
    Blank,
    Portal
}

You can also improve this by adding a class that loads the materials once then store them in static variable. This will prevent having to load it each time the dropdown is changed. You can learn more about Custom Inspector here.

Upvotes: 3

Related Questions