diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/pause-unstyled.png b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/pause-unstyled.png
index 3a592da4..aea789bb 100644
Binary files a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/pause-unstyled.png and b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/pause-unstyled.png differ
diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/title-unstyled.png b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/title-unstyled.png
index 9e4ad987..a4131a1f 100644
Binary files a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/title-unstyled.png and b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/images/title-unstyled.png differ
diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/index.md b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/index.md
index 8c34fbd6..5ba3c318 100644
--- a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/index.md
+++ b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/index.md
@@ -37,7 +37,7 @@ Gum addresses these challenges with ready-made solutions, allowing us to focus o
> [!IMPORTANT]
> This tutorial uses the Gum NuGet package to help with layout and responding to user interactions. This tutorial does not require the use of the Gum editor, we will be doing everything in code.
>
-> Keep in mind, that while it is possible to build a full UI system without any external dependencies, creating a layout engine is complicated and beyond the scope of this tutorial. Instead, we will be taking advantage of the Gum NuGet package.
+> Keep in mind that while it is possible to build a full UI system without any external dependencies, creating a layout engine is complicated and beyond the scope of this tutorial. Instead, we will be taking advantage of the Gum NuGet package.
>
> Gum is a powerful system enabling the creation of virtually any game UI, and we will be covering some of the basics of its use in this tutorial. The full Gum documentation can be found here: [https://docs.flatredball.com/gum/code/monogame](https://docs.flatredball.com/gum/code/monogame)
@@ -321,7 +321,7 @@ To add the Gum NuGet package in Visual Studio Code:
2. Choose `Add NuGet Package` from the context menu.
3. Enter `Gum.MonoGame` in the `Add NuGet Package` search prompt and press Enter.
4. When the search finishes, select the `Gum.MonoGame` package in the results
-5. When prompted for a version choose version `2025.5.1.1`.
+5. When prompted for a version choose version `2025.8.3.3`.
#### [Visual Studio 2022](#tab/vs2022)
@@ -332,7 +332,7 @@ To Add the Gum NuGet package in Visual Studio 2022:
3. In the NuGet Package Manager window, select the `Browse` tab if it is not already selected.
4. In the search box, enter `Gum.MonoGame`.
5. Select the "Gum.MonoGame" package from the search results.
-6. On the right, in the version dropdown, select version `2025.5.1.1` and click the "Install" button.
+6. On the right, in the version dropdown, select version `2025.8.3.3` and click the "Install" button.
#### [dotnet CLI](#tab/dotnetcli)
@@ -342,7 +342,7 @@ To add the Gum NuGet package using the dotnet CLI:
2. Enter the following command:
```sh
- dotnet add DungeonSlime.csproj package Gum.MonoGame --version 2025.5.1.1
+ dotnet add DungeonSlime.csproj package Gum.MonoGame --version 2025.8.3.3
```
---
@@ -351,11 +351,11 @@ To add the Gum NuGet package using the dotnet CLI:
> You can verify the package was successfully added by examining your `DungeonSlime.csproj` file, which should now contain a reference like:
>
> ```xml
->
+>
> ```
> [!IMPORTANT]
-> This tutorial uses version `2025.5.1.1` of Gum, which is the latest version of Gum as of this writing. That exact version is specified to use in the section above when installing the NuGet package to ensure compatibility throughout this tutorial. If there are newer versions of Gum available, please consult the [Gum documentation](https://docs.flatredball.com/gum/gum-tool/breaking-changes) before updating in case there are any breaking changes from the code that is presented in this tutorial.
+> This tutorial uses version `2025.8.3.3` of Gum, which is the latest version of Gum as of this writing. That exact version is specified to use in the section above when installing the NuGet package to ensure compatibility throughout this tutorial. If there are newer versions of Gum available, please consult the [Gum documentation](https://docs.flatredball.com/gum/gum-tool/upgrading) before updating in case there are any breaking changes from the code that is presented in this tutorial.
### Adding UI Sound Effect
@@ -385,7 +385,7 @@ With the Gum NuGet package added to our project, we need to initialize Gum in ou
First, open the `Game1.cs` file and add the following new using statements to the top:
-[!code-csharp[](./snippets/game1/usings.cs?highlight=4-5)]
+[!code-csharp[](./snippets/game1/usings.cs?highlight=2-5)]
Next, add the following method to the `Game1` class to encapsulate the initializations of the Gum UI service:
@@ -397,10 +397,10 @@ Finally, update the [**Initialize**](xref:Microsoft.Xna.Framework.Game.Initializ
The following is a breakdown of this initialization process:
-1. **Basic Initialization**: `GumService.Default.Initialize(this)` sets up the Gum system with our game instance. This is required for any gum project.
+1. **Basic Initialization**: `GumService.Default.Initialize(this, DefaultVisualsVersion.V2)` sets up the Gum system with our game instance. This is required for any gum project. The second parameter specifies the default visual styling. V2 is the latest version which makes it easy to style the default controls.
> [!NOTE]
- > We only need to pass our [**Game**](xref:Microsoft.Xna.Framework.Game) instance since we are using Gum as a code-first approach. Gum also offers a visual editor that creates Gum project files. When using the editor, you will need to also pass the Gum Project file here.
+ > We only need to pass our [**Game**](xref:Microsoft.Xna.Framework.Game) instance and the visuals version since we are using Gum as a code-first approach. Gum also offers a visual editor that creates Gum project files. When using the editor, you will need to also pass the Gum Project file to `Initialize`. For more information on how to use the Gum visual editor, see the [Gum Project Forms Tutorial](https://docs.flatredball.com/gum/code/monogame/tutorials/gum-project-forms-tutorial).
2. **Content Loading**: Gum needs to be made aware of which content manager to use to load assets through the content pipeline. By setting `GumService.Default.ContentLoader.XnaContentManager = Core.Content`, we tell Gum to use our game's content manager when loading assets. By using the game's existing content manager, Gum also gets the benefit of the caching that the content manager performs when loading assets.
3. **Input Configuration**:
diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/initializegum.cs b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/initializegum.cs
index 53a7cca5..1090962a 100644
--- a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/initializegum.cs
+++ b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/initializegum.cs
@@ -1,7 +1,9 @@
private void InitializeGum()
{
- // Initialize the Gum service
- GumService.Default.Initialize(this);
+ // Initialize the Gum service. The second parameter specifies
+ // the version of the default visuals to use. V2 is the latest
+ // version.
+ GumService.Default.Initialize(this, DefaultVisualsVersion.V2);
// Tell the Gum service which content manager to use. We will tell it to
// use the global content manager from our Core.
diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/usings.cs b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/usings.cs
index 6b518e38..a4dc924c 100644
--- a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/usings.cs
+++ b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/game1/usings.cs
@@ -1,5 +1,6 @@
using DungeonSlime.Scenes;
-using Microsoft.Xna.Framework.Media;
+using Gum.Forms;
+using Gum.Forms.Controls;
using MonoGameLibrary;
using MonoGameGum;
-using MonoGameGum.Forms.Controls;
\ No newline at end of file
+using Microsoft.Xna.Framework.Media;
\ No newline at end of file
diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/gamescene/usings.cs b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/gamescene/usings.cs
index 1ed2b803..78dbca4b 100644
--- a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/gamescene/usings.cs
+++ b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/gamescene/usings.cs
@@ -6,7 +6,7 @@
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoGameGum;
-using MonoGameGum.Forms.Controls;
+using Gum.Forms.Controls;
using MonoGameGum.GueDeriving;
using MonoGameLibrary;
using MonoGameLibrary.Graphics;
diff --git a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/titlescene/usings.cs b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/titlescene/usings.cs
index 228e8dc1..1559f9f5 100644
--- a/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/titlescene/usings.cs
+++ b/articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/titlescene/usings.cs
@@ -4,7 +4,7 @@
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoGameGum;
-using MonoGameGum.Forms.Controls;
+using Gum.Forms.Controls;
using MonoGameGum.GueDeriving;
using MonoGameLibrary;
using MonoGameLibrary.Scenes;
\ No newline at end of file
diff --git a/articles/tutorials/building_2d_games/21_customizing_gum_ui/index.md b/articles/tutorials/building_2d_games/21_customizing_gum_ui/index.md
index 346405f6..02129cee 100644
--- a/articles/tutorials/building_2d_games/21_customizing_gum_ui/index.md
+++ b/articles/tutorials/building_2d_games/21_customizing_gum_ui/index.md
@@ -182,7 +182,11 @@ Now that we have all our resources prepared, we can create custom versions of th
### The AnimatedButton Class
-Our first custom component will be an `AnimatedButton` that inherits from Gum's base `Button` class. This button will use the game's existing texture atlas for its visual appearance and provide animation when focused.
+Our first custom component is an `AnimatedButton` that inherits from Gum's base `Button` class. This button uses the game's existing texture atlas for its visual appearance and animates when focused.
+
+By default all Gum components provide a Visual property which can be cast to a type specific to the particular control. By convention the visual type is named the same as the component with the word `Visual` appened. For example, we will be casting the AnimatedButton's Visual property to `ButtonVisual` to access button-specific properties.
+
+This new `AnimatedButton` class casts the Visual property to `ButtonVisual` and modifies the button-specific properties such as background and text.
First, in the *DungeonSlime* project (your main game project), create a new folder named `UI` to store our custom UI components. Next, in that `UI` folder, create a new file called `AnimatedButton.cs` and add the following code to it:
@@ -190,21 +194,29 @@ First, in the *DungeonSlime* project (your main game project), create a new fold
Next, we will examine the key aspects of this new `AnimatedButton` implementation:
-#### Top-level Container
+#### ButtonVisual
-Every customized control needs a top-level container to hold all visual elements. For our button, we create a `ContainerRuntime` that manages the button's size and contains all other visual elements:
+As mentioned earlier, we first access the `Visual` object and cast it to a `ButtonVisual`. Doing so gives us access to button-specific properties including individual elements (such as the text and background visuals) as well as the states that are applied when the button is hovered or pressed.
-[!code-csharp[](./snippets/animatedbutton.cs?start=26&end=32)]
+We can modify the Visual to give it the appropriate size.
-The `WidthUnits` property set to `RelativeToChildren` means the container will automatically size itself based on its child elements, with 21 pixels of additional space. This allows the button to adapt its size depending on the text content.
+[!code-csharp[](./snippets/animatedbutton.cs?start=30&end=35)]
+
+The `WidthUnits` property set to `RelativeToChildren` means the container automatically sizes itself based on its child elements, with 21 pixels of additional space. This allows the button to adapt its size depending on the text content.
#### Nine-slice Background
-We use a `NineSliceRuntime` for the button's background. A nine-slice is a special graphic that can be stretch while preserving its corners and edges:
+`ButtonVisual` provides a `Background` which we can modify. This is of type `NineSliceRuntime` which is a special graphic that can be stretch while preserving its corners and edges:
+
+[!code-csharp[](./snippets/animatedbutton.cs?start=39&end=42)]
-[!code-csharp[](./snippets/animatedbutton.cs?start=34&end=41)]
+The `TextureAddress` property is set to `Custom` so we can specify exactly which portion of the atlas texture to use, while `Dock(Dock.Fill)` ensure the background fills the entire button area. The portion of the atlas is assigned using AnimationChains, which are discussed later in this tutorial.
-The `TextureAddress` property is set to `Custom` so we can specify exactly which portion of the atlas texture to use, while `Dock(Dock.Fill)` ensure the background fills the entire button area.
+#### Text
+
+`ButtonVisual` also provides a customizable `Text` property. In this case we assign the font, color, and size.
+
+[!code-csharp[](./snippets/animatedbutton.cs?start=45&end=55)]
#### Animated Chains
@@ -215,27 +227,25 @@ The most distinctive feature of our animated button is its ability to change app
Each animation frame specifies the coordinates within our texture atlas to display:
-[!code-csharp[](./snippets/animatedbutton.cs?start=62&end=102)]
+[!code-csharp[](./snippets/animatedbutton.cs?start=58&end=93)]
#### States and Categories
-In Gum, each control type has a specific category name that identifies its state collection. For buttons we use `Button.ButtonCategoryName`:
+In Gum, each control type has a specific category name that identifies its state collection. `ButtonVisual` provides access to ready-made states and catgories which we can modify. Before we speicfy how a state should modify the button's appearance, we clear out all existing functionality so that we can fully control the states:
-[!code-csharp[](./snippets/animatedbutton.cs?start=104&end=107)]
+[!code-csharp[](./snippets/animatedbutton.cs?start=104&end=104)]
-Within this category, we define how the button appears in different states by creating `StateSave` objects with specific state names:
+Each of the button's states can be accessed through `ButtonVisual`. Since the states were cleared previously, the code assigns only the necessary property assignments in the `Apply` delegate. In our case, we switch between animation chains to create the desired visual effect.
-[!code-csharp[](./snippets/animatedbutton.cs?start=109&end=140)]
-
-Each state's `Apply` action defines what visual changes occur when the state becomes active. In our case, we switch between animation chains to create the desired visual effect.
+[!code-csharp[](./snippets/animatedbutton.cs?start=107&end=130)]
#### Custom Input Handling
We add custom keyboard navigation to our button by handling the `KeyDown` event:
-[!code-csharp[](./snippets/animatedbutton.cs?start=142&end=143)]
+[!code-csharp[](./snippets/animatedbutton.cs?start=133&end=133)]
-[!code-csharp[](./snippets/animatedbutton.cs?start=152&end=167)]
+[!code-csharp[](./snippets/animatedbutton.cs?start=142&end=154)]
This allows players to navigate between buttons using the left and right arrow keys, providing additional control options beyond the default tab navigation.
@@ -243,9 +253,9 @@ This allows players to navigate between buttons using the left and right arrow k
We also add a `RollOn` event handler to ensure the button gets focus when the mouse hovers over it:
-[!code-csharp[](./snippets/animatedbutton.cs?start=145&end=146)]
+[!code-csharp[](./snippets/animatedbutton.cs?start=136&end=136)]
-[!code-csharp[](./snippets/animatedbutton.cs?start=169&end=175)]
+[!code-csharp[](./snippets/animatedbutton.cs?start=159&end=162)]
This creates a more responsive interface by immediately focusing elements that the player interacts with using the mouse.
@@ -253,6 +263,8 @@ This creates a more responsive interface by immediately focusing elements that t
Now we will create a custom `OptionsSlider` class to style the volume sliders. This class inherits from Gum's base `Slider` class and provides a styled appearance consistent with the game's visual theme.
+Unlike `AnimatedButton`, the `OptionsSlider` creates a Visual completely from scratch. This class provides an example for how to completely customize a Forms control by recreating its Visual object entirely. We do this because the desired appearance and behavior of our `OptionsSlider` is differs enough from the existing Slider that it is easier to replace its `Visual` entirely.
+
In the `UI` folder of the *DungeonSlime* project (your main game project), create a new file called `OptionsSlider.cs` and add the following code to it:
[!code-csharp[](./snippets/optionsslider.cs)]
diff --git a/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/animatedbutton.cs b/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/animatedbutton.cs
index 0e579ab4..3d304f92 100644
--- a/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/animatedbutton.cs
+++ b/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/animatedbutton.cs
@@ -1,10 +1,11 @@
using System;
using Gum.DataTypes;
using Gum.DataTypes.Variables;
+using Gum.Forms.Controls;
+using Gum.Forms.DefaultVisuals;
using Gum.Graphics.Animation;
using Gum.Managers;
using Microsoft.Xna.Framework.Input;
-using MonoGameGum.Forms.Controls;
using MonoGameGum.GueDeriving;
using MonoGameLibrary.Graphics;
@@ -22,27 +23,26 @@ internal class AnimatedButton : Button
/// The texture atlas containing button graphics and animations
public AnimatedButton(TextureAtlas atlas)
{
- // Create the top-level container that will hold all visual elements
+ // Each Forms conrol has a general Visual property that
+ // has properties shared by all control types. This Visual
+ // type matches the Forms type. It can be casted to access
+ // controls-specific properties.
+ ButtonVisual buttonVisual = (ButtonVisual)Visual;
// Width is relative to children with extra padding, height is fixed
- ContainerRuntime topLevelContainer = new ContainerRuntime();
- topLevelContainer.Height = 14f;
- topLevelContainer.HeightUnits = DimensionUnitType.Absolute;
- topLevelContainer.Width = 21f;
- topLevelContainer.WidthUnits = DimensionUnitType.RelativeToChildren;
+ buttonVisual.Height = 14f;
+ buttonVisual.HeightUnits = DimensionUnitType.Absolute;
+ buttonVisual.Width = 21f;
+ buttonVisual.WidthUnits = DimensionUnitType.RelativeToChildren;
- // Create the nine-slice background that will display the button graphics
+ // Get a reference to the nine-slice background to display the button graphics
// A nine-slice allows the button to stretch while preserving corner appearance
- NineSliceRuntime nineSliceInstance = new NineSliceRuntime();
- nineSliceInstance.Height = 0f;
- nineSliceInstance.Texture = atlas.Texture;
- nineSliceInstance.TextureAddress = TextureAddress.Custom;
- nineSliceInstance.Dock(Gum.Wireframe.Dock.Fill);
- topLevelContainer.Children.Add(nineSliceInstance);
-
- // Create the text element that will display the button's label
- TextRuntime textInstance = new TextRuntime();
- // Name is required so it hooks in to the base Button.Text property
- textInstance.Name = "TextInstance";
+ NineSliceRuntime background = buttonVisual.Background;
+ background.Texture = atlas.Texture;
+ background.TextureAddress = TextureAddress.Custom;
+ background.Color = Microsoft.Xna.Framework.Color.White;
+ // texture coordinates for the background are set down below
+
+ TextRuntime textInstance = buttonVisual.TextInstance;
textInstance.Text = "START";
textInstance.Blue = 130;
textInstance.Green = 86;
@@ -53,7 +53,6 @@ public AnimatedButton(TextureAtlas atlas)
textInstance.Anchor(Gum.Wireframe.Anchor.Center);
textInstance.Width = 0;
textInstance.WidthUnits = DimensionUnitType.RelativeToChildren;
- topLevelContainer.Children.Add(textInstance);
// Get the texture region for the unfocused button state from the atlas
TextureRegion unfocusedTextureRegion = atlas.GetRegion("unfocused-button");
@@ -94,58 +93,47 @@ public AnimatedButton(TextureAtlas atlas)
}
// Assign both animation chains to the nine-slice background
- nineSliceInstance.AnimationChains = new AnimationChainList
+ background.AnimationChains = new AnimationChainList
{
unfocusedAnimation,
focusedAnimation
};
- // Create a state category for button states
- StateSaveCategory category = new StateSaveCategory();
- category.Name = Button.ButtonCategoryName;
- topLevelContainer.AddCategory(category);
- // Create the enabled (default/unfocused) state
- StateSave enabledState = new StateSave();
- enabledState.Name = FrameworkElement.EnabledStateName;
+ // Reset all state to default so we don't have unexpected variable assignments:
+ buttonVisual.ButtonCategory.ResetAllStates();
+
+ // Get the enabled (default/unfocused) state
+ StateSave enabledState = buttonVisual.States.Enabled;
enabledState.Apply = () =>
{
// When enabled but not focused, use the unfocused animation
- nineSliceInstance.CurrentChainName = unfocusedAnimation.Name;
+ background.CurrentChainName = unfocusedAnimation.Name;
};
- category.States.Add(enabledState);
// Create the focused state
- StateSave focusedState = new StateSave();
- focusedState.Name = FrameworkElement.FocusedStateName;
+ StateSave focusedState = buttonVisual.States.Focused;
focusedState.Apply = () =>
{
// When focused, use the focused animation and enable animation playback
- nineSliceInstance.CurrentChainName = focusedAnimation.Name;
- nineSliceInstance.Animate = true;
+ background.CurrentChainName = focusedAnimation.Name;
+ background.Animate = true;
};
- category.States.Add(focusedState);
// Create the highlighted+focused state (for mouse hover while focused)
- // by cloning the focused state since they appear the same
- StateSave highlightedFocused = focusedState.Clone();
- highlightedFocused.Name = FrameworkElement.HighlightedFocusedStateName;
- category.States.Add(highlightedFocused);
+ StateSave highlightedFocused = buttonVisual.States.HighlightedFocused;
+ highlightedFocused.Apply = focusedState.Apply;
// Create the highlighted state (for mouse hover)
// by cloning the enabled state since they appear the same
- StateSave highlighted = enabledState.Clone();
- highlighted.Name = FrameworkElement.HighlightedStateName;
- category.States.Add(highlighted);
+ StateSave highlighted = buttonVisual.States.Highlighted;
+ highlighted.Apply = enabledState.Apply;
// Add event handlers for keyboard input.
KeyDown += HandleKeyDown;
// Add event handler for mouse hover focus.
- topLevelContainer.RollOn += HandleRollOn;
-
- // Assign the configured container as this button's visual
- Visual = topLevelContainer;
+ buttonVisual.RollOn += HandleRollOn;
}
///
@@ -172,4 +160,4 @@ private void HandleRollOn(object sender, EventArgs e)
{
IsFocused = true;
}
-}
+}
\ No newline at end of file
diff --git a/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/gamescene/usings.cs b/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/gamescene/usings.cs
index 0f66d95e..c19423d4 100644
--- a/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/gamescene/usings.cs
+++ b/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/gamescene/usings.cs
@@ -8,7 +8,7 @@
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoGameGum;
-using MonoGameGum.Forms.Controls;
+using Gum.Forms.Controls;
using MonoGameGum.GueDeriving;
using MonoGameLibrary;
using MonoGameLibrary.Graphics;
diff --git a/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/optionsslider.cs b/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/optionsslider.cs
index 63f4fbb0..2280b8a9 100644
--- a/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/optionsslider.cs
+++ b/articles/tutorials/building_2d_games/21_customizing_gum_ui/snippets/optionsslider.cs
@@ -3,7 +3,7 @@
using Gum.DataTypes.Variables;
using Gum.Managers;
using Microsoft.Xna.Framework;
-using MonoGameGum.Forms.Controls;
+using Gum.Forms.Controls;
using MonoGameGum.GueDeriving;
using MonoGameLibrary.Graphics;