You want the game window a bit smaller. It runs heavy, so you want lower quality. You want the music a little quieter. A settings screen is where players choose the state that suits them.
But placing dropdowns and sliders does not change the game's settings. The screen's job extends to applying the value chosen in the UI and being able to restore it on the next launch .
This article builds a small three-item settings screen using Game User Settings for display and a SaveGame for music volume.

What You'll Learn
- Why display settings and volume are saved in different places
- What Set and Apply each change
- How to apply and save Game User Settings
- How to confirm settings survive a relaunch
What We Build
- Choosing window size and quality and applying them with "Apply and save"
- Comparing music volume with a slider and saving it from the same button
- Relaunching the game and confirming display settings and volume come back
This assumes you have created Blueprint variables and functions and know the Widget placement and button events from UMG Basics. The hands-on is a Windows Standalone Game exercise showing the settings screen from launch.
- Display settings and volume save to different places
- What Set and Apply each change
- Choosing window size and quality
- Hands-On 1: display the settings screen
- Hands-On 2: apply the display settings
- Hands-On 3: change and save the music volume
- Relaunch and confirm
- Bonus: building it into your own game
- Summary
Display settings and volume save to different places
Game User Settings is UE's standard settings object holding resolution, display mode, quality, and more. In Blueprint you fetch it with Get Game User Settings . You do not create one; pass the returned object to each setting node's Target.
Saving display settings normally writes to a settings file called GameUserSettings.ini , which the game loads at launch. You avoid building a resolution SaveGame class or your own file I/O from scratch.
The standard Game User Settings, however, has no "music volume" entry. For that we prepare our own variable and save it to a SaveGame , a container whose contents you decide.
| What we want to keep | What it applies to | Where it is saved |
|---|---|---|
| Window size and quality | Game User Settings | GameUserSettings.ini |
| Music volume | The playing Audio Component | A volume SaveGame |
The same "Apply and save" button calls both save paths. One settings screen visually does not mean everything saves to the same place.
An Audio Component controls a playing sound. To change our music's volume, we specify that component.

Progress data can use SaveGame too, but keeping volume separate from adventure save slots is easier to handle. Starting a new game then carries over the volume the player chose.
What Set and Apply each change
Display settings split into specifying values and applying those values to the game .
| Node | What it does |
|---|---|
Set Screen Resolution , etc. | Changes a value held by Game User Settings |
Apply Settings | Applies the settings to the game and saves them |
Save Settings | Saves the setting values. Also called inside Apply Settings |
Passing 1280 x 720 to Set Screen Resolution does not finish switching the window to that size. Call Apply Settings at the end.
Apply Settings both applies and saves. There is no need to add Save Settings right after it. Apply Settings official reference, Save Settings official reference
Here we keep display settings in dropdowns and call Set and Apply together when "Apply and save" is pressed. That avoids the screen switching repeatedly while choosing.

Choosing window size and quality
Match the display mode, not just the resolution
Resolution is the pixel width and height drawn. 1280 x 720 is 1280 across and 720 down. In Blueprint you use an Int Point grouping two integers, with X for width and Y for height.
At the same resolution, the display mode changes how it looks.
| Mode | How it uses the screen |
|---|---|
| Windowed | A framed window. What we use for size changes |
| Windowed Fullscreen | A frameless window using the whole desktop |
| Fullscreen | Fullscreen. Supported resolutions and switching depend on the environment |
What we want to see is the difference between 800 x 600 and 1280 x 720 windows. So when changing size, we specify Windowed with Set Fullscreen Mode . Do not expect a smaller frame while staying in Windowed Fullscreen.

Quality can change several settings at once
Scalability adjusts quality such as shadows and draw distance, balancing looks against processing cost. Set Overall Scalability Level switches several settings at once.

