Коллекция Property Drawers

Раздел, посвящённый всему, что связано с программированием для Редактора Юнити. Скрипты Редактора, Wizards и прочее.

Коллекция Property Drawers

Сообщение Unitmen 25 фев 2014, 22:01

Предыстория: Во время разработки классов для использования в команде часто требуется делать для них интерфейс удобный для не программистов.
У меня таких классов вагон и маленькая тележка, без нормального инструментария привести их в божеский вид - сложная задачка. Короче теперь инструментарий есть Property Drawers, но на его разработку тоже тратится время.
Предлагаю делится своими Property Drawers.
Но для начала небольшой туториал на русском по их созданию (в отличии от известного тутора Property Drawers in Unity 4 - этот проще для понимания, так как основан на простейшем примере)

В виду того, что движок форума упорно заменяет открывающие скобки на заменяющие символы и весь код просто становится ничетаемым урок переехал на github, собственно и все примеры туда оформлю как будет время.

Далее предлагаю постить в эту тему свои Property Drawers.
Желательно оформлять по единому шаблону, например вот так:


Property Drawers HelpAttribute

help_demo.png

Example: test.cs
Синтаксис:
Используется csharp
using UnityEngine;

public class test : MonoBehaviour {
        [HelpAttribute("Анимация открытия дверей")]
        public Animator OpenDor;
}


Attribute: HelpAttribute.cs
Синтаксис:
Используется csharp
using UnityEngine;

public class HelpAttribute : PropertyAttribute
{
        public string HelpMessageText;
        public HelpAttribute(string text)
        {
                this.HelpMessageText = text;
        }
}


Drawer HelpDrawer.cs
Синтаксис:
Используется csharp
using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(HelpAttribute))]
public class HelpDrawer : PropertyDrawer {

        private int helpHeight = 50, textHeight = 16, HeaderY = 2;
       
        HelpAttribute helpAttribute
        {
                get
                {
                        return (HelpAttribute) attribute;
                }
        }

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){
                if(!string.IsNullOrEmpty(helpAttribute.HelpMessageText))
                {
                        position.height = textHeight;

                        EditorGUI.PropertyField(position,property,label);

                        position.y += textHeight + HeaderY;
                        position.height = helpHeight;

                        EditorGUI.HelpBox(position , helpAttribute.HelpMessageText, MessageType.Info); 
                }
                else
                {
                        EditorGUI.PropertyField(position,property,label);
                }
        }
       
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
                return base.GetPropertyHeight(property, label) + helpHeight + (string.IsNullOrEmpty(helpAttribute.HelpMessageText) ? 0 : textHeight);
        }
}
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось Unitmen 12 апр 2016, 15:39, всего редактировалось 2 раз(а).
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

Re: Коллекция Property Drawers

Сообщение Unitmen 26 фев 2014, 13:45

Админам: Резервирую.

Property Drawers: PopupAttribute

Примечание: Основная реализация PopupDrawer.cs не моя, я только устранил несколько ошибок и немного причесал.
Взято с японского форума, адрес уже потерялся, надеюсь автор не будет против.


Примечание 2: Следите за соответствием типов при использовании PopupAttribute. То-есть, если у вас тип переменной float, не стоит подставлять ей строку.

popup_demo.png


Example: PopupExample.cs
Синтаксис:
Используется csharp
using UnityEngine;

public class PopupExample : MonoBehaviour
{
    [Popup("Spot","Directional","Point","Area")]
    public string LightType;
    [Popup(2,4,16,256,65536)]
    public int Integer;
    [Popup(0.5f,1.0f,1.5f,2.0f,2.5f,3.0f)]
    public float Float;
        [PopupAttribute ("red", "blue", "gray")]
        public string Color;
}

Attribute: PopupAttribute.cs
Синтаксис:
Используется csharp
using UnityEngine;

