Class UnityLeaderboardPanel
Script on a leaderboard panel (theme's LeaderboardTemplate, or the procedural fallback built by
CreateProcedural(Transform, GameObject)): a header slot, a container the ranked rows render through, and an
empty-state slot shown when the board has no entries. Filled and driven by UnityLeaderboardView.
The rows container is itself a UnityTablePanel root (see Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.EnsureTable): rows
grow with the list, and scroll once the ROWS element's own authored placement Size clips them.
Namespace: Serenity.Leaderboard.Infrastructure.Views
Assembly: Serenity.UnityLeaderboard.Infrastructure.dll
Syntax
public sealed class UnityLeaderboardPanel : MonoBehaviour
Remarks
Intentionally Unity-only: a MonoBehaviour authored on a theme prefab (or built procedurally) and
driven only by UnityLeaderboardView (same module) via uGUI/TMP/layout APIs. No Business port for
v1 — a non-Unity port authors its own themed panel scene/script rather than porting an abstraction over
this class.
Constructors
UnityLeaderboardPanel()
Declaration
public UnityLeaderboardPanel()
Methods
ApplyElementPlacements(IReadOnlyList<LeaderboardElementPlacement>)
Stores placements and applies them through LeaderboardPanelPlacementApplier
immediately; re-applied automatically at the end of SetRows(IReadOnlyList<LeaderboardRowContent>, LeaderboardColumnLayout, GameObject) and
ConfigureRowsScrolling(bool) so the placements survive both rebuilding the rows and (when
scrollable) the table's own scroll-shell extent catching up. Passing null or an empty list leaves the
panel exactly as it was built — the stacking layout group and fitter stay enabled, and no element
gains a LayoutElement it didn't already have.
Declaration
public void ApplyElementPlacements(IReadOnlyList<LeaderboardElementPlacement> placements)
Parameters
| Type | Name | Description |
|---|---|---|
| IReadOnlyList<LeaderboardElementPlacement> | placements | One resolved placement per LeaderboardViewElement. |
ApplyThemeTitleTemplate(GameObject)
Replaces the procedural header holder CreateProcedural(Transform, GameObject) built with an instance of the
theme's TitleTemplate prefab, so a procedural panel's title renders through the same themed
title component a theme's own LeaderboardTemplate prefab already nests as its "Header" child
(see ChromePrefabBuilders.BuildLeaderboard) — mirrors UnityMenuTitleBuilder.RenderTitle.
A no-op when titleTemplate is null, this panel is not the procedural fallback (a
themed LeaderboardTemplate prefab already carries its own authored header — nothing to swap),
or no header holder exists. The new instance is parented under the old holder's own parent at the
same sibling index, inherits its active state and TMP text, and keeps the name "Header" so every
other lookup by field (TryResolveElementRect(LeaderboardViewElement, out RectTransform)'s TITLE case, SetTitle(string, bool))
keeps resolving through Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel._headerGameObject unchanged — callers must apply this BEFORE
SetTitle(string, bool) so the title text lands on the new instance, not the discarded holder. Only a
UnityEngine.GameObject template is accepted; the menu title builder's factory-resolution path for
exotic IUiThemeComponents.TitleTemplate types is out of scope here.
Declaration
public void ApplyThemeTitleTemplate(GameObject titleTemplate)
Parameters
| Type | Name | Description |
|---|---|---|
| GameObject | titleTemplate | The theme's |
ConfigureBackground(LeaderboardBackgroundStyle)
Shows or hides the panel's background and applies style's sprite/tint/slicing.
Resolves the background target in priority order: Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel._backgroundGameObject when wired,
else a direct child named Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.BackgroundChildName (what every panel this MonoBehaviour
builds — themed or procedural — names its background instance), else this panel's own root (only a
hand-authored panel with neither ever hits this branch). A resolved child is shown/hidden via
SetActive; the root is shown/hidden via Image.enabled instead, since disabling
the whole GameObject would hide every other element with it. Idempotent: every call fully re-derives
the target's state from style — including across mode switches, since the first
call latches the target's authored color/sprite (Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.CaptureBackgroundAuthoredState(UnityEngine.UI.Image)) and
every later THEME call composes against that same latched authoring rather than whatever a previous
CUSTOM call left on the image. Independent of TryResolveElementRect(LeaderboardViewElement, out RectTransform)'s
BACKGROUND case: this method decides whether the background renders at all, a resolved
LeaderboardElementPlacement only ever decides where it sits, and the two never fight
over the same field — see LeaderboardPanelPlacementApplier's remarks on Hidden
only ever deactivating.
Declaration
public void ConfigureBackground(LeaderboardBackgroundStyle style)
Parameters
| Type | Name | Description |
|---|---|---|
| LeaderboardBackgroundStyle | style | The resolved background style (mode, sprite override, tint, slicing, PPU). |
ConfigureBackground(bool, Sprite, Color)
Legacy shape, kept so every pre-existing caller/test keeps compiling and behaving the same: maps its
three arguments onto a LeaderboardBackgroundStyle — visible false
becomes HIDDEN; visible with a sprite becomes
CUSTOM at KEEP_SPRITE
(today's "never touch Image.type" behavior); visible with no sprite becomes
THEME — then delegates to
ConfigureBackground(LeaderboardBackgroundStyle). Intentional behavior change: the
no-sprite (THEME) path now COMPOSES tint with the target's authored color instead of
replacing it — a white tint keeps the authored look, previously only reachable this way when the caller
also passed visible: true against an already-white-authored target.
Declaration
public void ConfigureBackground(bool visible, Sprite spriteOverride, Color tint)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | visible | Whether the background renders at all. |
| Sprite | spriteOverride | Replaces the target's sprite when set; the existing sprite is kept when null. |
| Color | tint | Composed with the target's authored Image.color (THEME/HIDDEN) or applied absolute (CUSTOM). |
ConfigureRowsScrolling(bool)
Whether the rows table clips its overflow behind a scroll mask instead of rendering it visibly past
its own bounds — the vertical half of UnityCascadePanel.ConfigureScroll's contract, now owned
by the table's own TableLayoutConfig.ScrollableY flag rather than a row count. The
rows area's visible HEIGHT is whatever the ROWS element's own placement Size authors — see
Serenity.Leaderboard.Infrastructure.Views.LeaderboardTableMapper.ToTableConfig(System.Boolean).
Declaration
public void ConfigureRowsScrolling(bool scrollable)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | scrollable | Whether the rows table's vertical axis scrolls its overflow. |
Remarks
Stores scrollable and re-configures the table immediately when one already
exists — but the same flag flows into every SetRows(IReadOnlyList<LeaderboardRowContent>, LeaderboardColumnLayout, GameObject) call too, so calling this BEFORE
any rows exist (both production call sites — UnityLeaderboardView.Configure and
LeaderboardViewPreviewBuilder.ConfigurePanel — configure scrolling before rows arrive) is not
a no-op: the table applies it the moment SetRows(IReadOnlyList<LeaderboardRowContent>, LeaderboardColumnLayout, GameObject) first calls Configure.
CreateProcedural(Transform, GameObject)
Builds a minimal, unthemed panel (background, header, rows container, empty-state label) under
parent for when no theme LeaderboardTemplate is configured.
Declaration
public static UnityLeaderboardPanel CreateProcedural(Transform parent, GameObject backgroundTemplate = null)
Parameters
| Type | Name | Description |
|---|---|---|
| Transform | parent | The transform the procedural panel is parented under. |
| GameObject | backgroundTemplate | The active theme's shared background prefab ( |
Returns
| Type | Description |
|---|---|
| UnityLeaderboardPanel | The configured (still title-less, row-less) panel. |
SetButtons(IReadOnlyList<PlacedElement>)
Stores the panel's authored buttons (already built and paired with their placement by
LeaderboardButtonFactory/UnityLeaderboardView) and applies them immediately; re-applied
automatically alongside the element placements by Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.ApplyStoredPlacements, so buttons
survive both rebuilding the rows and the table's own scroll-shell extent catching up, exactly like
the fixed elements do. Passing null or an empty list leaves any previously stored buttons displayed
but stops them from being re-applied on the next SetRows(IReadOnlyList<LeaderboardRowContent>, LeaderboardColumnLayout, GameObject)/ConfigureRowsScrolling(bool)
call.
Declaration
public void SetButtons(IReadOnlyList<LeaderboardPanelPlacementApplier.PlacedElement> buttons)
Parameters
| Type | Name | Description |
|---|---|---|
| IReadOnlyList<LeaderboardPanelPlacementApplier.PlacedElement> | buttons | Each built button's rect, paired with the placement to apply to it. |
SetEmptyState(bool, string, bool)
Shows or hides the empty-state holder, setting its message when shown. When translate
is true, message is treated as a localization key and the empty-state label gains
a UnityUiTMP_TextLocalizationUpdaterComponent (added on demand) that resolves it through
the localization service at runtime — mirrors SetTitle(string, bool).
Declaration
public void SetEmptyState(bool visible, string message, bool translate = false)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | visible | Whether the empty-state holder should be shown. |
| string | message | The message to display when |
| bool | translate | Whether |
SetRows(IReadOnlyList<LeaderboardRowContent>, LeaderboardColumnLayout, GameObject)
Rebuilds the rows table from layout's columns and rows' already-
formatted cells, through Serenity.Leaderboard.Infrastructure.Views.LeaderboardTableMapper and the table's own SetMatrix —
the only rebuild trigger it exposes, so a previous build's rows are always cleared first. An empty
board never renders a lone header row — with no data beneath it, it would render centered on top of
the empty-state message instead of a real column header (see Serenity.Leaderboard.Infrastructure.Views.LeaderboardTableMapper.ToMatrix(Serenity.Leaderboard.Infrastructure.Views.LeaderboardColumnLayout,System.Collections.Generic.IReadOnlyList{Serenity.Leaderboard.Infrastructure.Views.LeaderboardRowContent})).
Declaration
public void SetRows(IReadOnlyList<LeaderboardRowContent> rows, LeaderboardColumnLayout layout, GameObject labelTemplate)
Parameters
| Type | Name | Description |
|---|---|---|
| IReadOnlyList<LeaderboardRowContent> | rows | The already-formatted rows to display, in order. |
| LeaderboardColumnLayout | layout | The resolved column layout that determines each row's cells, sizing and alignment. |
| GameObject | labelTemplate | A themed label prefab instantiated for each row's cells, or |
SetTextStyle(UiThemeTextStyle)
Stores the theme's text style so every procedural TMP label this panel builds from now on picks it up, and retroactively applies it to the title/empty-state holders already built by CreateProcedural(Transform, GameObject) — which runs before a caller has any chance to call this method.
Declaration
public void SetTextStyle(UiThemeTextStyle style)
Parameters
| Type | Name | Description |
|---|---|---|
| UiThemeTextStyle | style | The theme's typeface and colour, or an unresolved style to leave today's font alone. |
Remarks
Only the procedural fallback's own holders are touched. A panel instantiated from a theme's
LeaderboardTemplate prefab already carries that theme's authored font on its title/empty-state
labels, and overwriting it here would fight the very theme this style was read from. Row cells are
unaffected by Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel._isProcedural: they are always built procedurally regardless of the
panel's own origin (see SetRows(IReadOnlyList<LeaderboardRowContent>, LeaderboardColumnLayout, GameObject)), so they pick up the stored style unconditionally the
next time they are built. The header holder is skipped for the same reason once
ApplyThemeTitleTemplate(GameObject) has swapped it for an instance of the theme's own
TitleTemplate prefab (Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel._headerUsesThemeTemplate): that instance already carries
the theme's authored font on its own label, and this retroactive sweep would stomp it the same way
it is already skipped for a non-procedural panel. The empty-state holder is unaffected — it has no
themed-template counterpart and always stays procedural.
SetTitle(string, bool)
Sets the header text, hiding the header holder when the title is empty. When
translate is true, title is treated as a localization key and
the header label gains a UnityUiTMP_TextLocalizationUpdaterComponent (added on demand)
that resolves it through the localization service at runtime — mirroring
UnityModalComponent.SetTitle. When false, the title is shown as literal text and no updater
is added (an existing one from a previous call is left in place but its translate-on-start flag is
cleared).
Declaration
public void SetTitle(string title, bool translate = false)
Parameters
| Type | Name | Description |
|---|---|---|
| string | title | The header text, or a localization key when |
| bool | translate | Whether |
TryResolveElementRect(LeaderboardViewElement, out RectTransform)
Resolves the rect a placement for element applies to: the header holder for
TITLE, the rows table's own root for ROWS (stable before any rows exist — the table
scrolls internally without ever swapping which GameObject ROWS resolves to), the empty-state
holder for EMPTY_STATE, and — for BACKGROUND — whatever
Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.ResolveBackgroundGameObject resolves, EXCEPT when that resolves to this panel's own
root (target == gameObject), which reports no rect at all. The root rect IS the whole panel,
so letting a placement move it would drag every other element along with it. Every panel this
MonoBehaviour builds itself (CreateProcedural(Transform, GameObject) included, since
Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.BuildProceduralBackgroundChild(UnityEngine.Transform,UnityEngine.GameObject)) resolves a real background child and so gets a rect
here; only a hand-authored panel with neither a wired Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel._backgroundGameObject slot nor a
child named Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.BackgroundChildName falls back to the root and reports none. Used by both
Serenity.Leaderboard.Infrastructure.Views.UnityLeaderboardPanel.ApplyStoredPlacements and the Leaderboard View Designer's hit-testing.
Declaration
public bool TryResolveElementRect(LeaderboardViewElement element, out RectTransform rect)
Parameters
| Type | Name | Description |
|---|---|---|
| LeaderboardViewElement | element | The element to resolve a rect for. |
| RectTransform | rect | The resolved rect, or null when the panel has no slot for it. |
Returns
| Type | Description |
|---|---|
| bool | Whether a rect was resolved. |