Вопрос по Editor Window

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Вопрос по Editor Window

Сообщение bwolf88 12 сен 2014, 16:46

Всем снова доброго времени суток.
Такой вопрос:
Создал сериализуемый класс с кучей параметров, в инспекторе все эти параметры прекрасно отображатся. Как этот же набор параметров без перебора каждого элемента отобразить в созданном EditorWindow ? Какую переменную использовать ? Пробовал EditorGUILayout.PropertyField, но чего то он ругается.

Вот пример элемента из массива этого типа, но мне нужно отобразить не массив, а только один экземпляр класса со всеми переменными простым способом.
Изображение
Прошу помощи у знатоков :).
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Вопрос по Editor Window

Сообщение Neyl 12 сен 2014, 17:39

Именно PropertyField и надо использовать, как ругается? Возможно SerializedProperty для него неверно получаете?
Аватара пользователя
Neyl
UNIверсал
 
Сообщения: 404
Зарегистрирован: 20 июн 2010, 10:17

Re: Вопрос по Editor Window

Сообщение bwolf88 12 сен 2014, 17:47

Neyl писал(а):Именно PropertyField и надо использовать, как ругается? Возможно SerializedProperty для него неверно получаете?


А что есть SerializedProperty ? Как его получить ? То что в инспекторе отображается - это через DrawDefaultInspector(). А как вручную подобные классы показывать я так и не понял .
Сейчас смотрел в справке, чет нифига не понял как получить сериализованные переменные :-\.
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Вопрос по Editor Window

Сообщение GameWorld 12 сен 2014, 18:14

Последний раз редактировалось GameWorld 12 сен 2014, 18:27, всего редактировалось 1 раз.
«Улучшение работающего продукта - приводит к его ухудшению.»
Аватара пользователя
GameWorld
Старожил
 
Сообщения: 620
Зарегистрирован: 11 янв 2011, 03:02
Skype: Alien3DModeller

Re: Вопрос по Editor Window

Сообщение Neyl 12 сен 2014, 18:18