| Value | Level | Our option |
|---|---|---|
| 0 | Low | Low |
| 1 | Medium | Medium |
| 2 | High | High |
| 3 | Epic | Epic |
| 4 | Cinematic | Not added here |
Meanwhile, Get Overall Scalability Level can return -1 when settings were adjusted individually. That is not an error; it means "not every item is on the same level".
So we put "Do not change" first in the dropdown. Not choosing a quality leaves individual settings and Cinematic alone. That prevents changing quality wholesale while only meaning to save volume.
Hands-On 1: display the settings screen
Build the practice screen
Save a Third Person template level under the name L_SettingsPractice . So you can test both window sizes, work with a desktop of at least 1600 x 900 where the candidate windows fit. If they do not fit, shrink the size options below.
Create WBP_SettingsPractice with User Widget as its parent. Place a Canvas Panel in the Designer and arrange these elements under it.
Canvas Panel
└─ Size Box
└─ Border
└─ Vertical Box
├─ Text "Settings"
├─ Text "Window size"
├─ Combo Box (String) "ResolutionCombo"
├─ Text "Quality"
├─ Combo Box (String) "QualityCombo"
├─ Text "Music volume (move to preview)"
├─ Slider "VolumeSlider"
├─ Button "ApplyButton"
│ └─ Text "Apply and save"
├─ Text "CurrentSettingsText"
└─ Text "StatusText"
The Size Box's Canvas slot uses center Anchors, Alignment 0.5 / 0.5 , Position 0 / 0 , and Auto Size on. Turn on the Size Box's Width Override at 520 and leave Height Override off. The Border is white with Padding 24 .
Text is navy, with the heading at Font Size 28 and other Text at 18 . Each element in the Vertical Box fills horizontally with vertical Padding 4 . The Text inside ApplyButton is centered with Padding 10 . Turn on Auto Wrap Text on the last two Texts so long strings wrap. Leave their initial text empty.
Set ApplyButton's Style Normal Tint to blue with only the button's Text in white. Set both Combo Boxes to Font Size 18 with navy Foreground Color.
Turn Is Variable on for the two named Combo Boxes, the Slider, the Button, and the last two Texts. That lets you drag them into the graph to read values and rewrite displays.

The diagram shows the display once the logic is finished. The last two Texts can be empty for now.
Register the options in this order
A Combo Box (String) picks one string from a list of candidates. Add them to Details' Default Options in this order. Set Selected Option to Do not change on both.
| Index | ResolutionCombo | QualityCombo |
|---|---|---|
| 0 | Do not change | Do not change |
| 1 | 800 x 600 | Low |
| 2 | 1280 x 720 | Medium |
| 3 | — | High |
| 4 | — | Epic |
An Index is the candidate number, starting at 0. We use this ordering later to decide "index 2 means 800 x 600". Do not add the "—" entries in the left column.
Set VolumeSlider's Min Value to 0 , Max Value to 1 , and Value to 0.5 . Leave Is Enabled off initially and turn it on once the music is ready.
Show it at level start
In L_SettingsPractice's Level Blueprint, wire from Event BeginPlay in this order. Get Player Controller uses Player Index 0 .
| Order | Node | Connection / setting |
|---|---|---|
| 1 | Create Widget | Class = WBP_SettingsPractice, Owning Player = Get Player Controller's Return Value |
| 2 | Add to Viewport | Target = Create Widget's Return Value |
| 3 | Set Input Mode UI Only | Player Controller = Get Player Controller, In Widget to Focus empty, Mouse Lock = Do Not Lock |
| 4 | Set Show Mouse Cursor | Target = Get Player Controller, value on |
The white exec order follows the table. Split Get Player Controller's blue output to the three places named.

Displaying it alone does not make it operable. Change the input destination too.

This exercise operates the settings screen with the mouse, so the Input Mode is UI Only. It is the combination of switching not only display but the input destination to the UI and showing the cursor.
Set the "Play" method to Standalone Game and start. If the dropdowns open and the button is clickable, the screen is ready. Choosing options does not change display settings yet. Close the game window when you are done.
Hands-On 2: apply the display settings
From here we work in WBP_SettingsPractice's Graph.
Create a variable VideoSettings typed Game User Settings Object Reference with default None. A reference names the same settings object later.
From Event On Initialized, wire white exec through Get Game User Settings → Set VideoSettings . Pass Get Game User Settings' Return Value to Set VideoSettings' value. On Initialized is called once when this Widget's instance initializes. Our screen is created exactly once at level start.

What the "to the next diagram" label leads to is displaying the current values and loading the volume. Build up to here first and connect them after building each piece.
Split the apply logic into three stages
Create an argument-less function ApplyPracticeVideo and connect a Sequence from its entry. Use Add pin to reach Then 2.
Sequence advances through Then 0, then Then 1, then Then 2. We use no waiting logic here, so the order is "size → quality → apply at the end".

