How-To: Performance Stat Widgets

Goal: an FPS/ping readout with optional graph, grouped in a container that shows/hides each stat from a settings value.

You supply the data
The widgets are display shells. FetchStatValue returns 0.0 until you override it - there is no built-in sampler in CrimsonUI or CrimsonCommon. Wire it to your own telemetry (or engine queries like GAverageFPS / GetNetDriver()->GetPing()).

1. One widget per stat

Subclass Crimson Perf Stat Widget Base (UCrimsonPerfStatWidgetBase, a passive UCommonUserWidget). Set StatToDisplay (an ECrimsonDisplayablePerformanceStat from CrimsonCommon - ClientFPS, ServerFPS, FrameTime, FrameTime_GameThread, FrameTime_RenderThread, FrameTime_RHIThread, FrameTime_GPU, Ping, PacketLoss_Incoming/Outgoing, PacketRate_Incoming/Outgoing, PacketSize_Incoming/Outgoing, Latency_Total/Game/Render, IdleTime). Override Fetch Stat Value (BlueprintNativeEvent, returns double) to produce the number, and drive your TextBlock from it (e.g. a property binding or a timer).

Screenshot pendingImages/CrimsonUI/howto-perfstat-widget-bp.png
WBP_StatFPS (parent: Crimson Perf Stat Widget Base): Class Defaults Stat To Display = ClientFPS; Graph overrides Fetch Stat Value returning the FPS sample; a bound TextBlock formats it.

For a graph, add a Crimson Perf Stat Graph (UCrimsonPerfStatGraph) named PerfStatGraph (optional BindWidget) and call UpdateGraphData(ScaleFactor) (BlueprintCallable) whenever you sample; GraphLineColor, GraphBackgroundColor, and GraphMaxYValue style it.

Verify
The number updates in PIE. If it reads 0.0 forever, your Fetch Stat Value override is not being hit - check the function override list.

2. Group stats in a container

Put the stat widgets inside a subclass of Crimson Perf Stat Container Base (UCrimsonPerfStatContainerBase). On construct (and whenever you call UpdateVisibilityOfChildren), it asks GetStatDisplaySetting(Stat) for every child stat widget and applies the returned ECrimsonStatDisplayMode:

ModeEffect
HiddenWidget collapsed
TextOnlyShown when the container's StatDisplayModeFilter includes text
GraphOnlyShown for the graph variant
TextAndGraphAlways shown (default when you do not override)

Override Get Stat Display Setting (BlueprintNativeEvent) to read your project's user settings - e.g. a CrimsonSettings keyed value per stat - and call Update Visibility Of Children when the player changes them. Duplicate the container with different StatDisplayModeFilter values to build separate text-column and graph-column layouts from the same setting.

Verify
Toggling your setting between Hidden/TextOnly/TextAndGraph shows and hides each stat widget accordingly after Update Visibility Of Children runs.

See also

  • CrimsonSettings wiki - a keyed settings store that pairs naturally with GetStatDisplaySetting.