В то время как я очень рад новому UI от Unity — UI Toolkit (UITK), я также был постоянно разочарован в связи с отсутствием множества фич, которые нужны здесь и сейчас.
И несмотря на то, что привязка данных в рантайме и поддержка локализации (тоже пакет от Unity) уже в разработке для UITK, их релиз ожидается только к концу 2023. Потому я решил разработать привязку данных самостоятельно и не терять время в ожидании или привыканию к uGUI (естественно за исключением, когда необходим world‑space UI).
Учитывая, что UITK очень схож с уже давно существующими языками XAML — UXML и CSS — USS, становится очень удобно использование уже укрепившихся паттернов широко используемых при разработке GUI.
Например, уже в настоящий момент UITK полностью поддерживает разработку используя Model‑View‑Presentation паттерн. И хотя в его использовании не мало хорошего, но он также имеет ряд серьёзных недостатков. Поэтому было решено использовать паттерн Model‑View‑ViewModel, который подразумевает использование привязка данных типа View→ViewModel, что позволяет разделить разработку View и кода принося несколько ключевых преимуществ:
Появляется возможность рефакторить View, совершенно не трогая код и наоборот - можно рефакторить код, не ломая интерфейс.
UI дизайнерам не нужно знать, как работает код, чтобы работать на интерфейсом и наоборот - кодерам совсем не обязательно уметь верстать красивый интерфейс.
Использование привязки значительно сокращает количество необходимо кода.
Для того чтобы реализовать все эти преимущества я решил использовать CommunityToolkit.Mvvm широко рекомендуемый Microsoft, при использовании своих фреймворков. Его использование также добавляет несколько ключевых преимуществ:
Кодогенерация шаблонного кода
Высокопроизводительная система сообщений (Messaging)
Итак. Что же было достигнуто и что мы имеем?
На данный момент в моём пакете вы встретите следующие фичи:
Привязка текста TextElementов.
Прямо через UXML можно привязать text к свойству ViewModel, используя синтаксис string.Format.Привязка локализации с поддержкой переменных, вложенных (nested) переменных и вложенных локализаций и полной поддержкой всех фич предоставляемых smart-string.
Привязка по интерфейсу INotifyValueChanged<T>.
Такая привязка является двухсторонней и открывает широкие возможности для чтения ввода (input) пользователя.Привязка IRelayCommand.
Эта привязка позволяет очень просто создавать кнопки. Также можно даже передать параметр для вызываемого метода, что позволяет привязать к одному методу сразу несколько кнопок.Привязка через рефлексию.
С её помощью можно привязать практически любое свойства VisualElement к коду. Например: style.fontSize или style.backgroundImage.Поддержка Burst.
А если вы пользователь DOTS, то вы можете интегрировать игровую логику с UI с помощью специального враппера прямо из нативного кода.
И множество других фич на горизонте...
Все виды привязок используют делегаты и избегают боксинга значений так, как это только возможно. Достичь этого удалось с помощью явно объявленных дженериков, в виде, позволяющем добавить поддержку любого кастомного типа в одну строчку.
И всё это с полной поддержкой IL2CPP и WebGL.
Не обошлось и без требований. Для успешной работы привязок потребуется:
UniTask. Он широко используется для асинхронной привязки локализации, позволяя избегать скачков фреймрейта (fps).
Net Standard 2.1
Unity 2022.2. Хотя все предыдущие версии Unity тоже частично поддерживаются (при условии наличия UniTask и NS2.1), 2022.2 - это первая версия включающая поддержку Roslyn 4.0.1 API, которая даёт возможность использовать кодогенерацию из пакета CommunityToolkit.Mvvm.
В пакете представлены семпл проект и подробный readme с инструкцией на практически каждую фичу из проекта (на данный момент всё на английском и будет переведено при достаточном спросе).
Лицензирован пакет под лицензией MIT.
https://github.com/bustedbunny/com.bustedbunny.mvvmtoolkit
Проект всё ещё в активной разработке и до первого стабильного релиза в основную ветку могут быть запушены коммиты с кардинальными изменениями.