В справке смотрите SerializedObject и SerializedProperty.
SerializedObject это объект который получает доступ к сериализованным(сохраненным в сцену или в ассет в проекте) свойствам(полям) объекта (или нескольких), который вы редактируете. Если вы пишете кастомный инспектор (наследуетесь от Еditor), то serializedObject у вас уже есть http://docs.unity3d.com/ScriptReference ... bject.html
Для EditorWindow нужно будет его создать через конструктор.
Дальше нужно по имени получить SerializedProperty через SerializedObject.FindProperty и отобразить её через EditorGUILayout.PropertyField
Синтаксис:
Используется csharp
        serializedObject.Update(); //обновить значения
        EditorGUI.BeginChangeCheck();

        EditorGUILayout.PropertyField(serializedObject.FindProperty("title"));
        EditorGUILayout.PropertyField(serializedObject.FindProperty("color"));
        EditorGUILayout.PropertyField(serializedObject.FindProperty("myClass), true);//для своих классов или массивов использовать такой вариант для автоматического отображения дочерних свойств

        if (EditorGUI.EndChangeCheck())
        {
        serializedObject.ApplyModifiedProperties();//применить измененные значения обратно к объекту
        }


Имя SerializedProperty можно увидеть, если в инспекторе с зажатым шифтом сделать правый клик по свойству и выбрать в меню "Print Property Path"

Для DrawDefaultInspector используется такая конструкция, которая автоматически перебирает все имеющиеся свойства
Синтаксис:
Используется csharp
            serializedObject.Update(); //обновить значения
            EditorGUI.BeginChangeCheck();
            SerializedProperty iterator = serializedObject.GetIterator();
            while(iterator.NextVisible(true))
            {
                EditorGUILayout.PropertyField(iterator, true);
            }
            if (EditorGUI.EndChangeCheck())
            {
                 serializedObject.ApplyModifiedProperties();
            }
Аватара пользователя
Neyl
UNIверсал
 
Сообщения: 404
Зарегистрирован: 20 июн 2010, 10:17

Re: Вопрос по Editor Window

Сообщение bwolf88 12 сен 2014, 18:35

В целом понял (буду по автоматному способу отображать), но не понял как создать этот самый сериализуемый объект.
У меня есть сериализованный класс Nodes. Его тип - Nodes, как его привести к Object если это просто переменная, а не объект (я создаю его не через ScriptableObject и на сцене его нет) ?

Вот конструктор "SerializedObject(Object obj);" Он требует тип object. Как сделать приведение, ведь это совершенно разные типы. :-o
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Вопрос по Editor Window

Сообщение Neyl 12 сен 2014, 19:08

Этот класс ведь пренадлежит какому либо окну? Значит SerializedObject для него это EditorWindow (которое наследовано от ScriptableObject).
Можно сделать так, будет работать, хоть так никто и не делает
Синтаксис:
Используется csharp
[Serializable]
public class Node
{
      public string name;
      public Vector3 position;
      public int hash;
}
public class TestWindow : EditorWindow
    {
        public Node[] nodes;

private void OnGUI()
        {
            SerializedObject so = new SerializedObject(this);//лучше сделать это в OnEnable
            so.Update();
            EditorGUILayout.PropertyField(so.FindProperty("nodes"), true);
            so.ApplyModifiedProperties();
        }
}
 
Аватара пользователя
Neyl
UNIверсал
 
Сообщения: 404
Зарегистрирован: 20 июн 2010, 10:17

Re: Вопрос по Editor Window

Сообщение bwolf88 12 сен 2014, 19:30

Не работает, ругается вот на эту строчку. Пишет NullReferenceException.

EditorGUILayout.PropertyField(serializedObj.FindProperty("SelectedNode"), true);
Я так понимаю, потому что EditorWindow - это не объект.

Делаю примерно так в скрипте :EditorWindow(чтобы весь код не переписывать)
Синтаксис:
Используется csharp
public Nodes SelectedNode; //это экземпляр класса
public SerializedObject serializedObj; //это экземпляр сериализуемого объекта
//дальше нажимаю GUI кнопку идет выполнение функции в которой присваиваются значения

void функция_по_кнопке()
{
...
SelectedNode = AG3D.nodes [grNode]; //выбирается нужный экземпляр из массива
serializedObj = new SerializedObject (this); //инициализируем
serializedObj.Update ();
}
//далее по условию в OnGUI должны показать чего у нас там получилось и ничего не показывается потому что объекта не существует
if (selectedObject != null)
{
     EditorGUILayout.PropertyField(serializedObj.FindProperty("SelectedNode"), true); //вот здесь получаем ошибку
      serializedObj.ApplyModifiedProperties();
}
 
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331

Re: Вопрос по Editor Window

Сообщение Neyl 12 сен 2014, 20:09

bwolf88 писал(а):И я не совсем понял, что значит класс принадлежит окну ?

Имел ввиду что экземпляр Serializable класса Nodes в поле SelectedNode принадлежит классу унаследованому от EditorWindow, которое в свою очередь унаследовано от UnityEngine.Object, а значит должно сериализовывать свои публичные поля.

Можно попробовать прикрутить костыль
Синтаксис:
Используется csharp
SelectedNode = AG3D.nodes [grNode]; //выбирается нужный экземпляр из массива
EditorUtility.SetDirty(this);//костыль
serializedObj = new SerializedObject (this); //инициализируем


Что такое AG3D? Не MonoBehaviour ?
Тогда именно он должен быть источником для SerializedObject
Синтаксис:
Используется csharp
void функция_по_кнопке()
{
...
//SelectedNode = AG3D.nodes [grNode]; //не нужно
serializedObj = new SerializedObject (AG3D); //инициализируем
}
//далее по условию в OnGUI должны показать чего у нас там получилось и ничего не показывается потому что объекта не существует
if (selectedObject != null)
{
     serializedObj.Update ();//лучше это делать перед началом отрисовки свойств
     EditorGUILayout.PropertyField(serializedObj.FindProperty("nodes").GetArrayElementAtIndex(grNode) , true); //получаем непосредственно элемент массива
     serializedObj.ApplyModifiedProperties();
}
Аватара пользователя
Neyl
UNIверсал
 
Сообщения: 404
Зарегистрирован: 20 июн 2010, 10:17

Re: Вопрос по Editor Window

Сообщение bwolf88 12 сен 2014, 21:40

Все, заработало!
Пример с костылем тоже не пошел, он снова ругался на несуществующий объект, а второй пример заработал (чуть изменил правда). Вот это жесть, как все запутанно и сложно, но зато какая куча опыта. Теперь хотя бы понятно как создается этот сериализуемый объект и как посмотреть нестандартный набор свойств.

Очень благодарствую за терпение :).
Сюда периодически чего нибудь выкладываю https://github.com/LuchunPen
Аватара пользователя
bwolf88
Адепт
 
Сообщения: 2184
Зарегистрирован: 30 апр 2014, 06:40
Skype: bwolf331


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 27