/// <summary>
/// Popup attribute - позволяют создать выпадающие списки предопределенных значений.
/// </summary>
public class PopupAttribute : PropertyAttribute
{
        /// <summary>
        /// list - массив предопределенных значений.
        /// </summary>
        public object[] ValuesArray;
   
        /// <summary>
        /// Инициализирует новый экземпляр класса <see cref="PopupAttribute"/>.
        /// </summary>
        /// <param name="list">Массив предопределенных значений.</param>
    public PopupAttribute (params object[] list)
    {
                this.ValuesArray = list;
    }
}


Drawer: PopupDrawer.cs
Синтаксис:
Используется csharp
using UnityEngine;
using UnityEditor;
using System;

[CustomPropertyDrawer(typeof(PopupAttribute))]
public class PopupDrawer : PropertyDrawer
{
       
        private Action<int> setValue;
        private Func<int, int> validateValue;
        private string[] _list = null;
       
        private string[] list
        {
                get
                {
                        if (_list == null)
                        {
                                _list = new string[popupAttribute.ValuesArray.Length];
                                for (int i = 0; i < popupAttribute.ValuesArray.Length; i++)
                                {
                                        _list[i] = popupAttribute.ValuesArray[i].ToString();
                                }
                        }
                        return _list;
                }
        }
       
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
                if (validateValue == null && setValue == null)
                        SetUp(property);
               
               
                if (validateValue == null && setValue == null)
                {
                        base.OnGUI(position, property, label);
                        return;
                }
               
                int selectedIndex = 0;
               
                for (int i = 0; i < list.Length; i++)
                {
                        selectedIndex = validateValue(i);
                        if (selectedIndex != 0)
                                break;
                }
               
                EditorGUI.BeginChangeCheck();
                selectedIndex = EditorGUI.Popup(position, label.text, selectedIndex, list);
                if (EditorGUI.EndChangeCheck())
                {
                        setValue(selectedIndex);
                }
        }
       
        void SetUp(SerializedProperty property)
        {
                if (variableType == typeof(string))
                {
                       
                        validateValue = (index) =>
                        {
                                return property.stringValue == list[index] ? index : 0;
                        };
                       
                        setValue = (index) =>
                        {
                                property.stringValue = list[index];
                        };
                }
                else if (variableType == typeof(int))
                {
                       
                        validateValue = (index) =>
                        {
                                return property.intValue == Convert.ToInt32(list[index]) ? index : 0;
                        };
                       
                        setValue = (index) =>
                        {
                                property.intValue = Convert.ToInt32(list[index]);
                        };
                }
                else if (variableType == typeof(float))
                {
                        validateValue = (index) =>
                        {
                                return property.floatValue == Convert.ToSingle(list[index]) ? index : 0;
                        };
                        setValue = (index) =>
                        {
                                property.floatValue = Convert.ToSingle(list[index]);
                        };
                }
               
        }
       
        PopupAttribute popupAttribute
        {
                get { return (PopupAttribute)attribute; }
        }
       
        private Type variableType
        {
                get
                {
                        return popupAttribute.ValuesArray[0].GetType();
                }
        }
}
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось Unitmen 27 фев 2014, 15:14, всего редактировалось 2 раз(а).
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

Re: Коллекция Property Drawers

Сообщение Unitmen 26 фев 2014, 14:14

Резервирую.

Property Drawers: TooltipAttribute

tooltip_demo.png


Example: TooltipExample.cs
Синтаксис:
Используется csharp
using UnityEngine;

public class TooltipExample : MonoBehaviour
{
        [TooltipAttribute("Всплывающая подсказка по WheelCollider")]
    public WheelCollider wheelCollider;
}


Attribute: TooltipAttribute.cs
Синтаксис:
Используется csharp
using UnityEngine;