Then 0: change window size only when chosen
Get Get Selected Index from ResolutionCombo's Get. Pass that integer to Switch on Int 's Selection and wire Then 0's white line to the Switch. Provide outputs 0, 1, and 2.
Switch on Int continues to the exec output matching the number it receives. Here it splits size settings by dropdown index.
| Switch output | What to connect |
|---|---|
| 0 / Default | Nothing |
| 1 | Set Screen Resolution with Make Int Point (X=800, Y=600) → Set Fullscreen Mode (Windowed) |
| 2 | Set Screen Resolution with Make Int Point (X=1280, Y=720) → Set Fullscreen Mode (Windowed) |
Place a Set Screen Resolution and a Set Fullscreen Mode on both the 1 and 2 sides. Target on both is VideoSettings. Creating them by dragging from Get VideoSettings makes the target hard to get wrong.
Even with nothing connected to 0, the Sequence continues to Then 1. Values like -1 when nothing is selected go to Default, continuing without changing size.

The right edge of the diagram explains where each output goes. You do not create a "do not change" node.

Specify the window format along with the resolution.

Then 1: set quality in bulk only when chosen
Get Get Selected Index from QualityCombo and pass it to In Range (Integer) with Min 1 , Max 4 , and both Inclusive Min / Max on. It checks "is the number within 1 to 4".

From Then 1, continue to a Branch with In Range's Boolean output into Condition. A Boolean is true or false, here meaning "inside the range or not".
- True: call
Set Overall Scalability Levelwith Target = VideoSettings and Value = the selected Index minus1 - False: do nothing

"Low" is Index 1, but the quality value passed to UE is 0. An integer subtraction resolves that off-by-one. "Do not change" is outside the range, so Set is never called.

Then 2: apply and save together
Call Apply Settings from Then 2 with Target VideoSettings and Check for Command Line Overrides off. That input decides whether launch-time command specifications take priority; the exercise uses what you chose on screen.
Now, whether you chose a size and quality or left both at "Do not change", you reach one Apply Settings at the end. Do not add Save Settings.
Wire it to the button and test small
Add On Clicked from ApplyButton in the Designer and call Apply Practice Video (Target = Self). Connect a Print String after it showing Video settings applied .
Compile, save, and start in Standalone. Alternate between 800 x 600 and 1280 x 720 and press "Apply and save". A changing window size means the chain from UI to display settings works.
Switch quality between "Low" and "High". Shadow changes depend on the scene, so do not judge by looks alone; prepare the display below too.
Show the current settings on screen
Create an argument-less function RefreshPracticeStatus . From Get VideoSettings, fetch Get Screen Resolution and Get Overall Scalability Level.
Split Get Screen Resolution's return value into X and Y with Break Int Point . Convert the quality integer into a display name as follows.
- Add integer
1to Get Overall Scalability Level's value. Individual settings' -1 becomes 0 and Low's 0 becomes 1. - Pass that to a
Selectnode's Index. Use Add pin to reach six options and set the output type to Text. - Enter
Individual / Low / Medium / High / Epic / Cinematicfrom Option 0 onward.
Select returns one value corresponding to a number. Unlike a Switch, which routes execution, here it chooses the text to display.

Enter Current: {W} x {H} / Quality {Q} into Format Text 's Format and pass X to W, Y to H, and Select's Return Value to Q. Format Text fills values into the braces.

From the function entry, call CurrentSettingsText's Set Text and pass Format Text's Result to In Text.

Call RefreshPracticeStatus from two places.
- After Set VideoSettings in Event On Initialized
- After Apply Settings in ApplyPracticeVideo's Then 2

