1. Быстрый старт
Минимальный компонент
<!-- HelloWorld.sharq -->
<template>
<ui:Label $MainElement :text="Message" class="greeting"
style="font-size: 24px; -unity-text-align: middle-center; color: white;" />
</template>
<script>
public string Message = "Hello SUS!";
</script>Компилируется в:
[UxmlElement]
public partial class HelloWorld : SusComponent
{
public string Message = "Hello SUS!";
protected override void Build()
{
AddToClassList("greeting");
this.AddToClassList("sharq-HelloWorld-s0");
BindText(this, () => Message);
}
}Использование в UXML:
<sus:HelloWorld />Подключение к сцене (bootstrap)
Аналог подхода Vue createApp(App).mount('#app').
Порядок важен. Точка входа
Mount<App>()скомпилируется только после того, какApp.sharqбудет сгенерирован вApp.g.cs. Сначала создайте компонент (сохраните.sharq/ запустите Setup Project), затем добавляйте точку входа — иначе получитеCS0246(правило «курица и яйцо», см. 00-integration).
1. Создайте корневой компонент — App.sharq (дочерние <sus:MainMenu> / <sus:BattleHUD> ниже — это ваши собственные компоненты; необязательные библиотеки UI — отдельные продукты на https://sus-ui.dev):
<template>
<ui:VisualElement $MainElement class="app-root" style="flex-grow: 1;">
<sus:MainMenu v-if="CurrentScreen == 'menu'" />
<sus:BattleHUD v-if="CurrentScreen == 'battle'" />
</ui:VisualElement>
</template>
<script>
public string CurrentScreen = "menu";
</script>2. Добавьте точку входа. Предпочитайте SusApp — задокументированную точку входа (TSS, каскад токенов, OverlayHost, world panel, тема):
using Sharq.Core;
using UnityEngine;
using UnityEngine.UIElements;
public class AppEntry : MonoBehaviour
{
public UIDocument uiDocument;
void Start()
{
SusApp.Create(uiDocument)
.UseTheme(SusTheme.Dark)
.Mount<App>();
}
}Низкоуровневая альтернатива — SusBootstrap.Mount<T> (загружает каскад токенов, но не применяет SusDefault.tss, не задаёт тему и не собирает каркас слоёв (ScreenHost / OverlayHost) — при необходимости вызовите SusBootstrap.ApplyDefaultTSS(uiDocument) и SusThemeService.Instance.SetTheme(root, SusTheme.Dark) самостоятельно):
using Sharq.Core;
using UnityEngine;
using UnityEngine.UIElements;
public class AppEntry : MonoBehaviour
{
public UIDocument uiDocument;
void Start()
{
// Vue analogue: createApp(App).mount('#app')
SusBootstrap.Mount<App>(uiDocument);
}
}Без UIDocument — в любой VisualElement:
SusBootstrap.Mount<App>(someVisualElement);Передача параметров:
var app = SusBootstrap.Mount<App>(uiDocument);
app.IsLoggedIn = true;
app.PlayerName = "Alice";Несколько независимых деревьев:
public class MultiPanelEntry : MonoBehaviour
{
public UIDocument leftPanel;
public UIDocument rightPanel;
void Start()
{
var sidebar = SusBootstrap.Mount<Sidebar>(leftPanel);
sidebar.ActiveTab = "inventory";
var details = SusBootstrap.Mount<ItemDetails>(rightPanel);
details.ItemId = 42;
// Components from different trees communicate through events:
sidebar.On("tab-changed", (Action<string>)(tab => details.FilterByTab(tab)));
}
}EventSystem:
SusBootstrap.Mount<T>()/SusAppпри первом запуске автоматически создаютEventSystem(GameObject только сEventSystem— безStandaloneInputModule). Ввод UI Toolkit не требует legacy Input Module.
Каскад design-токенов — загружается в контейнер в следующем порядке:
_palette → _font → _theme → design-tokens → _icon → зарегистрированные дополнения (L4/L5) → OverlayHost
_global.uss не входит в этот каскад. Он применяется через panel TSS (SusDefault.tss / SusBootstrap.ApplyDefaultTSS / SusApp.Create(UIDocument)).
Шрифт по умолчанию — Montserrat. Идёт в комплекте с пакетом (_font.uss). Предпочтительный способ переопределить — SusApp.UseFonts(SusFontAsset) (см. Design tokens §2). Чтобы переопределить через USS:
- Создайте
Assets/Resources/SusRuntime/_font.uss - Добавьте
:root { -unity-font-definition: url("path/to/YourFont.asset"); }(используйте-unity-font-definitionс Font Asset, а не устаревший-unity-font)
Установка
Через Unity Package Manager (Git URL):
https://github.com/antaresdk/sus-core.git#v1.0.29Композиция компонентов (родитель → потомок)
<!-- ParentScreen.sharq -->
<template>
<ui:VisualElement $MainElement class="parent">
<!-- Literal prop -->
<sus:SusButton variant="primary" :text="BtnText" />
<!-- Reactive prop - when Status.Value changes, the button will be updated -->
<sus:SusButton :variant="Status.Value" text="Dynamic" />
<!-- Slot: content between tags → in <slot> child -->
<sus:SusCard>
<ui:Label text="I'm in the #default slot!" />
</sus:SusCard>
</ui:VisualElement>
</template>
<script>
public Prop<string> BtnText = new("Click Me");
public Prop<string> Status = new("primary");
</script>Конфигурация — создайте Assets/sus.config.json:
{
"SharqDirectory": "Assets/SusUI",
"GeneratedDirectory": "Assets/SusUI/Generated",
"EnableValidation": true,
"StrictVForKey": true,
"LogGeneratedFiles": true,
"HotReloadStatePreserve": true
}