Theming¶
Tick UI themes a project through colours, fonts, and icons that swap between sections of the UI or at runtime. This guide connects the Resource providers concept and the Add a custom font task.
What this guide builds¶
This guide builds a small theming setup that covers the following:
- A
Themepalette that the rest of the UI references. - A custom
GUIResourceProviderthat carries the project's fonts and icons. - A locale-pack provider pushed at runtime when the player changes language.
Step 1: create a palette object¶
Centralise colours so the rest of the UI keeps hex strings in one place. A static palette type works well:
public static class Theme
{
public static readonly Color Primary = UI.FromHex("#23C9FF");
public static readonly Color Background = UI.FromHex("#1A1A1A");
public static readonly Color Surface = UI.FromHex("#2A2A2A");
public static readonly Color Text = UI.FromHex("#EAEAEA");
public static readonly Color TextMuted = UI.FromHex("#9A9A9A");
public static readonly Color Danger = UI.FromHex("#FF4D4D");
}
Reference Theme.Primary and the other palette colours from
DoUI. A centralised palette delivers two benefits:
- A colour rename is a single edit.
- A palette switch for a dark or light theme is a single swap of the static type.
For the colour helpers used here, refer to Colors reference.
Step 2: register the project's fonts and icons¶
Author a GUIResourceProvider asset under
Assets/UI/Resources/MyGameUIAssets.asset. Populate the Fonts
list with each font and size variant you need, and the Images
list with project icons.
Add the asset to the Resource Providers array on the
BaseGameUI subclass. Index 0 is checked first, so place
project-wide assets at the top.
The bundled DefaultTickConfig is appended automatically as the
lowest-priority fallback, so the bundled roboto_mono and shader set
remain available alongside your project assets.
For the per-font procedure, refer to Add a custom font. For the provider chain, refer to Resource providers.
Step 3: add dark and light theme variants¶
Tick UI supports two patterns for theme variants:
- Compile-time: two static
Themetypes and a#ifswitch insideDoUI. This pattern costs the least at runtime and fixes the choice at compile time. - Runtime: a
Themeinterface and a runtime-swappable implementation, or a static field reassigned at theme-change time. This pattern costs a field read per access and supports player-facing theme switches.
Either pattern pairs with provider-based asset swaps when the dark and light themes use different fonts or icons.
Step 4: swap locale packs at runtime¶
For locale-specific fonts and icons, ship one
GUIResourceProvider per locale. Push at runtime when the player
selects a language, and remove it on the next switch:
public void SetLocale(LocalePack pack)
{
if (m_currentLocale != null)
m_baseGameUI.ResourceProviders.Remove(m_currentLocale);
m_baseGameUI.ResourceProviders.Push(pack);
m_currentLocale = pack;
}
Push inserts at the highest priority, so the new pack's fonts
and icons shadow lower-priority entries with the same names.
Remove returns to the previous order.
Pitfalls¶
A locale pack does not take effect immediately.
: The push happened before BaseGameUI's Start finished.
Wait for Start to complete (or check
BaseGameUI.ResourceProviders is non-null) before pushing.
A theme swap leaks across panels. : The palette is cached inside a panel's state that survives the swap. Audit the panel for stale references.
Pink materials after a theme provider change. : The new provider has a partial shader list. Populate the full set, or remove the shader list so the bundled default supplies the shaders.
Additional resources¶
- Resource providers: the composite chain and runtime push semantics.
- Add a custom font: the per-font procedure.
- Colors reference:
FromHex,FromInt,WithAlpha. - Animation guide: theme-aware hover and press animations.