The dropdowns returning to "Do not change" at launch does not mean settings were lost. The dropdowns above are what you are about to change and the Text below is the settings currently held.
Hands-On 3: change and save the music volume
With display settings working, add music. Here we change the volume of one music track playing on the settings screen, not a game-wide master volume.
1. Prepare looping music
Drag a WAV file into the Content Browser to import it as a Sound Wave. Right-click that asset, choose Create Cue, and name the resulting Sound Cue SC_SettingsPracticeBGM . A Sound Cue assembles which sound plays and how.
Open the Sound Cue and connect the Wave Player with your audio to Output. Turn Looping on in the Wave Player's Details. Confirm it repeats in the preview and save.
So it can return from volume 0, set the Sound Cue's Virtualization Mode to Play When Silent , which keeps playback running while silent. We later lower the slider to 0 and raise it again.
2. Build the container that saves the volume
Create a Blueprint SG_SettingsPracticeAudio with SaveGame as its parent class. Add a Float variable BGMVolume with default 0.5 , then compile and save.
Float handles decimals such as 0.5. We use it to vary volume finely between 0 and 1.
Add these two variables to WBP_SettingsPractice as well.
| Variable | Type | Default |
|---|---|---|
| AudioPreferences | SG_SettingsPracticeAudio Object Reference | None |
| PreviewAudio | Audio Component Object Reference | None |
AudioPreferences is the container holding the saved value and PreviewAudio is the reference controlling the sound actually playing. The value you save and the sound you are playing are handled separately even at the same volume.
Standardize the save location name as SettingsPracticeAudio with User Index 0 . A Slot Name identifies saved data. A single character differing between saving and loading means looking for different data.
3. Prepare defaults first, then read back if saved
Create argument-less functions LoadPracticeAudio and StartPracticeAudio and compile once.
Build LoadPracticeAudio in this order.
- Set
Create Save Game Object's Save Game Class to SG_SettingsPracticeAudio. - Pass Return Value to Set AudioPreferences' value. Also wire white exec from Create to Set.
- Then call
Does Save Game Existwith Slot Name SettingsPracticeAudio and User Index 0. - Wire its exec output to a Branch and its Return Value to Condition.

On the Branch's False, call StartPracticeAudio (Target = Self) directly. With no saved data on the first run, we use the default 0.5 we just created.

On True, call Load Game from Slot with the same Slot Name and User Index. Pass its Return Value to Cast To SG_SettingsPracticeAudio 's Object and wire white exec into the Cast.
The Cast checks whether the loaded data can be treated as our SG_SettingsPracticeAudio. On success you can read its BGMVolume.
On a successful Cast, pass As SG Settings Practice Audio to Set AudioPreferences and then call StartPracticeAudio. That replaces the default container with the saved one.
On Cast Failed, Print String Audio preferences could not be loaded and then call StartPracticeAudio. Even when the read fails, the screen works with the initial 0.5.

4. Start playback at the loaded volume
Inside StartPracticeAudio, get Get BGMVolume from Get AudioPreferences and pass it to Clamp (Float) with Min 0 and Max 1. Clamp keeps a value in range, matching the slider's range here.

Wire white exec in this order.
| Order | Node | Connection / setting |
|---|---|---|
| 1 | VolumeSlider's Set Value | In Value = Clamp's Return Value |
| 2 | Spawn Sound 2D | Sound = SC_SettingsPracticeBGM, Volume Multiplier = the same Clamp Return Value, Pitch 1, Start Time 0, Persist Across Level Transition off, Auto Destroy on |
| 3 | Set PreviewAudio | Value = Spawn Sound 2D's Return Value |
| 4 | VolumeSlider's Set Is Enabled | In Is Enabled = on |
Spawn Sound 2D starts the sound and returns an Audio Component for controlling it. Passing the saved volume from the start avoids a burst of loud audio right after launch. Spawn Sound 2D official reference

Keep the sound you started so you can change its volume later.

Finally, connect LoadPracticeAudio after RefreshPracticeStatus in Event On Initialized. The launch order is "fetch and display display settings → load the volume → play music".

5. Move the slider and compare
Add VolumeSlider's On Value Changed. Wire the event's white exec output to the exec-pin Is Valid with Get PreviewAudio as Input Object.
From the Is Valid side, call Set Volume Multiplier with PreviewAudio as Target and On Value Changed's Value as New Volume Multiplier. Do nothing on Is Not Valid. That avoids operating on a nonexistent Audio Component if the value changes during initialization before playback starts.

Start in Standalone and move the slider. 1 is the original volume multiplier and 0.5 is half of it. That does not mean the perceived loudness is exactly half.
There is no save logic yet, so relaunching returns to the default. Next we keep the chosen volume too.
6. Save the volume from the same button
Create an argument-less function SavePracticeAudio .
From Get AudioPreferences' blue output create Set BGMVolume , passing VolumeSlider's Get Value as the value. The Set's Target is AudioPreferences. You do not create a same-named variable on the Widget.