/// <summary>
/// Tooltip attribute - Атрибут позволяет Выводить всплывающую подсказку при наведении мышки на контрол.
/// </summary>
public class TooltipAttribute : PropertyAttribute
{
        /// <summary>
        /// Значение типа строка для всплывающей подсказки.
        /// </summary>
    public string Tooltip;
        /// <summary>
        /// Создание экземпляра класса <see cref="TooltipAttribute"/>.
        /// </summary>
        /// <param name="tooltip">Значение типа строка для всплывающей подсказки.</param>
    public TooltipAttribute(string tooltip)
    {
        this.Tooltip = tooltip;
    }
}


Drawer: TooltipDrawer.cs
Синтаксис:
Используется csharp
using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(TooltipAttribute))]
public class TooltipDrawer : PropertyDrawer
{
    TooltipAttribute tooltipAttribute
    {
        get
        {
            return (TooltipAttribute) attribute;
        }
    }
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        if (!string.IsNullOrEmpty(tooltipAttribute.Tooltip))
        {
            label.tooltip = tooltipAttribute.Tooltip;
        }
        EditorGUI.PropertyField(position, property, label);
    }
}
У вас нет доступа для просмотра вложений в этом сообщении.
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

Re: Коллекция Property Drawers

Сообщение Strannik 26 фев 2014, 15:32

свои еще не писал, но когда ознакамливался, наткнулся на эту коллекцию Property Drawers:
https://github.com/anchan828/property-drawer-collection
Strannik
UNIт
 
Сообщения: 93
Зарегистрирован: 26 апр 2012, 22:30
Откуда: Омск

Re: Коллекция Property Drawers

Сообщение Unitmen 26 фев 2014, 16:07

Strannik писал(а):свои еще не писал, но когда ознакамливался, наткнулся на эту коллекцию Property Drawers:
https://github.com/anchan828/property-drawer-collection

Посмотрел, в принципе часть из них у меня уже есть, только в нормальном виде. Как набор заготовок для создания собственный Property Drawers - самое оно. Кстати изначальный PopupAttribute похоже именно из этого сборника.
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

Re: Коллекция Property Drawers

Сообщение KingPeas 27 мар 2014, 13:02

Unitmen писал(а):Drawer: TooltipDrawer.cs


При использовании для поля типа Vector3 или Vector2 проблема с высотой поля. При узком окне инспектора для Vector свойство выводится в две строки, а Drawer отрисовывает высотой в одну строку. Как не пытался так и не смог сие победить.
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ...
Мой первый плагин PropertyDrawerCollection
Аватара пользователя
KingPeas
UNIт
 
Сообщения: 78
Зарегистрирован: 12 сен 2012, 12:34
Откуда: Новосибирск
Skype: evgeniygurlev
  • Сайт
  • ICQ

Re: Коллекция Property Drawers

Сообщение Nicloay 27 мар 2014, 14:13

вот вам коллекция built in аттрибутов. такие вещи как popup - там уже есть.
https://docs.unity3d.com/Documentation/ ... =Attribute
If you wish to make an apple pie from scratch, you must first invent the universe.(Carl Sagan, Cosmos)
| My Asset Store | coloring book | github | _wiki.unity3d.com | twitter | linkedin |
Аватара пользователя
Nicloay
Адепт
 
Сообщения: 1288
Зарегистрирован: 31 май 2012, 09:27
Откуда: Альпс
  • Сайт

Re: Коллекция Property Drawers

Сообщение KingPeas 28 мар 2014, 06:01

Nicloay писал(а):вот вам коллекция built in аттрибутов. такие вещи как popup - там уже есть.
https://docs.unity3d.com/Documentation/ ... =Attribute

Что-то не по глазам, а где там popup?
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ...
Мой первый плагин PropertyDrawerCollection
Аватара пользователя
KingPeas
UNIт
 
Сообщения: 78
Зарегистрирован: 12 сен 2012, 12:34
Откуда: Новосибирск
Skype: evgeniygurlev
  • Сайт
  • ICQ

Re: Коллекция Property Drawers

Сообщение Unitmen 19 апр 2014, 15:55

