【问题标题】:EditorGUILayout.EnumPopup resetting value in custom editorEditorGUILayout.EnumPopup 在自定义编辑器中重置值
【发布时间】:2017-01-04 12:27:38
【问题描述】:

我有一个编辑器脚本,它应该允许我更改瓷砖的纹理(我正在制作一个游戏板)。它的工作原理是创建一个具有不同“瓷砖类型”的下拉菜单,然后当我从菜单中选择新的瓷砖类型时,它会将纹理更改为适当的类型。

[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;
        }
    }
}

如果我删除了设置材质的行,下拉菜单会按预期工作,但是包含这些行时,当我从下拉菜单中选择 Portal 时,它会暂时更改纹理,然后纹理和菜单将自己重置回枚举中的第一项(空白)。

这里发生了什么,如何让我的选择持续存在?

编辑

我已经稍微缩小了范围。当我选择 Portal 类型时,它执行 Type.Portal 案例,但随后 type 立即变回 Type.Blank 并执行 Type.Blank 案例。因此,在对OnInspectorGUI() 的调用之间,似乎有些东西正在改变我的type 变量。

【问题讨论】:

  • 为什么不发布您的 Tile 脚本?
  • @Programmer 目前是空白的。只是一个空班。
  • 好的,你的“Portal Tile”放在什么目录下?
  • @Programmer Resources/Materials。纹理正确加载,并在图块上显示片刻,然后恢复。
  • 有趣。只是想确保 Resources.Load 不为空。我能够复制这个问题。有点奇怪。这看起来像一个错误.....

标签: c# unity3d


【解决方案1】:

只有两个问题:

它会立即重置为第一个枚举,当您保存场景并加载它时,它也会在您选择附加的 GameObject Tile 脚本时重置为第一个枚举。

解决方案 1

Type type 设为静态。只需将Type type; 更改为static Type type;。 这应该可以解决我上面描述的问题。

但是,你会意识到,当你保存并重新加载你的项目时,枚举并没有被保存。它重置为索引 0 (Type.Blank)。

解决方案 2

我几乎不处理编辑器脚本,但据我了解,type 变量应该在Tile 脚本中声明,而不是在TileEditor 脚本中。此外,您应该将该 Type enum 重命名为其他名称。 Type 是来自 System 命名空间的 C# 标准 API 的一部分。将其重命名为 TileType 之类的名称,这样您以后就不会混淆了。

Tile 脚本中声明它应该可以解决您的所有问题。

平铺脚本:

public class Tile : MonoBehaviour
{
    public TileType type;

    // Use this for initialization
    void Start()
    {

    }

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

    }
}

TileEditor脚本:

[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
}

您还可以通过添加一个加载材料一次然后将它们存储在静态变量中的类来改进这一点。这将避免每次更改下拉列表时都必须加载它。您可以了解更多关于 Custom Inspector here.

【讨论】:

  • 天哪。我怎么会错过呢?我将平铺类型存储在编辑器中而不是平铺中。那是我的愚蠢。但如果没有你的帮助,我想我不会弄明白的,非常感谢。
  • 如果您之前没有制作过自定义检查器,这并不愚蠢。我认为这是我看到this 后验证的问题。不客气,编码愉快!
猜你喜欢
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多