Skip to content

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 Theme palette that the rest of the UI references.
  • A custom GUIResourceProvider that 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 Theme types and a #if switch inside DoUI. This pattern costs the least at runtime and fixes the choice at compile time.
  • Runtime: a Theme interface 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