Unity Editor - C #: почему мой список сбрасывается в ноль OnEnable? - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь создать собственный редактор единиц и по какой-то причине каждый раз, когда я закрываю окно и открываю его снова, мой список сбрасывается в ноль.

Я пытаюсь сохранить данные из словаряпутем разделения ключей и значений на 2 отдельных списка 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();

    }

У кого-нибудь есть идеи, почему яможет потерять данные моего списка?Я не устанавливаю никаких значений в инспекторе, они все устанавливаются и сохраняются с помощью кода.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Я не совсем понимаю из вашего вопроса, являются ли OnEnable и OnDisable частью вашего сценария редактора или самого компонента.

Если позже:

OnEnableвызывается, когда компонент переходит из отключенного состояния в включенное, , а не , когда он получает фокус в инспекторе.Точно так же OnDisabled вызывается, когда компонент или соответствующий GameObject отключен, не , если он теряет фокус.

Если то, что вы хотите, реагирует на получение и потерю фокуса в инспекторе, егодолжно быть OnEnable и OnDisable самого сценария 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;
    }
}

Я также не вижу, где вы заполняете словарь, поскольку вы говорите, что это не происходит в инспекторе.Это может быть проблемой, когда mixonb SerializedProperty имеет прямой доступ к полям.

0 голосов
/ 04 февраля 2019

UnityEditor - хитрый зверь (отличный инструмент), который запускает свой собственный цикл обратного вызова, а сериализация и десериализация в редакторе может быть немного грязной.

Иногда Unity будет игнорировать любой конструктор объекта и заменять его значениями по умолчанию при следующем обновлении.Я предполагаю, что инспектор объекта инициализирует его, когда он находит ноль, где ожидается список, но если вы не сохраните новую сериализованную форму со своей сценой, она останется нулевой и будет нулевой, когда OnEnable произойдет в булле(после десериализации), если только он не сохранен вместе со сценой.

У меня нет полного понимания процесса, но я так его себе представляю.

Для быстрого обхода выполните:

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

}

, так что вы не сможете случайно стереть его, если он существует

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...