Expert-Level Guide to Unreal Engine Slate UI & Custom Input Behaviors

Slate is Unreal Engineโ€™s low-level UI framework, offering full control over UI elements and input handling. While UMG (Unreal Motion Graphics) is the easiest way to create UI, Slate is required for high-performance UI, editor tools, and custom UI behaviors.


๐Ÿ”น Part 1: Understanding Slate Fundamentals

๐Ÿ“Œ What is Slate?

Slate is Unrealโ€™s immediate mode UI framework, meaning UI elements are redrawn every frame. Itโ€™s lightweight and designed for real-time responsiveness, which is why itโ€™s used extensively in editor tools and custom HUDs.

๐Ÿ“œ Slate vs UMG โ€“ Why Use Slate?

| Feature | Slate (C++) | UMG (Blueprint) | |โ€”โ€”โ€”|โ€”โ€”โ€”โ€”|โ€”โ€”โ€”โ€”โ€”-| | Performance | โœ… Very Fast | โŒ Slower (Blueprint Overhead) | | Customization | โœ… Full Control | โŒ Limited to UMG Widgets | | Editor Tools | โœ… Used for Unreal Editor UI | โŒ Mostly for runtime UI | | Game UI | โœ… Advanced HUDs | โœ… Easy-to-use UI | | Input Handling | โœ… Custom Input Behaviors | โŒ Limited Input Customization |

๐Ÿ‘‰ Use Slate when: You need maximum performance, complex custom UI, or need to modify input handling.


๐Ÿ“Œ How Slate Works (The Basics)

๐Ÿ”น Key Slate Concepts

| Concept | Description | |โ€”โ€”โ€”|โ€”โ€”โ€”โ€”| | SWidget | Base class for all Slate UI elements. | | SNew() | Macro for creating new Slate widgets. | | Children | UI elements are nested inside containers (e.g., SVerticalBox). | | Arguments | UI elements take properties (.Text(), .Padding(), etc.). | | Paint & Input Functions | Each widget paints itself and handles input events. |


๐Ÿ”น Part 2: Setting Up Slate in Your Project

1๏ธโƒฃ Include Slate Dependencies

In your projectโ€™s Build.cs, add:

PublicDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

Then include the Slate headers in your C++ file:

#include "SlateBasics.h"
#include "SlateExtras.h"

๐Ÿ”น Part 3: Creating a Basic Slate UI

Letโ€™s create a simple UI with text and a button.

Step 1: Create a New Slate Widget Class

Create SMySlateWidget.h:

#pragma once

#include "Widgets/SCompoundWidget.h"  // Base class for custom widgets
#include "Widgets/Text/STextBlock.h"
#include "Widgets/Input/SButton.h"

class SMySlateWidget : public SCompoundWidget
{
public:
    SLATE_BEGIN_ARGS(SMySlateWidget) {}
    SLATE_ARGUMENT(FText, InitialText)
    SLATE_END_ARGS()

    void Construct(const FArguments& InArgs);
};

Step 2: Implement the Widget (SMySlateWidget.cpp)

#include "SMySlateWidget.h"

void SMySlateWidget::Construct(const FArguments& InArgs)
{
    ChildSlot
    [
        SNew(SVerticalBox)

        + SVerticalBox::Slot()
        .AutoHeight()
        [
            SNew(STextBlock)
            .Text(InArgs._InitialText)  // Uses argument passed to the widget
        ]

        + SVerticalBox::Slot()
        .AutoHeight()
        [
            SNew(SButton)
            .Text(FText::FromString("Click Me!"))
            .OnClicked_Lambda([]() 
            {
                UE_LOG(LogTemp, Warning, TEXT("Button Clicked!"));
                return FReply::Handled();
            })
        ]
    ];
}

Step 3: Add the Widget to a Viewport

Inside a HUD class (AHUD or AGameMode), add:

TSharedPtr<SMySlateWidget> MySlateWidget;

void AMyHUD::BeginPlay()
{
    Super::BeginPlay();

    SAssignNew(MySlateWidget, SMySlateWidget)
    .InitialText(FText::FromString("Hello, Slate!"));

    GEngine->GameViewport->AddViewportWidgetContent(MySlateWidget.ToSharedRef());
}

โœ… Result: This will add a text block and button to the screen using Slate.


๐Ÿ”น Part 4: Creating Custom Slate Elements (Custom Input Behavior)

Now letโ€™s create a custom input widget that listens for key presses and performs custom actions.

๐Ÿ“Œ Step 1: Define the Custom Widget Class

Create SMyCustomInputWidget.h:

#pragma once

#include "Widgets/SCompoundWidget.h"

class SMyCustomInputWidget : public SCompoundWidget
{
public:
    SLATE_BEGIN_ARGS(SMyCustomInputWidget) {}
    SLATE_END_ARGS()

    void Construct(const FArguments& InArgs);

    virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override;
};

๐Ÿ“Œ Step 2: Implement the Input Handling

SMyCustomInputWidget.cpp

#include "SMyCustomInputWidget.h"
#include "SlateOptMacros.h"
#include "InputCoreTypes.h"

void SMyCustomInputWidget::Construct(const FArguments& InArgs)
{
    ChildSlot
    [
        SNew(STextBlock)
        .Text(FText::FromString("Press any key!"))
    ];
}

// Capture keyboard input
FReply SMyCustomInputWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{
    FKey PressedKey = KeyEvent.GetKey();

    if (PressedKey == EKeys::SpaceBar)
    {
        UE_LOG(LogTemp, Warning, TEXT("Spacebar Pressed!"));
        return FReply::Handled();
    }

    return FReply::Unhandled();
}

๐Ÿ“Œ Step 3: Add the Custom Input Widget to the Game

Inside your HUD or GameMode, add:

TSharedPtr<SMyCustomInputWidget> MyInputWidget;

void AMyHUD::BeginPlay()
{
    Super::BeginPlay();

    SAssignNew(MyInputWidget, SMyCustomInputWidget);

    GEngine->GameViewport->AddViewportWidgetContent(MyInputWidget.ToSharedRef());
}

โœ… Result: The UI listens for keyboard input and logs โ€œSpacebar Pressed!โ€ when the spacebar is hit.


๐Ÿ”น Part 5: Advanced Slate Input Handling (Mouse, Keyboard, Focus, Events)

You can override different input events to handle custom interactions.

Event Description
OnMouseButtonDown() Detects mouse button presses.
OnMouseMove() Tracks cursor movement.
OnKeyDown() Handles key presses.
OnKeyUp() Detects key releases.
OnFocusReceived() Called when the widget gets focus.

Example: Handling Mouse Clicks

FReply SMyCustomInputWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
    if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
    {
        UE_LOG(LogTemp, Warning, TEXT("Left Mouse Clicked!"));
        return FReply::Handled();
    }

    return FReply::Unhandled();
}

๐ŸŽฏ Conclusion

โœ… Slate is a powerful C++ UI system for creating custom editor tools, HUDs, and advanced UIs.
โœ… You can override input functions (OnKeyDown, OnMouseButtonDown) to create custom UI interactions.
โœ… Slate is more performant than UMG but requires more code and setup.


๐Ÿš€ Next Steps:
Would you like a fully working project showcasing Slate UI, animations, and event-driven interactions? Let me know! ๐ŸŽฎ๐Ÿ”ฅ