Reputation: 8747
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
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