Settings menu
The module PulseSettings is a settings menu for the player settings of PulseFoundation. Every setting that a plugin or the game registers (a UPulsePlayerSettings class, a settings collection asset or code) shows up in it without UI code: tabs, sections, a row per setting, a detail panel, apply/revert, reset and key binding with conflict handling. It is built with CommonUI and opens on the PulseCore HUD.
How settings are registered, their sources, apply modes and conditions are described in the PulseFoundation player settings page.
Opening the menu
- Blueprint: Open Settings Screen (
UPulseSettingsLibrary::OpenSettingsScreen) with the local player controller. It pushes the screen class from the project settings on the configured HUD stack (defaultPulse.HUD.Stack.Main). - The menu needs the PulseCore HUD (
UPulseHUDSettings::bEnableHUD). Without it the function logs a warning and returns null. - Cheat:
PulseSettingsOpen.
Leaving the menu (Back button or the CommonUI back action) with pending changes (settings with apply mode OnApply, such as resolution) asks: Apply, Discard or Stay. Closing it in any other way (stack cleared, map change) drops pending changes.
Layout
| Part | Comes from |
|---|---|
| Tabs | The categories directly below Pulse.SettingCategory (Gameplay, Video, Audio, Controls, Interface, Accessibility, own ones). Tabs without visible settings are hidden. |
| Sections | Deeper categories (Pulse.SettingCategory.Interface.HUD is the section HUD of the tab Interface), shown as a header. |
| Rows | One UPulseSettingEntry per setting, in the order of the registry (sort order, then name). Rows are pooled. |
| Detail panel | Name and description of the hovered or focused row. |
Default widgets
The defaults live in /PulseCore/Settings/. Derive from them (or from the C++ classes) to restyle the menu; all logic is in C++, the Blueprints only hold the layout.
| Widget | Class | Job |
|---|---|---|
W_PulseSettingsScreen | UPulseSettingsScreen | The screen. |
W_PulseSettingEntry | UPulseSettingEntry | A row (every value type). |
W_PulseKeyCapture | UPulseKeyCaptureWidget | “Press a key” prompt on the modal stack. |
W_PulseSettingsButton | UPulseHUDTextButton | Button with text (footer, row controls), theme role Pulse.UI.Button.Secondary. |
W_PulseSettingsTab | UPulseHUDTextButton | Tab button (TabButtonClass), theme role Pulse.UI.Button.Tab. |
All defaults use Pulse Style roles of the UI theme (PulseFoundation), so the theme changes their look; buttons set their role with StyleRole (the Apply button Pulse.UI.Button.Primary, row arrows and Reset Pulse.UI.Button.Icon). Section headers use SectionTextStyle, or the theme role Pulse.UI.Text.Heading when it is empty, also after a theme change.
Screen (UPulseSettingsScreen)
Named widgets the screen binds (all optional except the first two):
| Name | Type | Use |
|---|---|---|
TabPanel | panel (horizontal or vertical box) | Receives the tab buttons (TabButtonClass, spacing TabPadding). |
EntryPanel | panel (vertical box) | Receives section headers (SectionTextStyle, SectionPadding) and rows. |
EntryScrollBox | scroll box | Scrolls the focused row into view. |
ApplyButton, RevertButton | common buttons | Enabled while there are pending changes. |
ResetButton | common button | Asks, then sets the settings of the shown tab back to their defaults. |
BackButton | common button | Same as the back action. |
DetailNameText, DetailDescriptionText | text blocks | Detail panel. |
RestartHint | any widget | Shown while pending changes need a restart. |
EmptyHint | any widget | Shown when no setting is registered. |
Class settings: EntryClass (row for every type), EntryClassOverrides (row class per value type, e.g. a color picker for Color), KeyCaptureClass, KeyCaptureStack, bManageInput / InputPriority (adds a menu input context through the input manager while the screen is open). Blueprint: GetSettings (the UMVVMPulseSettings view model), SelectTab, ApplyChanges, RevertChanges, ResetSelectedTab, RequestClose, ShowDetails, CaptureKey, event On Tab Selected.
Values that are not applied. Apply checks every pending value with its source first. A value the source does not take (an invalid key, a resolution it cannot parse) stays pending; a value whose source has nothing to write to, or that fails while it is written, is dropped. Both are reported: the screen shows a notification “Not applied” with the text of the result (GetLastApplyResult of the view model, details FPulseSettingsApplyReport), also after a reset of a tab. Leaving with Apply keeps the screen open while values are still pending, so the player can change them or choose Discard. The restart hint after Apply only appears when a written setting needs a restart. Key settings take an empty value or None as “unbound”. Assigning a key that another setting uses swaps both in one change (Pulse::Settings::Menu::AssignKey): when either value is refused, neither is written.
Row (UPulseSettingEntry)
One row class handles every value type: it shows the parts that fit the setting and collapses the others, so one Blueprint styles all rows.
| Name | Type | Shown for |
|---|---|---|
NameText, ValueText | text blocks | All (the value text is hidden when a button shows the value). |
PendingIndicator | any widget | Value changed but not applied yet. |
ResetButton | common button | Value differs from the default. |
ToggleButton | UPulseHUDTextButton | Bool: a click toggles, the text shows On/Off. |
Slider | slider | Int and Float with a range. |
PreviousButton, NextButton | common buttons | Options (previous/next option) and numbers without slider (one step). |
KeyButton | UPulseHUDTextButton | Key: a click asks for a new key, the text shows the key. |
Disabled settings (a condition with effect Disable) are shown disabled, hidden ones are collapsed. The event On Setting Refreshed runs after every change, for own parts. GetSetting returns the UMVVMPulseSetting of the row.
Key bindings
A click on KeyButton pushes W_PulseKeyCapture on the modal stack. The next key, mouse button or gamepad button is taken (bAllowMouseButtons, bAllowGamepadKeys); CancelKeys (Escape and the gamepad menu button by default) and the back action cancel. If another key setting already uses the key, the menu asks whether to swap the keys, so both stay bound. In code: Pulse::Settings::Menu::FindKeyConflict and AssignKey.
Project settings
Project Settings > Pulse > Core > Settings Menu (UPulseSettingsMenuSettings):
| Setting | Default | Meaning |
|---|---|---|
ScreenClass | W_PulseSettingsScreen | Screen that Open Settings Screen opens. |
StackTag | Pulse.HUD.Stack.Main | HUD stack the screen is pushed on. |
Input
- Back (Escape, gamepad) goes through the CommonUI back action. The project needs CommonUI input data with a back action (Project Settings > Common Input), otherwise CommonUI logs “Cannot create action binding … no action provided” and only the Back button closes the menu. The same applies to PulseCore modals.
- With the input manager enabled (
UPulseHUDSettings::bEnablePlayerInputManager), the screen adds a menu context (cursor shown, UI input) while it is open. - Gamepad: rows focus their control (toggle, slider, next button, key button); the scroll box follows the focus.
Cheats
| Cheat | Does |
|---|---|
PulseSettingsOpen | Opens the settings screen. |
PulseSettingsList | Prints every player setting with value, type and who registered it. |
PulseSettingsSet <setting> <value> | Changes a setting like the menu would (pending for OnApply settings), e.g. PulseSettingsSet Pulse.Setting.HUD.ShowCompass false. |
In the editor, Pulse.PIE.Exec <instance> <command> (PulseFoundation) runs them as the player of a PIE instance.
Tests
PulseSettings.Keys: finding a key that is already used, assigning, swapping.