Unity — сказочный движок.
Иногда эта сказка добрая, про пони и радугу. А иногда — про страшного бабайку. И очень важная часть данного движка, а именно расширения для редактора (custom inspectors) — как раз про бабайку. В статье я бы хотел поделиться опытом использования собственных расширений на примере нашей игры.
Начнем с определения. Вот, что говорится в документации про расширения:
“Unity позволяет вам расширить редактор своими собственными инспекторами и окнами редактора (Editor Windows), и вы можете задать, как свойства должны отображаться и инспектора при помощи пользовательского Property Drawers.” https://docs.unity3d.com/Manual/ExtendingTheEditor.html
То есть имеем три основных типа для расширения функционала, наследуемые от базовых классов:
- UnityEditor.Editor
- UnityEditor.EditorWindow
- UnityEditor.PropertyDrawer
И сразу же первая загвоздка — все расширения делаются только с помощью кода. Никакого визуального программирования и блок-схем, WYSIWYG, перетаскивания кнопочек по формочкам. Только C #, только хардор. Изменил размер кнопки — будь добр пересобрать весь проект, чтобы увидеть изменения. Соответственно, написать новое расширение или поправить скаченное из Asset Store не программисту — практически непосильная задача.
Первый тип (Editor) используется для того, чтобы сказать Unity “как отобразить класс”. Это может быть ScriptableObject или MonoBehaviour. Используется чаще всего, по крайне мере у нас. Второй (EditorWindow) — может быть использован для отображения почти любого содержимого в пределах нового окна, за которое он отвечает. Третий (PropertyDrawer) отвечает на вопрос “как отобразить параметр”. Причем это может быть как один из стандартных типов параметров, так и свой собственный.
Для каждого из типов расширений можно найти по небольшому “Hello World” в документации. Но чтобы сделать действительно полезное, удобное и красивое расширение, придется еще постараться. Связано это, во-первых, с наличием ОГРОМНОГО числа недокументированных и внутренних (Internal) функций движка, которые можно использовать. Во-вторых, с большим количеством багов и общей не интуитивностью подсистемы. В-третьих, почти все статьи про расширения на английском или вообще иероглифы. Если с английским лично я еще могу справится, то китайский поддается только гугл транслейту, что слабо помогает общему усвоению информации. Именно поэтому сделать что-то сложнее двух дополнительных кнопок — сродни алхимии и черной магии. Но когда это нас останавливало?
В нашей, казалось бы, небольшой игре используется 22 собственных скрипта для расширений на ~2 500 строк кода в сумме. Приведу особо интересные примеры для каждого типа расширений.
PropertyDrawer
Здесь, как раз, ничего сильно интересного у нас нет. Просто для примера — отображение свойства неактивным, если объект на сцене. И возможность редактировать свойство, если объект является префабом.
Эта функция используется для свойств-идентификаторов объектов. Что-то типа ИД, необходимого для сериализации/десериализации структуры уровня. Защита от самого себя, чтобы не поменять идентификатор во время сборки уровня в редакторе. Если так сделать — уровень сохранится, но загружаться не будет.
Еще есть PropertyDrawer для класса “Координаты X и Y” — вместо двух строчек выводит в одну. Еще один — для отображения коллекции string в виде выпадающего списка.
EditorWindow
Здесь уже интереснее. Кастомное окно у нас одно. Используется как основной способ редактирования уровня. Весь код я приводить, конечно, не буду. Из интересного можно выделить пару моментов.
Первый — получение картинки-превью префаба. Т.е. той картинки, которая отображается в самом редакторе Unity. Реализуется с помощью одного метода AssetPreview.GetAssetPreview(gameObject).
Второй — центрирование камеры в SceneView к выбранной ячейке.
В LocalizationEditor надо было сделать что-то вроде таблицы, чтобы четные и нечетные сроки выводились разным цветом. Решается это заведение двух разных стилей.
Вторым проблемным моментом было сделать поиск в уже добавленных ключах локализации и мгновенный вывод результатов в виде выпадающего списка под строкой поиска. Вот для этого найти решение было действительно непросто. В итоге нашелся метод на каком-то китайском сайте с иероглифами. Хорошо, что код — он и в африке (Китае) код. http://www.clonefactor.com/wordpress/public/1769/
Путем небольшой доработки напильником стало выглядеть вот так:
Собственно на этом все. В качестве вывода могу сказать, что расширения для редактора Unity — это очень и очень мощная штука. Пользоваться ей стоит однозначно. Правда перед этим нужно запастись терпением и навыком гуглить информацию на иностранных языках.
Почитать статью без картинок, зато с объемным кодом на C # можно на форуме: http://www.cyberforum.ru/unity/thread2191585.html
Подписывайтесь, комментируйте, покупайте нашу игру))
Источник: DTF