К содержимому

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, console

World-space не подключён к OverlayHost. После Mount / Run используйте:

csharp
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/ «для чистоты» без регенерацииТа же курица и яйцо

Как избежать поломки:

  1. Запустите Window → SUS → Setup Project один раз — копирует конфиг, стартер SusApp, HomeScreen.sharq + уже сгенерированный HomeScreen.g.cs. Это рекомендуемый путь (см. Шаг 2).
  2. Либо, для экрана вручную: создайте sus.config.json + .sharq, затем сохраните .sharq (или выполните Window → SUS → Sharq → Regenerate All Prototype Components), чтобы .g.cs появился до (или вместе с) кода, который ссылается на эти типы.
  3. Вне Unity (CI / свежий клон приложения-потребителя): CLI sus-core/Tools~/SharqBootstrap генерирует .g.cs без необходимости в скомпилированном Editor.
  4. Не редактируйте *.g.cs / *.g.uss руками — редактируйте .sharq и регенерируйте.
  5. Generated/ проекта-потребителя обычно в gitignore; репозитории пакетов с опциональными библиотеками компонентов и core Starter~ поставляют сгенерированные исходники, чтобы UPM / Setup компилировались из коробки.

Window → SUS → Validate Setup предупреждает, когда .sharq существует, а Generated/ — нет.


Шаг 1. Установите пакет

Добавьте в Packages/manifest.json:

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:

xml
<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:

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
LogGeneratedFilestrue (по умолчанию) — логировать каждый сгенерированный файл; false — отключить

Если файла нет, компилятор Sharq использует пути по умолчанию (Assets/SusUI).


Шаг 5. Генерация Sharq (ручной путь)

После сохранения .sharq компилятор Sharq автоматически генерирует:

  • Assets/SusUI/Generated/HelloScreen.g.cs — partial-класс C#
  • Assets/SusUI/Generated/HelloScreen_static.g.uss — inline style="…", вынесенный в USS (глобальный HelloScreen.g.uss / scoped HelloScreen_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:

csharp
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:

  1. Create — применяет SusDefault.tss к PanelSettings (_palette + _font + _global на уровне панели)
  2. Icons — регистрируются провайдеры UseIcons (наивысший приоритет)
  3. Token cascade_palette_font_themedesign-tokens_icon → L4/L5 extras + OverlayHost (последний child)
  4. WorldEnsureWorldSpacePanel + WorldSpaceService.Default (если не указано UseWorldSpace(false))
  5. FontsUseFonts на root + OverlayHost
  6. Custom stylesUseCustomStyles на root + OverlayHost (верхний override-слой)
  7. Configure — коллбэки (регистрация роутера, ручной UI)
  8. Mount — корневой компонент (если Mount<T>)
  9. Theme lastSusThemeService.Instance.SetTheme(root, theme), чтобы OverlayHost унаследовал классы темы

Это поддерживаемый способ запуска приложения SUS. Предпочитайте Setup Project, чтобы стартер + первый .g.cs создавались вместе.


Шаг 7. Play

Нажмите Play → белый текст «Hello SUS!» на тёмном фоне.


Альтернативный bootstrap — SusBootstrap.Mount<T>()

Если SusApp не подходит (например, ручной UI без тем):

csharp
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:

json
{
  "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):

csharp
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>XMLv-if / v-else / v-for / v-show, :prop, @event, $MainElement
<script>C#$using Namespace;
<style>CSSUSS -unity-*, design tokens --sus-*

Установка в VS Code или Cursor

A. Скопировать папку (Node / Marketplace не нужны):

  1. Найдите пакет на диске — Package Manager → SusCore → path, или git checkout sus-core. Откройте Tools~/vscode-sharq/.
  2. Скопируйте эту папку в:
    • 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/…)
  3. Перезапустите редактор и откройте .sharq — в статус-баре язык должен быть Sharq.

B. Установка из VSIX:

В той же папке есть sharq-language-0.1.0.vsix. В редакторе: Extensions → … → Install from VSIX… → выберите файл → reload.

Чтобы позже пересобрать VSIX:

bash
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 в репозитории пакета