C# Unity Editor-C:为什么我的列表会重置为null OnEnable?

C# Unity Editor-C:为什么我的列表会重置为null OnEnable?,c#,list,unity3d,C#,List,Unity3d,我试图创建一个自定义的unity编辑器,由于某种原因,每次我关闭窗口并再次打开它时,我的列表都会重置为null 我试图通过将键和值分离为两个单独的列表OnDisable来保存字典中的数据,然后通过组合这些列表重新创建字典OnEnable。但每次调用OnEnable时,我的列表中都会出现空值 下面是代码的示例 public Dictionary<string, string> myDictionary = new Dictionary<string, string>();

我试图创建一个自定义的unity编辑器,由于某种原因,每次我关闭窗口并再次打开它时,我的列表都会重置为null

我试图通过将键和值分离为两个单独的列表OnDisable来保存字典中的数据,然后通过组合这些列表重新创建字典OnEnable。但每次调用OnEnable时,我的列表中都会出现空值

下面是代码的示例

public Dictionary<string, string> myDictionary = new Dictionary<string, string>();

[SerializeField]
public List<string> listOfDictionaryKeys;


    private void OnEnable()
    {
        // this always returns null
        Debug.Log(listOfDictionaryKeys.Count);

    }

    private void OnDisable()
    {
        // this successfully saves the keys to the list
        listOfDictionaryKeys = (myDictionary.Keys).ToList();

    }

有人知道我为什么会丢失列表数据吗?我没有在检查器中设置任何值,它们都是通过代码设置和保存的。

UnityEdit是一个很棒的工具,它运行自己的回调循环,编辑器中的序列化和反序列化可能有点混乱

有时,unity会忽略对象的构造函数所做的任何事情,并在下次更新时使用默认值覆盖它。我设想,当一个对象的检查器在需要列表的地方发现null时,它会初始化它,但是如果您不将新的序列化表单与场景一起保存,它将保持null,并且在反序列化后bull中发生OnEnable时,它将为null,除非它与场景一起保存

我并没有完全掌握这个过程,但这就是我的想象

要快速解决问题,请执行以下操作:

private void OnEnable()
{
    if (listOfDictionaryKeys==null) listOfDictionaryKeys=new List<string>();
    // this always returns null
    Debug.Log(listOfDictionaryKeys.Count);

}

这样你就不会在它存在的情况下意外地删除它

从你的问题中我真的不明白OnEnable和OnDisable是编辑器脚本的一部分还是组件本身

如果后者:

当组件从禁用状态变为启用状态时,而不是当它在检查器中获得焦点时,将调用OnEnable。当组件或相应的游戏对象被禁用时,调用OnDisabled的方式与此相同,而不是当它失去焦点时

如果您想要的是对inspector中的焦点的获得和丢失做出反应,那么它必须是inspector脚本本身的统一和不可禁用。例如

[CustomEditor(typeof(XY)]
public class XYEditor : Editor
{
    XY _target;
    SerializedProperty list;

    // Called when the class gains focus
    private void OnEnable()
    {
        _target = (XY) target;

        //Link the SerializedProperty
        list = serializedObject.FindProperty("listOfDictionaryKeys");
    }

    public override void OnInpectorGUI()
    {
        //whatever your inspector does
    }

    // Called when the component looses focus
    private void OnDisable()
    {
        serializedObjet.Update();

        // empty list
        list.ClearArray;

        // Reading access to the target's fields is okey 
        // as long as you are sure they are set at the moment the editor is closed
        foreach(var key in _target.myDoctionary.keys)
        {
            list.AddArrayElementAtIndex(list.arraySize);
            var element = list.GetArrayElementAtIndex(list.arraySize - 1);
            element.stringValue = key;
        }

        serialzedObject.ApplyModifiedProperties;
    }
}

我也不知道你在哪里填充字典,因为你说它不会发生在inspector中。当mixonbSerializedProperty可以直接访问字段时,这可能会出现问题。

最好的方法是始终初始化列表,如public List of dictionarykeys=new List;这就是全部代码,因为我看不到在OnEnable中您在何处重新创建列表…@derHugo我在onDisable中填充列表,在OnEnable中,我尝试从列表中获取一个计数,以查看它是否为null,并且它始终返回null。我更改了DictionaryKeys的公开列表;公开静态列表ListOfDictionalKeys=新列表;现在,当我关闭并打开窗口时,列表会正常工作,但是,每当脚本重新编译时,我会再次丢失列表数据。我不明白为什么只在OnDisable?@derHugo中填充它,因为列表只是试图保存我的字典条目的一种方式,OnDisable之后,我的字典会被擦除为null,因此,我试图将字典中的所有数据保存到两个列表中,一个是键列表中的可禁用列表,另一个是值列表,然后将这两个列表中的相同数据重新加载到字典中的可禁用列表中。但是我的名单上的数据也被删除了,我不明白为什么你的问题不是很清楚。我猜会发生什么,但必须确切地了解类的设置和编辑器脚本。另外,如果你能真正了解你是如何以及在什么地方填写这份清单的,这也会有很大帮助。还有,你在哪里填写字典?文章中的代码是编辑器脚本的一部分。通过进入自定义编辑器窗口,在同一脚本中填充词典。我将功能放在了OnEnable和OnDisable中,因为当inspector窗口关闭/打开时,这些是第一个也是最后一个要调用的方法。现在,当我关闭自定义编辑器窗口并重新打开它时,一切正常,当调用OnDisable时,字典被复制到两个列表中,然后这两个列表在OnEnable中重新填充字典。但是当我的编辑器脚本重新编译时,我再次丢失数据并得到空列表