跳转到内容

1. 快速开始 ​

最小组件 ​

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

编译结果:

csharp
[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 中使用:

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

xml
<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、主题):

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

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

csharp
SusBootstrap.Mount<App>(someVisualElement);

传递参数:

csharp
var app = SusBootstrap.Mount<App>(uiDocument);
app.IsLoggedIn = true;
app.PlayerName = "Alice";

多个独立的组件树:

csharp
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(只挂 EventSystem 组件的 GameObject —— 不含 StandaloneInputModule)。 UI Toolkit 的输入不需要 legacy Input Module。

Design-token 级联 —— 按以下顺序加载到容器上:

_palette → _font → _theme → design-tokens → _icon → 已注册的扩展项(L4/L5) → OverlayHost

_global.uss 不属于这个级联。它是通过 panel TSS 应用的(SusDefault.tss / SusBootstrap.ApplyDefaultTSS / SusApp.Create(UIDocument))。

默认字体是 Montserrat,随包附带(_font.uss)。推荐的覆盖方式是 USS 令牌级别:

  1. 在你的项目中创建 Assets/Resources/SusRuntime/_font.uss
  2. 将 --sus-font-family-regular(以及你需要的任何其他字体族)设置为 url("path/to/YourFont.asset") — 使用 Font Asset(SDF),而不是已废弃的 -unity-font

或者填充 SusFontAsset(Assets → Create → SUS → Font Set)并运行 Window → SUS → Fonts → Export Font Set to USS,这会为你写入相同的文件。 SusApp.UseFonts(SusFontAsset) 仅注册该集合,以便在你忘记 导出步骤时发出警告 — 它本身不应用字体。完整内容见 Documentation~/font-extension.md(两种路径、角色标记类、SDF vs. raw TTF、缺失字形回退)。

安装 ​

通过 Unity Package Manager(Git URL):

https://github.com/antaresdk/sus-core.git#v1.3.4

组件组合(父 → 子) ​

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

json
{
  "SharqDirectory": "Assets/SusUI",
  "GeneratedDirectory": "Assets/SusUI/Generated",
  "EnableValidation": true,
  "StrictVForKey": true,
  "LogGeneratedFiles": true,
  "HotReloadStatePreserve": true
}