KingPeas писал(а):При использовании для поля типа Vector3 или Vector2 проблема с высотой поля. При узком окне инспектора для Vector свойство выводится в две строки, а Drawer отрисовывает высотой в одну строку. Как не пытался так и не смог сие победить.

Попробовал, так и есть, видимо нужно переопределять и перерисовывать и сами vector2/vector3 поля...
Синтаксис:
Используется csharp
        if (!string.IsNullOrEmpty(tooltipAttribute.Tooltip))
        {
            label.tooltip = tooltipAttribute.Tooltip;
           
            // Здесь меняем property (вначале проверить тип property  т.д.)

        }
        EditorGUI.PropertyField(position, property, label);
 

Сейчас разбираться нет времени, есть желание - поправьте...
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

Re: Коллекция Property Drawers

Сообщение KingPeas 23 апр 2014, 06:24

Ну на сколько я понимаю гораздо правильнее было бы переопределить высоту поля. Осталось только определить что рисуется поле с типом вектора и вычислить что в данном случае он должен отрисоваться в две строки потому как Editor окно узкое.
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ...
Мой первый плагин PropertyDrawerCollection
Аватара пользователя
KingPeas
UNIт
 
Сообщения: 78
Зарегистрирован: 12 сен 2012, 12:34
Откуда: Новосибирск
Skype: evgeniygurlev
  • Сайт
  • ICQ

Re: Коллекция Property Drawers

Сообщение KingPeas 25 мар 2015, 20:35

Для того чтобы определить выводятся ли большинство типов полей (Vector2-4, Rect, и т.п.) в одну строку или в несколько нужно пользоваться EditorGUIUtility.wideMode, именно в этой переменной хранится как осуществляется вывод сложных полей, выводится метка на первой строке, а объект ниже или же поля выводятся после метки в той же первой строке.
Наконец добил свой плагин PropertyDrawerCollection выложил в AssetSore. :ymparty:
В планах для 2 версии добавить поддержку массивов с возможностью сортировки, вставки, удаления и переноса элементов внутри массива.
Аватара пользователя
KingPeas
UNIт
 
Сообщения: 78
Зарегистрирован: 12 сен 2012, 12:34
Откуда: Новосибирск
Skype: evgeniygurlev
  • Сайт
  • ICQ

Re: Коллекция Property Drawers

Сообщение Tolking 11 дек 2015, 12:41

Вот такую штуку запилил для не очень кастомных монобехов...
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Коллекция Property Drawers

Сообщение Unitmen 09 янв 2016, 06:27

Tolking писал(а):Вот такую штуку запилил для не очень кастомных монобехов...

(3A4OT) Более подробно можно про разработочку?
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

Re: Коллекция Property Drawers

Сообщение Tolking 09 янв 2016, 14:03

1) Ищу монобехи и помечаю галкой, тот который хочу кастомизировать.
2) Помеченный монобех разбираю через рефлексию и составляю список полей для вывода, сохраняю в скриптаблеОбжект.
3) Генерирую текст кастомного вывода монобеха и компилю. В кастомном выводе из скриптаблеОбжект берется список полей и выводиться...
4) Сделал формочку кастомизации вывода.
| а) Очередность
| б) Название
| в) коментарий
| г) добавление пробела между полями
| д) группировка полей
все это сохраняется в скриптаблеОбжект и выводится...

Для подготовки компонента для геймдизайнера очень экономит время. +скрывать в отдельной папке "служебные" поля и коментарии чтоб не забыть что и зачем...
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Коллекция Property Drawers

Сообщение Unitmen 28 янв 2016, 23:14

Tolking писал(а):Для подготовки компонента для геймдизайнера очень экономит время. +скрывать в отдельной папке "служебные" поля и коментарии чтоб не забыть что и зачем...

:-bd Отличная идея, беру на вооружение...
Аватара пользователя
Unitmen
UNIт
 
Сообщения: 122
Зарегистрирован: 10 авг 2013, 00:55

След.

Вернуться в Editor

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

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