00. Интеграция SUS с нуля
Цель: поднять пустой Unity-проект до первого экрана
.sharq, не обращаясь к другим документам.
Критично: SusApp + генерируемые файлы
Sharq.Core.SusApp — документированная точка входа приложения. Предпочитайте её самодельному Start(), который просто вызывает styleSheets.Add / Mount. Она применяет TSS, каскад токенов, тему, гарантирует наличие OverlayHost (последний child корня экрана) и создаёт SusWorldSpacePanel, чтобы world-space UI (BindToWorld, health-бары) имел известную точку монтирования.
Что где лежит (после bootstrap)
SusApp — это fluent bootstrap, а не VisualElement с тремя дочерними слотами. Реальное дерево:
Camera
└── __SusWorldSpacePanel__ (SusWorldSpacePanel + UIDocument) ← UNDER all screen UI
└── healthbars / nameplates / floating damage
(WorldSpaceService.Default → BindToWorld)
Screen UIDocument ← SusApp.Create(uiDocument) targets this root
└── rootVisualElement
├── screen content (Mount<T> or SusRouteView) ← screens
└── OverlayHost ← last child: modals, tooltips,
dropdowns, toasts, consoleWorld-space не подключён к OverlayHost. После Mount / Run используйте:
WorldSpaceService.BindToWorld(healthBar, unit.transform, offset: new Vector3(0, 2f, 0));
// or: app.WorldPanel / WorldSpaceService.Default.WorldSpacePanelОтключить: .UseWorldSpace(false) для чисто 2D-приложений. Подробности: 07-overlayhost.
Курица и яйцо: держим сгенерированные .g.cs в синхроне
Исходники Sharq (.sharq) — не C#. Компилятор пишет partial-классы в GeneratedDirectory (например, Assets/SusUI/Generated/*.g.cs). Ваша точка входа (MyApp / стартер мастера Setup) обычно делает Mount<HomeScreen>() — а этот тип существует только после генерации.
Setup Project копирует готовый стартер из sus-core git (Editor/Setup/Starter~/):
| Скопированный файл | Роль |
|---|---|
HomeScreen.sharq | Исходный SFC |
Generated/HomeScreen.g.cs | Уже сгенерирован — проект компилируется сразу |
{AppName}.cs | Вызывает Sharq.Core.SusApp.Create(...).Mount<HomeScreen>() |
Для стартера по умолчанию первый RegenerateAll не требуется — мастер копирует закоммиченный .g.cs, поэтому проект компилируется в момент появления файлов. RegenerateAll запускается, только если вы включаете scaffold кастомизации вместе с downstream-пакетом компонента (AppButton.sharq), которому нужна генерация. Мейнтейнеры обновляют закоммиченный .g.cs стартера через Tools~/refresh-starter-generated.ps1 или Window → SUS → Setup → Refresh Starter Generated, затем коммитят в sus-core.
| Плохое состояние | Что происходит |
|---|---|
.sharq существует, Generated/ отсутствует или пуст | Проект не компилируется → Unity AssetPostprocessor / Sharq могут не запуститься → компилятор не может исцелить себя сам |
| Стартер ссылается на экран, который никогда не генерировался | CS0246 / domain застревает сломанным |
Удаление Generated/ «для чистоты» без регенерации | Та же курица и яйцо |
Как избежать поломки:
- Запустите
Window → SUS → Setup Projectодин раз — копирует конфиг, стартер SusApp,HomeScreen.sharq+ уже сгенерированныйHomeScreen.g.cs. Это рекомендуемый путь (см. Шаг 2). - Либо, для экрана вручную: создайте
sus.config.json+.sharq, затем сохраните.sharq(или выполнитеWindow → SUS → Sharq → Regenerate All Prototype Components), чтобы.g.csпоявился до (или вместе с) кода, который ссылается на эти типы. - Вне Unity (CI / свежий клон приложения-потребителя): CLI
sus-core/Tools~/SharqBootstrapгенерирует.g.csбез необходимости в скомпилированном Editor. - Не редактируйте
*.g.cs/*.g.ussруками — редактируйте.sharqи регенерируйте. Generated/проекта-потребителя обычно в gitignore; репозитории пакетов с опциональными библиотеками компонентов и core Starter~ поставляют сгенерированные исходники, чтобы UPM / Setup компилировались из коробки.
Window → SUS → Validate Setup предупреждает, когда .sharq существует, а Generated/ — нет.
Шаг 1. Установите пакет
Добавьте в Packages/manifest.json:
{
"dependencies": {
"com.sharq-it.sus.core": "https://github.com/antaresdk/sus-core.git#v1.0.29"
}
}Unity автоматически подхватит пакет, когда редактор окажется в фокусе. Он появится в Package Manager как "SusCore".
Для локальной разработки можно использовать
"file:../sus-core"рядом с вашим проектом. Для продакшена — git URL или npm registry.
Шаг 2. Рекомендуемый путь — Setup Project
Window → SUS → Setup Project делает всё нижеперечисленное в один клик:
- проверяет окружение (версия Unity, UI Toolkit, пакеты),
- записывает
sus.config.json, - создаёт сцену с
UIDocument+PanelSettings, - копирует готовый стартер (
HomeScreen.sharq+Generated/HomeScreen.g.cs+{AppName}.cs), - опционально создаёт scaffold папки
Customization/.
Поскольку стартер поставляется с уже сгенерированным .g.cs, проект компилируется сразу — первый шаг генерации не нужен. После завершения работы мастера и перекомпиляции Unity переходите сразу к Шагу 7 (Play).
Предпочитайте этот путь. Шаги 3–6 ниже описывают ручную настройку экрана без мастера — полезно для понимания пайплайна или добавления экранов вручную.
Шаг 3. Первый компонент .sharq (вручную)
Создайте Assets/SusUI/HelloScreen.sharq:
<template>
<ui:VisualElement $MainElement style="flex-grow: 1; align-items: center; justify-content: center;">
<ui:Label text="Hello SUS!" style="font-size: 28px; color: white; -unity-text-align: middle-center;" />
</ui:VisualElement>
</template>
<script>
$using Sharq.Core;
</script>В
<script>используйте$using(директиву Sharq), а не обычныйusing.Sharq.Coreимпортируется автоматически, так что пустой<script>(или его отсутствие) тоже работает —$usingвыше — просто пример.
Шаг 4. sus.config.json
Создайте Assets/sus.config.json:
{
"SharqDirectory": "Assets/SusUI",
"GeneratedDirectory": "Assets/SusUI/Generated",
"ResourcesDirectory": "Assets/SusUI/Generated/Resources/SusRuntime",
"LogGeneratedFiles": true
}| Поле | Назначение |
|---|---|
SharqDirectory | Где живут ваши .sharq-файлы |
GeneratedDirectory | Куда писать .g.cs и .g.uss |
ResourcesDirectory | Куда писать Resources/-зеркала .uss |
LogGeneratedFiles | true (по умолчанию) — логировать каждый сгенерированный файл; false — отключить |
Если файла нет, компилятор Sharq использует пути по умолчанию (
Assets/SusUI).
Шаг 5. Генерация Sharq (ручной путь)
После сохранения .sharq компилятор Sharq автоматически генерирует:
Assets/SusUI/Generated/HelloScreen.g.cs— partial-класс C#Assets/SusUI/Generated/HelloScreen_static.g.uss— inlinestyle="…", вынесенный в USS (глобальныйHelloScreen.g.uss/ scopedHelloScreen_scoped.g.ussпоявляются, только если у компонента есть блок<style>)
Порядок важен: генерируйте (или дождитесь импорта) до того, как скомпилируется точка входа с Mount<HelloScreen>(). Если domain уже сломан, используйте Setup Project / Regenerate All Prototype Components / CLI bootstrap — см. Критично: SusApp + генерируемые файлы выше.
Проверьте консоль Unity: Window → SUS → Validate Setup — диагностика покажет, всё ли в порядке.
Шаг 6. Точка входа — SusApp (ручной путь)
Создайте MyApp.cs и повесьте его на GameObject с UIDocument:
using Sharq.Core;
using UnityEngine;
using UnityEngine.UIElements;
[RequireComponent(typeof(UIDocument))]
public class MyApp : MonoBehaviour
{
// OnEnable mirrors the Setup Project starter; Start() also works.
private void OnEnable()
{
// Prefer Sharq.Core.SusApp — avoids clash with a legacy global SusApp type.
Sharq.Core.SusApp.Create(GetComponent<UIDocument>())
.UseTheme(SusTheme.Dark)
.Mount<HelloScreen>();
}
}SusApp.Create(UIDocument), затем Mount / Run — полный порядок Finalize:
- Create — применяет
SusDefault.tssк PanelSettings (_palette+_font+_globalна уровне панели) - Icons — регистрируются провайдеры
UseIcons(наивысший приоритет) - Token cascade —
_palette→_font→_theme→design-tokens→_icon→ L4/L5 extras +OverlayHost(последний child) - World —
EnsureWorldSpacePanel+WorldSpaceService.Default(если не указаноUseWorldSpace(false)) - Fonts —
UseFontsна root + OverlayHost - Custom styles —
UseCustomStylesна root + OverlayHost (верхний override-слой) - Configure — коллбэки (регистрация роутера, ручной UI)
- Mount — корневой компонент (если
Mount<T>) - Theme last —
SusThemeService.Instance.SetTheme(root, theme), чтобы OverlayHost унаследовал классы темы
Это поддерживаемый способ запуска приложения SUS. Предпочитайте Setup Project, чтобы стартер + первый .g.cs создавались вместе.
Шаг 7. Play
Нажмите Play → белый текст «Hello SUS!» на тёмном фоне.
Альтернативный bootstrap — SusBootstrap.Mount<T>()
Если SusApp не подходит (например, ручной UI без тем):
void Start()
{
// Apply the default TSS + create OverlayHost.
// NOTE: Mount<T> does NOT call ApplyDefaultTSS for you — do it explicitly here.
SusBootstrap.ApplyDefaultTSS(_uiDocument);
var root = _uiDocument.rootVisualElement;
// Load the token cascade manually (_palette → _font → _theme → design-tokens → _icon).
SusBootstrap.LoadTokenCascade(root);
// Mount the component
SusBootstrap.Mount<HelloScreen>(root);
}Вам всё равно нужен сгенерированный .g.cs для HelloScreen. Пропуск SusApp не отменяет правило курицы и яйца. Этот путь применяет каскад, но не тему — вызовите SusThemeService.Instance.SetTheme(root, SusTheme.Dark) сами, если она нужна.
Подключение sus-router
Open-core (бесплатные) пакеты с публичного GitHub:
{
"dependencies": {
"com.sharq-it.sus.core": "https://github.com/antaresdk/sus-core.git#v1.0.29",
"com.sharq-it.sus.router": "https://github.com/antaresdk/sus-router.git#v1.0.16"
}
}Опциональные библиотеки UI-компонентов — отдельные продукты, см. https://sus-ui.dev.
С роутером (using Sharq.Router;). Регистрируйте каждый экран, на который переходите, — в примере используются HomeScreen и SettingsScreen, поэтому у обоих должны быть исходники .sharq (и сгенерированный .g.cs):
SusApp.Create(_uiDocument)
.UseTheme(SusTheme.Dark)
.UseRouter(
new SusRouter(),
r =>
{
r.Register("/", typeof(HomeScreen));
r.Register("/settings", typeof(SettingsScreen));
},
initialPath: "/")
.Run();Мастер Setup и папка Customization/
Всё вышеперечисленное можно получить одной кнопкой: Window → SUS → Setup Project — мастер проверяет окружение, записывает sus.config.json, создаёт сцену с UIDocument + PanelSettings и копирует готовый стартер (HomeScreen.sharq + уже сгенерированный HomeScreen.g.cs + {AppName}.cs). Для стартера по умолчанию первая генерация не запускается, поэтому он компилируется из коробки (решает курицу и яйцо).
При включённой опции Create customization scaffold (включена по умолчанию) мастер также создаёт {UI-root}/Customization/ — выделенное место для кастомизации проекта с живым примером для каждой оси; всё уже подключено в стартере через одну строку Use*:
| Ось | Файл | Строка в стартере |
|---|---|---|
| Цвета/размеры (токены) | Customization/Theme/Resources/branding.uss | .UseCustomStyles("branding") |
| Шрифты | Customization/Fonts/AppFonts.asset | .UseFonts(_fonts) |
| Иконки | Customization/Icons/Resources/SusRuntime/Icons/app/… | .UseIcons(new ResourcesFolderIconProvider(<yourPackageOrCollection>, "app")) |
| Ваш компонент | Customization/Components/AppButton.sharq (опциональный downstream-пакет) | <sus:AppButton> в HomeScreen.sharq |
Иконки — нюанс первого аргумента.
ResourcesFolderIconProvider(editorPackagePath, collection)направляет скан редактора вPackages/{editorPackagePath}/Runtime/Resources/SusRuntime/Icons/{collection}(с fallback наAssets/Resources/SusRuntime/Icons/{collection}). Для приложения-потребителя, поставляющего собственный пакет, передавайте свой id пакета (например,"com.my.game"); для иконок подAssets/.../Resourcesпередавайте id, путь которого не существует, чтобы сработал fallback наAssets/Resources. Не копируйте"com.sharq-it.sus.core"дословно — это направит скан на core-пакет, а не на ваши иконки. См. Design tokens §4.
Карточка «Хочу изменить X → редактировать файл Y» — в созданном Customization/README.md. Повторный запуск мастера не стирает отредактированные файлы (создаются только отсутствующие).
Диагностика
Window → SUS → Validate Setup проверяет:
- Версия Unity (≥6000.0)
- UI Toolkit
sus.config.jsonи пути- Наличие
.sharqи.g.cs PanelSettings- Наличие пакетов
Настройка редактора — подсветка синтаксиса .sharq
.sharq сам по себе не C# / XML / CSS. Без расширения редактора файл выглядит как обычный текст. SusCore поставляет расширение VS Code / Cursor в Tools~/vscode-sharq/ внутри пакета (Unity никогда не импортирует Tools~ как ассеты).
Что подсвечивается:
| Блок | Язык | Дополнения Sharq |
|---|---|---|
<template> | XML | v-if / v-else / v-for / v-show, :prop, @event, $MainElement |
<script> | C# | $using Namespace; |
<style> | CSS | USS -unity-*, design tokens --sus-* |
Установка в VS Code или Cursor
A. Скопировать папку (Node / Marketplace не нужны):
- Найдите пакет на диске — Package Manager → SusCore → path, или git checkout
sus-core. ОткройтеTools~/vscode-sharq/. - Скопируйте эту папку в:
- Windows VS Code:
%USERPROFILE%\.vscode\extensions\sharq-it.sharq-language-0.1.0 - macOS / Linux VS Code:
~/.vscode/extensions/sharq-it.sharq-language-0.1.0 - Cursor:
%USERPROFILE%\.cursor\extensions\sharq-it.sharq-language-0.1.0(или~/.cursor/extensions/…)
- Windows VS Code:
- Перезапустите редактор и откройте
.sharq— в статус-баре язык должен быть Sharq.
B. Установка из VSIX:
В той же папке есть sharq-language-0.1.0.vsix. В редакторе: Extensions → … → Install from VSIX… → выберите файл → reload.
Чтобы позже пересобрать VSIX:
npm i -g @vscode/vsce
cd <path-to-sus-core>/Tools~/vscode-sharq
vsce package --allow-missing-repositoryСтартовый пример после установки: Editor/Setup/Starter~/HomeScreen.sharq (также копируется в проект мастером Setup Project).
Rider / JetBrains
Отдельного JetBrains-плагина пока нет. Укажите TextMate / TextMate Bundles Rider на Tools~/vscode-sharq/syntaxes/sharq.tmLanguage.json (те же scopes, что у VS Code). Это поддерживаемый временный путь.
Marketplace (опционально)
Листинг VS Code Marketplace под publisher sharq-it опционален и отделён от поставки пакета. Локальная копия / VSIX выше достаточны для повседневного редактирования.
Далее
- Quick start — подробнее о
.sharq, композициях, props - OverlayHost — оверлейные слои экрана vs world-space
- Design tokens — темизация: цвета, шрифты, иконки
- Заметки о расширении тем —
Documentation~/theme-extension.mdв репозитории пакета