Connect Save Game to Slot after it with Save Game Object AudioPreferences, Slot Name SettingsPracticeAudio, and User Index 0. Wire its exec output to a Branch and its Return Value to Condition.

| Branch | What to do |
|---|---|
| True | Set StatusText to "Applied display settings. Music volume saved." |
| False | Set StatusText to "Display settings applied. Saving music volume failed." |
That Return Value tells you whether the volume SaveGame saved. It is not a value judging Apply Settings' overall save success.

Make ApplyButton's On Clicked run Apply Practice Video → Save Practice Audio . Remove the earlier Print String. Display settings save via Apply Settings and volume via Save Game to Slot.

Relaunch and confirm
Compile, save, and launch Standalone Game. Our saved data is meant to persist into the next session, so verify accordingly.
| Action | Expected result |
|---|---|
| Set size to 1280 x 720 and quality to High, then apply | The window resizes and the current display reads 1280 x 720 and High |
| Lower the volume a little and press Apply and save | The music gets quieter and the volume save result appears |
| Lower the volume to 0 and raise it again | Sound returns from silence. If it does not, check the Sound Cue's Play When Silent |
| Close the game window and run the same exercise again | The launch settings persist and the music starts at the saved volume |
| Set size and quality to "Do not change" and save only volume | Display settings are not changed wholesale while volume updates |
| Change the volume to preview it and close without saving | The next launch returns to the last saved volume |
The point is watching the applied result and the next launch, not just how the settings fields look . After confirming in Standalone, verify the same round trip in a packaged build. Editor launch settings and command-line specifications can affect window size too.

When it does not work
| Symptom | Where to check |
|---|---|
| The settings screen is visible but not clickable | UI Only, Show Mouse Cursor, and elements' Is Enabled |
| The size does not change | Whether you run Standalone, whether you set Windowed, whether Then 2 reaches Apply Settings |
| The quality level is off by one | Whether you subtract 1 from the Combo's Index |
| Changing only volume also changes quality | Whether Set Overall Scalability Level is called only for Index 1 to 4 |
| No music | The Sound Cue preview alone, Spawn Sound 2D's Sound, the saved volume, whether Load continues to StartPracticeAudio |
| Moving the slider does not change the sound | Whether Set Volume Multiplier's Target is PreviewAudio and whether Value is connected |
| The volume does not persist | Set BGMVolume's Target, Save Game Object, and the Slot Name and User Index on save and load |
| The dropdown reads "Do not change" and settings look lost | Check current values in CurrentSettingsText. The dropdowns choose what to change next |
Bonus: building it into your own game
Adding more resolution options. Our fixed two options are for practicing window sizes. In a product, prepare options matching your target environments and display modes. Get Supported Fullscreen Resolutions is a starting point for fullscreen and Get Convenient Windowed Resolutions for windowed. Also handle empty candidate arrays, a current value not among the candidates, and an unselected Index of -1.
A confirmation screen for reverting. If you also offer Fullscreen, asking "keep these settings?" and reverting on a timeout makes it easier to recover control. Apply Settings also saves, so design the revert path to apply and save the previous values too.
Volume beyond music. We control one PreviewAudio here. To adjust several music tracks and sound effects together, group sounds with Sound Classes and control them with Sound Mix or Audio Modulation. The idea of separating the saved value from applying it to actual sound stays the same.
Extending to an in-game settings menu. We create the Widget once at level start. To turn it into an openable menu, move music playback outside the screen so the same track does not stack each time you open it. For restoring input and cursor on close, the pause menu article is the continuation.
The scale of your save logic. Our SaveGame holds one volume value, so we used the normal blocking save and load. If you handle large progress data at the same time, consider asynchronous saving. See Epic's saving and loading your game for details.
Summary
Display settings pass values into Game User Settings and Apply Settings applies and saves them. Music volume applies to the playing Audio Component, and the value kept in a SaveGame is read back on the next launch.
Start by changing the window size and music volume and closing the game. If it comes back the way you chose, you have moved from "UI you can merely pick things in" to a settings screen that actually tunes playability.
Reference: Overall scalability values, Quality value with individual settings, Sound Cue and looping, Save Game to Slot
To extend the settings screen to multiple languages, move on to switching languages with the Localization Dashboard.