Войти в почту

Кастомные редакторы для Unity3D, которые мы используем в игре

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

Кастомные редакторы для Unity3D, которые мы используем в игре
© DTF.RU