Agent skill

Ue UI Umg Slate

by quodsoler in quodsoler/unreal-engine-skills

A skill your agent uses when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models.

MITAuto-check passedGame Development

Install Ue UI Umg Slate

skills CLI
$ npx skills add quodsoler/unreal-engine-skills --skill ue-ui-umg-slate -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install quodsoler/unreal-engine-skills ue-ui-umg-slate --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ue-ui-umg-slate .claude/skills/ue-ui-umg-slate && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ue-ui-umg-slate
GitHub stars
362
Token cost
~7.4k tokens
SKILL.md length
1,783 words
Files
4 (incl. references)
Skills in repo
31
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models.

  • Fixing Unreal Engine UI in C++ — UMG user widgets
  • SKILL.md covers Context, Widget Lifecycle, BindWidget and Widget Interaction, plus 11 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Common UI screens

What it does

Ue UI Umg Slate is an agent skill from quodsoler/unreal-engine-skills. Use when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models. Also use when the user mentions 'UUserWidget', 'NativeConstruct', 'BindWidget', 'CreateWidget', 'AddToViewport', 'ESlateVisibility', 'OnClicked', 'UListView', 'widget animation', 'SNew', 'SLATEBEGINARGS', 'SCompoundWidget', 'UCommonActivatableWidget', 'activatable widget stack', 'UCommonButtonBase', 'gamepad focus', 'FUIInputConfig', 'UMVVMViewModelBase', 'FieldNotify', or…

Its SKILL.md is about 7.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/common-ui-setup.md`, `references/slate-patterns.md` and `references/widget-types.md`).

It sits in Game Development. It works with C++ and Unreal Engine. The repository describes itself as: Unreal Engine C++ skills for AI coding agents. 27 skills covering gameplay, rendering, networking, animation, and more. Works with Claude Code, Cursor, Windsurf, and any agent… The licence is MIT.

When your agent uses it

  • Fixing Unreal Engine UI in C++ — UMG user widgets
  • Common UI screens
  • MVVM view models
  • The user mentions UUserWidget

Example prompts

  • “UUserWidget”
  • “NativeConstruct”
  • “BindWidget”
  • “/ue-ui-umg-slate”

What it can do on your machine

Read from SKILL.md and the folder at commit f3742d7. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are cpp and csharp).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Ue UI Umg Slate loads about 7.4k tokens when it runs, and up to ~21k if it reads all its reference files. Until then it costs about 161 tokens; SKILL.md has 1,783 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~161
When it runs · the whole SKILL.md, loaded when a task matches
~7.4k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~21k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from quodsoler/unreal-engine-skills at commit f3742d7, republished under its MIT licence (© quodsoler). 1,783 words, ~7,421 tokens.

Download SKILL.mdSave it as .claude/skills/ue-ui-umg-slate/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
ue-ui-umg-slate
description
Use when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models. Also use when the user mentions 'UUserWidget', 'NativeConstruct', 'BindWidget', 'CreateWidget', 'AddToViewport', 'ESlateVisibility', 'OnClicked', 'UListView', 'widget animation', 'SNew', 'SLATE_BEGIN_ARGS', 'SCompoundWidget', 'UCommonActivatableWidget', 'activatable widget stack', 'UCommonButtonBase', 'gamepad focus', 'FUIInputConfig', 'UMVVMViewModelBase', 'FieldNotify', or 'WidgetComponent'. For input modes and Enhanced Input, see ue-input-system; for Slate in editor tooling, see ue-editor-tools.
metadata.version
2.0.0
metadata.engine
5.8

UE UI: UMG, Slate, and Common UI

Target engine: UE 5.8. APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".

UMG is the runtime UI framework (UMG module, Engine/Source/Runtime/UMG/Public) built on Slate (Slate, SlateCore). Common UI (plugin, production in 5.8) adds cross-platform input routing, activation stacks and platform-aware buttons. Model View Viewmodel (plugin, Beta in 5.8) adds declarative data binding on top of FieldNotification.

Context

Read .agents/ue-project-context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.

Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.

Request is about…Go to
Widget class, overrides, creation, visibility, GCWidget Lifecycle
Wiring designer widgets into C++ (meta=(BindWidget))BindWidget
Buttons, text, images, bars, listsWidget Interaction
Playing/stopping UMG animationsWidget Animation
Mouse cursor, focus, SetInputModeInput Mode and Focus
Menus, screen stacks, gamepad, back actionCommon UI
Data binding, view models, field notificationsMVVM
UI rendered in the levelWorld-Space UI
Iterating widgets, drag/drop, brushes, geometryWidget Tree and Helper Libraries
Custom SWidget, SNew, SLATE_BEGIN_ARGSSlate

Per-widget method tables (setters, delegates, enums) live in references/widget-types.md. Full Common UI plugin setup lives in references/common-ui-setup.md. A complete custom Slate widget lives in references/slate-patterns.md.

Widget Lifecycle

cpp
// MyWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "MyWidget.generated.h"

class UButton;

UCLASS()
class MYGAME_API UMyWidget : public UUserWidget
{
    GENERATED_BODY()

protected:
    virtual void NativeOnInitialized() override;
    virtual void NativePreConstruct() override;
    virtual void NativeConstruct() override;
    virtual void NativeDestruct() override;
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;

    UPROPERTY(meta=(BindWidget))
    TObjectPtr<UButton> PlayButton;

    UFUNCTION()
    void HandlePlayClicked();
};

// MyWidget.cpp — #include "MyWidget.h" and "Components/Button.h"
void UMyWidget::NativeOnInitialized() { Super::NativeOnInitialized(); }
void UMyWidget::NativePreConstruct() { Super::NativePreConstruct(); }
void UMyWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
}

void UMyWidget::NativeConstruct()
{
    Super::NativeConstruct();       // Runs on every re-add; pair each bind with an unbind in NativeDestruct
    PlayButton->OnClicked.AddDynamic(this, &UMyWidget::HandlePlayClicked);
}

void UMyWidget::NativeDestruct()
{
    PlayButton->OnClicked.RemoveDynamic(this, &UMyWidget::HandlePlayClicked);
    Super::NativeDestruct();
}
Override (verbatim from Blueprint/UserWidget.h)When it runs
virtual void NativeOnInitialized() override;Once per instance, after construction of the widget object
virtual void NativePreConstruct() override;After the Slate tree is rebuilt, just before NativeConstruct (UserWidget.cpp:1231); also runs in the Designer
virtual void NativeConstruct() override;Slate widget added to a parent — bind delegates here
virtual void NativeDestruct() override;Slate widget removed — unbind here
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;Per frame while ticking
virtual int32 NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;Custom drawing; return the last used layer id
virtual FReply NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;Pointer press
virtual FReply NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;Key press while focused
virtual FReply NativeOnFocusReceived(const FGeometry& InGeometry, const FFocusEvent& InFocusEvent) override;This widget gained focus
virtual void NativeOnAddedToFocusPath(const FFocusEvent& InFocusEvent) override;This widget or a descendant gained focus
virtual bool Initialize() override;Builds the widget tree; call Super::Initialize() and return its result
virtual TSharedRef<SWidget> RebuildWidget() override;Builds the underlying Slate widget
virtual void ReleaseSlateResources(bool bReleaseChildren) override;Drop cached TSharedPtr<SWidget> members here

Input handlers return FReply::Handled() to consume the event or FReply::Unhandled() to let it bubble.

Creation, viewport, visibility
cpp
// CreateWidget<T>(Owner, Class, WidgetName = NAME_None). Owner may be a UWidget,
// UWidgetTree, APlayerController, UGameInstance or UWorld.
UMyWidget* Widget = CreateWidget<UMyWidget>(GetOwningPlayer(), MyWidgetClass);
Widget->AddToViewport(0);       // ZOrder: higher draws on top. Roots the widget.
Widget->AddToPlayerScreen(0);   // Split-screen: one player's viewport region; returns bool
Widget->RemoveFromParent();     // Un-roots - collectable unless a UPROPERTY holds it
Widget->SetVisibility(ESlateVisibility::Collapsed);  // Not drawn, takes no space
Widget->SetVisibility(ESlateVisibility::Hidden);     // Not drawn, still takes space
Widget->SetVisibility(ESlateVisibility::Visible);    // Drawn, hit-testable
Widget->SetIsEnabled(false);                         // Greys out, blocks input

HitTestInvisible draws but passes input through for the widget and its children; SelfHitTestInvisible passes input through for the widget only. Hold a UPROPERTY() TObjectPtr<UMyWidget> if the widget must survive RemoveFromParent. GetOwningPlayer() returns the owning APlayerController; GetOwningPlayer<AMyPlayerController>() casts for you.

BindWidget

cpp
UPROPERTY(meta=(BindWidget))                 // Compile error in the Widget BP if missing
TObjectPtr<UTextBlock> ScoreText;
UPROPERTY(meta=(BindWidgetOptional))         // May be null - always null-check
TObjectPtr<UTextBlock> SubtitleText;
UPROPERTY(Transient, meta=(BindWidgetAnim))  // Transient is required for animation bindings
TObjectPtr<UWidgetAnimation> IntroAnim;

Rules: the C++ member name must match the Widget Blueprint's widget name exactly (case-sensitive); the declared type must match or be a base of the designer widget's class; bound members are assigned inside Initialize() before NativeOnInitialized runs (UserWidget.cpp:153,175), so they are valid in NativeOnInitialized, NativePreConstruct and NativeConstruct — bind once-per-instance delegates in NativeOnInitialized. Declare them protected with no Category.

Widget Interaction

Dynamic multicast delegates on UMG components use AddDynamic, so the handler must be a UFUNCTION().

cpp
PlayButton->OnClicked.AddDynamic(this, &UMyWidget::HandlePlayClicked);
PlayButton->SetColorAndOpacity(FLinearColor(1.f, 0.8f, 0.f, 1.f));
ScoreText->SetText(FText::Format(NSLOCTEXT("HUD", "ScoreFmt", "Score: {0}"), FText::AsNumber(Score)));
ScoreText->SetTextOverflowPolicy(ETextOverflowPolicy::Ellipsis);
PlayerAvatar->SetBrushFromSoftTexture(SoftAvatarTexture, /*bMatchSize=*/false);
UMaterialInstanceDynamic* AvatarMID = PlayerAvatar->GetDynamicMaterial();
AvatarMID->SetScalarParameterValue(TEXT("Opacity"), 0.5f);
HealthBar->SetPercent(CurrentHealth / MaxHealth);   // 0.0-1.0
HealthBar->SetFillColorAndOpacity(FLinearColor(0.f, 1.f, 0.f, 1.f));

Method and enum tables for UButton, UTextBlock, UImage, UProgressBar, UScrollBox, UWidgetSwitcher, UCheckBox, UEditableTextBox, USlider, UComboBoxString and the UWidget base are in references/widget-types.md.

Lists: UListView, UTileView, UTreeView

All three are virtualised — only visible entry widgets exist, and they are recycled. Items are UObject*; the entry widget derives from UUserWidget and implements IUserObjectListEntry, overriding virtual void NativeOnListItemObjectSet(UObject* ListItemObject) override; (call IUserObjectListEntry::NativeOnListItemObjectSet first). The full entry-widget example and the UListView method table are in references/widget-types.md.

cpp
ItemList->ClearListItems();
for (const FMyItemInfo& Info : Items)
{
    UMyItemData* Data = NewObject<UMyItemData>(this);
    Data->DisplayName = Info.DisplayName;
    ItemList->AddItem(Data);
}
UMyItemData* Selected = ItemList->GetSelectedItem<UMyItemData>();

BP_OnItemClicked is a Blueprint-only private delegate. From C++, bind the native event ItemList->OnItemClicked().AddUObject(...) (FSimpleListItemEvent, Components/ListViewBase.h:48; also OnItemSelectionChanged()), or override virtual void OnItemClickedInternal(UObject* Item) override; in a UListView subclass. Inside an entry widget, read the item with GetListItem<UMyItemData>() and query selection with the interface member IsListItemSelected() (Blueprint/IUserListEntry.h:32).

Widget Animation

PlayAnimation and its variants return an FWidgetAnimationHandle (Animation/WidgetAnimationHandle.h); keep the handle, not a sequence-player pointer. A valid handle may still resolve to no state once the animation finishes, so check IsValid().

cpp
// PlayAnimation(UWidgetAnimation*, StartAtTime=0, NumLoopsToPlay=1,
//               EUMGSequencePlayMode::Type=Forward, PlaybackSpeed=1, bRestoreState=false)
FWidgetAnimationHandle IntroHandle = PlayAnimation(IntroAnim);
IntroHandle.SetUserTag(TEXT("Intro"));
PlayAnimationForward(IntroAnim);                        // also PlayAnimationReverse
const float PausedAt = PauseAnimation(IntroAnim);
const bool bPlaying = IsAnimationPlaying(IntroAnim);
StopAnimation(IntroAnim);

Input Mode and Focus

ue-input-system owns input modes and Enhanced Input. Minimal correct form:

cpp
FInputModeUIOnly UIMode;
UIMode.SetWidgetToFocus(Widget->TakeWidget());
UIMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
GetOwningPlayer()->SetInputMode(UIMode);
GetOwningPlayer()->SetShowMouseCursor(true);
// Restore gameplay:
GetOwningPlayer()->SetInputMode(FInputModeGameOnly());
GetOwningPlayer()->SetShowMouseCursor(false);

FInputModeGameAndUI also has SetWidgetToFocus and SetLockMouseToViewportBehavior. Set the input mode from the code that added the widget (HUD, PlayerController, GameMode), not from NativeConstruct. When Common UI is enabled, do not call SetInputMode at all — return an FUIInputConfig instead.

Common UI

Enable the CommonUI plugin (it ships both the CommonUI and CommonInput modules), add both modules to Build.cs, and set the viewport client class to UCommonGameViewportClient — it reroutes input to the UI action router before the game (CommonGameViewportClient.h:21); gamepad/mouse/touch changes are detected by UCommonInputSubsystem's FCommonInputPreprocessor and broadcast from that subsystem. Setup details, layer architecture and settings keys are in references/common-ui-setup.md.

cpp
// MyMenuScreen.h
#pragma once
#include "CommonActivatableWidget.h"
#include "MyMenuScreen.generated.h"

class UCommonButtonBase;

UCLASS()
class MYGAME_API UMyMenuScreen : public UCommonActivatableWidget
{
    GENERATED_BODY()

protected:
    virtual void NativeOnActivated() override;
    virtual void NativeOnDeactivated() override;
    virtual UWidget* NativeGetDesiredFocusTarget() const override;
    virtual TOptional<FUIInputConfig> GetDesiredInputConfig() const override;
    virtual bool NativeOnHandleBackAction() override;   // Return true when handled

    UPROPERTY(meta=(BindWidget))
    TObjectPtr<UCommonButtonBase> CloseButton;

    void HandleCloseClicked();
};

// MyMenuScreen.cpp — #include "MyMenuScreen.h" and "CommonButtonBase.h"
void UMyMenuScreen::NativeOnActivated()
{
    Super::NativeOnActivated();     // Broadcasts OnActivated(), which activates this widget's tree node
    CloseButton->OnClicked().AddUObject(this, &UMyMenuScreen::HandleCloseClicked);
}

void UMyMenuScreen::NativeOnDeactivated()
{
    CloseButton->OnClicked().RemoveAll(this);
    Super::NativeOnDeactivated();   // Broadcasts OnDeactivated(); the router moves focus to the parent
}

UWidget* UMyMenuScreen::NativeGetDesiredFocusTarget() const { return CloseButton; }

TOptional<FUIInputConfig> UMyMenuScreen::GetDesiredInputConfig() const
{
    return FUIInputConfig(ECommonInputMode::Menu, EMouseCaptureMode::NoCapture);
}

bool UMyMenuScreen::NativeOnHandleBackAction() { DeactivateWidget(); return true; }
void UMyMenuScreen::HandleCloseClicked() { DeactivateWidget(); }

Public API: ActivateWidget(), DeactivateWidget(), IsActivated(), GetDesiredFocusTarget(), ClearFocusRestorationTarget(), RequestRefreshFocus(), plus the non-dynamic OnActivated() / OnDeactivated() delegates. BP_GetDesiredFocusTarget is the BlueprintImplementableEvent that NativeGetDesiredFocusTarget routes to — override the native one in C++. Editable defaults: bAutoActivate, bIsBackHandler, bIsBackActionDisplayedInActionBar, bIsModal, bAutoRestoreFocus, bSetVisibilityOnActivated/ActivatedVisibility, bSetVisibilityOnDeactivated/DeactivatedVisibility. ECommonInputMode is Menu (UI only), Game (game only) or All.

Containers

UCommonActivatableWidgetContainerBase (Widgets/CommonActivatableWidgetContainer.h) is the base; UCommonActivatableWidgetStack shows the topmost widget and re-activates the one beneath when it deactivates; UCommonActivatableWidgetQueue shows one at a time and advances when the active one deactivates. UCommonActivatableWidgetSwitcher is an index-based switcher, not a stack — do not use it here.

cpp
UPROPERTY(meta=(BindWidget))
TObjectPtr<UCommonActivatableWidgetStack> MenuLayer;
// AddWidget<T> creates (or pools) the instance, adds it, and the container activates it.
UMyMenuScreen* Screen = MenuLayer->AddWidget<UMyMenuScreen>(UMyMenuScreen::StaticClass());
// Overload with an init lambda that runs after creation, before the widget is added:
MenuLayer->AddWidget<UMyMenuScreen>(UMyMenuScreen::StaticClass(),
    [](UMyMenuScreen& Instance) { Instance.SetIsEnabled(true); });

if (UCommonActivatableWidget* Active = MenuLayer->GetActiveWidget())
{
    Active->DeactivateWidget();         // Pops the stack
}
// RemoveWidget(UCommonActivatableWidget&) deactivates the active widget, or yanks an inactive one
MenuLayer->RemoveWidget(*Screen);
MenuLayer->ClearWidgets();              // GetNumWidgets() reports the current depth
Buttons, input type, action routing
cpp
// UCommonButtonBase::OnClicked() returns FCommonButtonEvent (DECLARE_EVENT, no params).
MyButton->OnClicked().AddUObject(this, &UMyMenuScreen::HandleCloseClicked);
MyButton->OnClicked().RemoveAll(this);
MyButton->SetIsSelected(true);
MyButton->SetIsInteractionEnabled(true);
UCommonInputSubsystem* InputSubsystem = UCommonInputSubsystem::Get(GetOwningLocalPlayer());
const ECommonInputType InputType = InputSubsystem->GetCurrentInputType();  // MouseAndKeyboard, Gamepad, Touch
InputSubsystem->OnInputMethodChangedNative.AddUObject(this, &UMyMenuScreen::HandleInputMethodChanged);

// UCommonUIActionRouterBase is the local-player subsystem that routes input through the activation tree.
if (UCommonUIActionRouterBase* Router = UCommonUIActionRouterBase::Get(*CloseButton))
{
    const ECommonInputMode Mode = Router->GetActiveInputMode();
}

// On a UCommonUserWidget subclass, with UPROPERTY(EditDefaultsOnly) TObjectPtr<UInputAction> BackInputAction:
FUIActionBindingHandle BackHandle = RegisterUIActionBinding(
    FBindUIActionArgs(BackInputAction, /*bShouldDisplayInActionBar=*/true,
        FSimpleDelegate::CreateUObject(this, &UMyMenuScreen::HandleCloseClicked)));

OnInputMethodChangedNative is a DECLARE_EVENT_OneParam, so HandleInputMethodChanged(ECommonInputType) needs no UFUNCTION(). Enhanced Input and Common Input are unified in 5.8: with bEnableEnhancedInputSupport on (UCommonInputSettings::IsEnhancedInputSupportEnabled()), FBindUIActionArgs takes a const UInputAction* and UCommonActivatableWidget::InputMapping / InputMappingPriority push a mapping context on activation.

MVVM

ModelViewViewModel is Beta in 5.8. A view model is a UMVVMViewModelBase; FieldNotify properties get a generated field descriptor, and UE_MVVM_SET_PROPERTY_VALUE compares, assigns and broadcasts in one call.

cpp
// MyGameViewModel.h
#pragma once
#include "MVVMViewModelBase.h"
#include "MyGameViewModel.generated.h"

UCLASS()
class MYGAME_API UMyGameViewModel : public UMVVMViewModelBase
{
    GENERATED_BODY()

public:
    void SetScore(int32 NewScore) { UE_MVVM_SET_PROPERTY_VALUE(Score, NewScore); }
    int32 GetScore() const { return Score; }

private:
    UPROPERTY(BlueprintReadOnly, FieldNotify, Getter, meta=(AllowPrivateAccess))
    int32 Score = 0;
};

// Binding at runtime - the UMVVMView extension on the user widget owns the generated bindings.
UMyGameViewModel* ViewModel = NewObject<UMyGameViewModel>(this);
if (UMVVMView* View = UMVVMSubsystem::GetViewFromUserWidget(MyWidget))
{
    View->SetViewModel(TEXT("ScoreViewModel"), ViewModel);   // Name from the Bindings panel
}

UE_MVVM_SET_PROPERTY_VALUE(MemberName, NewValue) expands to SetPropertyValue(MemberName, NewValue, ThisClass::FFieldNotificationClassDescriptor::MemberName). Use UE_MVVM_SET_PROPERTY_VALUE_INLINE for values that cannot be passed as function arguments (bitfields), and UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED(MemberName) when you assigned the member yourself; both end in BroadcastFieldValueChanged(UE::FieldNotification::FFieldId) from INotifyFieldValueChanged.

UHT generates the descriptor for every FieldNotify property and function. Declare fields by hand only under the UCLASS(CustomFieldNotify) class specifier (not a meta key; see Components/Widget.h:215), with the UE_FIELD_NOTIFICATION_DECLARE_CLASS_DESCRIPTOR_BEGIN / UE_FIELD_NOTIFICATION_DECLARE_FIELD(Name, API_STRING) / UE_FIELD_NOTIFICATION_DECLARE_ENUM_FIELD(Name) / ..._END family in FieldNotificationDeclaration.h (FieldNotification module; the old FieldNotification/ path is deprecated since 5.3), paired with UE_FIELD_NOTIFICATION_IMPLEMENTATION_BEGIN and UE_FIELD_NOTIFICATION_IMPLEMENTATION_END in the .cpp. UMVVMView also exposes GetViewModel(FName), SetViewModelByClass(...) and ExecuteViewModelBindings(FName); UMVVMSubsystem is a UEngineSubsystem and GetViewFromUserWidget is static.

Show full SKILL.md (723 more words)Show less

World-Space UI

UWidgetComponent (Components/WidgetComponent.h, UMG module) renders a UUserWidget onto a plane or cylinder in the level.

cpp
// In the constructor of AMyCharacter (NameplateComponent is a UPROPERTY member):
NameplateComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("Nameplate"));
NameplateComponent->SetupAttachment(RootComponent);
NameplateComponent->SetWidgetSpace(EWidgetSpace::World);        // or EWidgetSpace::Screen
NameplateComponent->SetDrawSize(FVector2D(256.f, 64.f));
NameplateComponent->SetGeometryMode(EWidgetGeometryMode::Plane);// or Cylinder
NameplateComponent->SetTwoSided(false);
// At runtime:
NameplateComponent->SetWidget(NameplateWidget);
UUserWidget* Current = NameplateComponent->GetUserWidgetObject();
NameplateComponent->SetTickMode(ETickMode::Disabled);   // Then drive updates manually
NameplateComponent->RequestRedraw();

Enable bReceiveHardwareInput only for a widget that must take real mouse input; otherwise drive interaction with a UWidgetInteractionComponent.

Widget Tree and Helper Libraries

cpp
WidgetTree->ForEachWidget([](UWidget* Widget) { Widget->SetRenderOpacity(1.f); });
WidgetTree->ForEachWidgetAndDescendants([](UWidget* W) { W->SetIsEnabled(true); });
UButton* Found = WidgetTree->FindWidget<UButton>(TEXT("PlayButton"));
UMyEntryWidget* Built = WidgetTree->ConstructWidget<UMyEntryWidget>(EntryWidgetClass);

UWidgetBlueprintLibrary (Blueprint/WidgetBlueprintLibrary.h) holds the brush, drag-and-drop, FEventReply and FPaintContext drawing helpers; USlateBlueprintLibrary (Blueprint/SlateBlueprintLibrary.h) converts between local, absolute and viewport space. Both are enumerated in references/widget-types.md.

Slate

Use Slate for editor extensions and for runtime widgets UMG does not expose. SWidget is the base; SCompoundWidget is the usual parent for a custom widget.

A custom widget declares its arguments between SLATE_BEGIN_ARGS / SLATE_END_ARGS — SLATE_ATTRIBUTE for a TAttribute<T> that can be bound to a lambda, SLATE_ARGUMENT for a plain value, SLATE_EVENT for a delegate — and builds its children into ChildSlot inside Construct(const FArguments& InArgs). Bind Slate delegates with CreateSP so a destroyed widget never gets called. A complete SCompoundWidget with all three argument kinds: references/slate-patterns.md.

SNew(WidgetType) returns a TSharedRef<WidgetType>; SAssignNew(Var, WidgetType) does the same and stores it in a TSharedPtr. FOnClicked is DECLARE_DELEGATE_RetVal(FReply, FOnClicked), so a click handler must return FReply. UWidget::GetCachedWidget() gives the TSharedPtr<SWidget> behind a UMG widget; UUserWidget::TakeWidget() builds and returns the TSharedRef<SWidget>.

Public TAttribute members on stock Slate widgets are being privatised. Do not read or write them directly; use the accessors named in the deprecation message — Set<Name> to assign, Get<Name>Attribute() to read the TSlateAttributeRef. In 5.8 this hits SCheckBox::PaddingOverride (SetPaddingOverride / GetPaddingOverrideAttribute), SCheckBox::ForegroundColorOverride (SetForegroundColorOverride / GetForegroundColorOverrideAttribute), SEditableText::Font (SetFont / GetFontAttribute), SEditableText::ColorAndOpacity (SetColorAndOpacity / GetColorAndOpacityAttribute) and SMenuAnchor::Placement (SetMenuPlacement / GetPlacementAttribute).

Slate vs UMG: Slate for editor tools and maximum control; UMG for game runtime UI, Blueprint extensibility, animations and BindWidget.

Build.cs

csharp
PublicDependencyModuleNames.AddRange(new string[] { "UMG", "Slate", "SlateCore" });
PrivateDependencyModuleNames.AddRange(new string[] {
    "CommonUI", "GameplayTags", // Activatable widgets, buttons, action router, FUIInputConfig; FBindUIActionArgs' FUIActionTag links GameplayTags
    "CommonInput", "EnhancedInput", // UCommonInputSubsystem, ECommonInputType/Mode; UInputAction UPROPERTYs
    "ModelViewViewModel",  // MVVM (Beta in 5.8)
    "FieldNotification" }); // Field-notification declaration macros

Deprecated — do not use

Do not emitUse in 5.8Source
UUserWidget::RemoveFromViewport()RemoveFromParent()UE_DEPRECATED(5.1) in Blueprint/UserWidget.h:356
UUMGSequencePlayer* returned from PlayAnimationFWidgetAnimationHandle / FWidgetAnimationStateUE_DEPRECATED(5.6) in Animation/UMGSequencePlayer.h:29
UUserWidget::ActiveSequencePlayers / StoppedSequencePlayersActiveAnimationsUE_DEPRECATED(5.6) in Blueprint/UserWidget.h:1491,1499
UUserWidget::InitializeInputComponent()bAutomaticallyRegisterInputOnConstructionUE_DEPRECATED(5.7) in Blueprint/UserWidget.h:1713
FWidgetStateBitfield enum-state accessorsBinary and named states onlyUE_DEPRECATED(5.5) in Binding/States/WidgetStateBitfield.h:35
UListView::InitHorizontalEntrySpacing / InitVerticalEntrySpacingSetHorizontalEntrySpacing / SetVerticalEntrySpacingUE_DEPRECATED(5.6) in Components/ListView.h:343,346
USlateBlueprintLibrary::TransformScalarAbsoluteToLocal / TransformVectorAbsoluteToLocalScalar_LocalToAbsolute / Vector_LocalToAbsoluteUE_DEPRECATED(5.6) in Blueprint/SlateBlueprintLibrary.h:77,87
UGameViewportSubsystem::Get(UWorld*)UGameViewportSubsystem::Get()UE_DEPRECATED(5.8) in Blueprint/GameViewportSubsystem.h:64
UButton::WidgetStyle / ColorAndOpacity / ClickMethod direct field accessSetStyle / SetColorAndOpacity / SetClickMethodUE_DEPRECATED(5.2) in Components/Button.h:37,42,52
UCommonUIActionRouterUCommonUIActionRouterBaseClass name in Input/CommonUIActionRouterBase.h:66
RegisterLinkedPreprocessor(Widget, Processor, int32 DesiredIndex)overload taking FInputPreprocessorRegistrationKeyUE_DEPRECATED(5.5) in Input/CommonUIActionRouterBase.h:87
FUIActionBinding::TryCreate(Widget, Args)TryCreate(Widget, Args, UserIndex)UE_DEPRECATED(5.6) in Input/UIActionBinding.h:35
FOnRerouteTouchInputDelegate, UCommonGameViewportClient::OnRerouteTouchInput()FTouchRerouteDelegate, GetRerouteTouchRegistration() / GetRerouteTouchDelegate()UE_DEPRECATED(5.8) in CommonGameViewportClient.h:15,47
#include "Input/CommonInputMode.h" (CommonUI)#include "CommonInputModeTypes.h" (CommonInput)UE_DEPRECATED_HEADER(5.1) in Input/CommonInputMode.h
UMVVMViewModelBase::K2_BroadcastFieldValueChangedthe generated property setterUE_DEPRECATED(5.3) in MVVMViewModelBase.h:71

Common Mistakes

Binding in NativeConstruct without unbinding: NativeConstruct runs again every time the widget is re-added, so an unpaired AddDynamic there binds twice. Bind once in NativeOnInitialized (bound widgets are already valid there), or pair NativeConstruct with NativeDestruct — never bind in NativeTick.

Using SetVisibility(Hidden) to close a menu: the widget still occupies layout and stays in the viewport (rooted). Call RemoveFromParent(), or SetVisibility(ESlateVisibility::Collapsed) if it must stay in the tree.

CreateWidget(GetWorld(), ...) for player UI: pass the owning APlayerController so the widget has a local player, split-screen works, and GetOwningPlayer() is valid.

AddDynamic on UCommonButtonBase::OnClicked(): it returns FCommonButtonEvent (a DECLARE_EVENT, not a dynamic delegate). Use AddUObject in NativeOnActivated and RemoveAll(this) in NativeOnDeactivated.

Skipping Super::NativeOnActivated / Super::NativeOnDeactivated: the Super calls broadcast OnActivated() / OnDeactivated(), which the widget's activation-tree node listens to (UIActionRouterTypes.cpp:1372), and push/pop InputMapping, so focus, back handling and input config stop working without them.

No UPROPERTY after RemoveFromParent: the widget is unrooted and collectable. Hold a UPROPERTY() TObjectPtr<> if you intend to re-add it.

Unspecified Z-order: widgets added at the same Z-order have undefined draw order. Pass an explicit value to AddToViewport(ZOrder) and reserve ranges (for example HUD 0-9, menus 10-19, popups 20+). Slate ticks a widget from its paint pass (SWidget.cpp:1511), so NativeTick stops while it is Hidden or Collapsed — do not rely on NativeTick to un-hide it.

Calling SetInputMode under Common UI: it bypasses the activation tree and fights the router. Return an FUIInputConfig from GetDesiredInputConfig() instead.

  • ue-input-system — Enhanced Input, input mapping contexts, FInputModeUIOnly / FInputModeGameAndUI / FInputModeGameOnly, input priority
  • ue-gameplay-framework — where HUD/PlayerController create and own widgets, split-screen ownership
  • ue-cpp-foundations — UPROPERTY/UFUNCTION specifiers, TObjectPtr, GC rules, subsystems
  • ue-editor-tools — Slate in detail customisations, editor utility widgets, UToolMenus
  • ue-materials-rendering — UI materials, UMaterialInstanceDynamic parameters driven from widgets
  • ue-data-assets-tables — data assets and data tables that back list items and icon sets
  • ue-gameplay-abilities — attribute change delegates that drive health/resource bars
  • ue-blueprint-cpp-interop — exposing C++ to Blueprint: UFUNCTION/UPROPERTY meta keys, latent actions and async nodes
  • ue-gameplay-cameras — spring arms, view targets, camera modifiers, shakes and the Gameplay Camera System

© quodsoler, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in skills/ue-ui-umg-slate of quodsoler/unreal-engine-skills.

  • SKILL.md
  • references/common-ui-setup.md
  • references/slate-patterns.md
  • references/widget-types.md

Open the folder on GitHubat commit f3742d7

Compare with similar skills

Ue UI Umg Slate next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Ue UI Umg Slate compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Ue UI Umg Slate this skillquodsoler/unreal-engine-skills362—~7.4kAutomated safety check: PassMIT
Ue Specifiersfjz13/UnrealSpecifiers1.1k—~1.4kAutomated safety check: PassCustom licence
Unreal Engine MCPEpicGames/unreal-engine-skills-for-claude-code-plugin338—~1.8kAutomated safety check: PassMIT
Unreal Live CodingItalink/UnrealClientProtocol127—~1kAutomated safety check: PassMIT
Unreal Cpp Gameplayukanwat/overtime3871 repos~1.5kAutomated safety check: PassApache-2.0
Unreal Enhanced Inputukanwat/overtime3871 repos~1.5kAutomated safety check: PassApache-2.0

Similar skills

  • Ue Specifiers

    fjz13/UnrealSpecifiers

    A skill your agent uses when writing, editing, reviewing, validating, or explaining Unreal Engine C++ reflected declarations: UCLASS, USTRUCT, UENUM, UINTERFACE, UPROPERTY, UFUNCTION, UPARAM, UMETA…

    1.1k GitHub stars~1.4k tokensUpdated 4 mo ago
    Game DevelopmentAuto-check passed
  • Unreal Engine MCP

    EpicGames/unreal-engine-skills-for-claude-code-plugin

    Drives a live Unreal Editor through the unreal-mcp server: spawn actors, edit Blueprints, materials and sequences, change properties and trigger Live Coding.

    338 GitHub stars~1.8k tokensUpdated 24 days ago
    Game DevelopmentAuto-check passed
  • Unreal Live Coding

    Italink/UnrealClientProtocol

    Trigger Live Coding compilation via UCP. An agent skill from Italink/UnrealClientProtocol.

    127 GitHub stars~1k tokensUpdated 1 mo ago
    Game DevelopmentAuto-check passed
  • Unreal Cpp Gameplay

    ukanwat/overtime

    Write Unreal Engine 5 C++ gameplay code: the UCLASS/UPROPERTY/UFUNCTION reflection macros, the Gameplay Framework (GameMode, Pawn, Character, PlayerController, Actor components), and the module…

    387 GitHub starsUsed in 1 repo~1.5k tokens
    Game DevelopmentAuto-check passed
  • Unreal Enhanced Input

    ukanwat/overtime

    Set up player input in Unreal Engine 5 with Enhanced Input: Input Actions, Input Mapping Contexts, modifiers and triggers, adding the mapping context, and binding actions by ETriggerEvent.

    387 GitHub starsUsed in 1 repo~1.5k tokens
    Game DevelopmentAuto-check passed
  • Unreal Niagara

    ukanwat/overtime

    Create and control VFX in Unreal Engine 5 with Niagara: systems and emitters, modules and the spawn/update stages, exposed User parameters, and spawning or driving effects from Blueprints or C++.

    387 GitHub starsUsed in 1 repo~1.5k tokens
    Game DevelopmentAuto-check passed

More from quodsoler/unreal-engine-skills

All 31 skills in this repo
  • Unreal Actor-Component Architecture

    quodsoler/unreal-engine-skills

    Unreal Engine C++ guidance for AActor and UActorComponent: lifecycle hooks, spawning, component creation and attachment, ticking, interfaces and composition.

    362 GitHub stars~7.5k tokensUpdated 12 days ago
    Auto-check passed
  • Unreal Engine AI and Navigation

    quodsoler/unreal-engine-skills

    Guides Unreal Engine C++ AI work across AI controllers, behavior trees, blackboards, perception, navmesh pathfinding, EQS and Smart Objects.

    362 GitHub stars~8.9k tokensUpdated 12 days ago
    Auto-check passed
  • Unreal Engine Animation System

    quodsoler/unreal-engine-skills

    Reference for writing and debugging Unreal Engine 5.8 animation C++: AnimInstance and proxy, montages, notifies, curves, blend spaces, state machines, linked layers and root motion.

    362 GitHub stars~7k tokensUpdated 12 days ago
    Auto-check passed
  • Unreal Engine Async and Threading

    quodsoler/unreal-engine-skills

    Picks and applies the right Unreal Engine C++ concurrency API, from UE::Tasks and FPipe to ParallelFor, FRunnable, locks and timers, with game-thread safety rules.

    362 GitHub stars~8k tokensUpdated 12 days ago
    Auto-check passed
  • Ue Audio System

    quodsoler/unreal-engine-skills

    A skill your agent uses when playing, mixing or debugging sound in Unreal Engine — one-shot SFX, looping ambience, music, dialogue or procedural audio.

    362 GitHub stars~7.9k tokensUpdated 12 days ago
    Auto-check passed
  • Unreal Blueprint and C++ Interop

    quodsoler/unreal-engine-skills

    Reference for exposing Unreal Engine C++ to Blueprint and calling Blueprint from C++, covering UFUNCTION and UPROPERTY specifiers, latent and async nodes, and interfaces.

    362 GitHub stars~7.8k tokensUpdated 12 days ago
    Auto-check passed

Questions about Ue UI Umg Slate

What does Ue UI Umg Slate do?

A skill your agent uses when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models. Ue UI Umg Slate is an agent skill from quodsoler/unreal-engine-skills. Use when writing or fixing Unreal Engine UI in C++ — UMG user widgets, Slate widgets, Common UI screens, or MVVM view models.

When should I use Ue UI Umg Slate?

Ue UI Umg Slate fits situations like: fixing Unreal Engine UI in C++ — UMG user widgets; common UI screens; MVVM view models; the user mentions UUserWidget.

How do I install Ue UI Umg Slate in Claude Code?

Run `npx skills add quodsoler/unreal-engine-skills --skill ue-ui-umg-slate -a claude-code`. Or copy the skill folder (skills/ue-ui-umg-slate in quodsoler/unreal-engine-skills) into .claude/skills/ue-ui-umg-slate in your project. Claude Code loads it when a task matches its description.

How do I install Ue UI Umg Slate in Codex?

Run `npx skills add quodsoler/unreal-engine-skills --skill ue-ui-umg-slate -a codex`. Or copy the skill folder (skills/ue-ui-umg-slate in quodsoler/unreal-engine-skills) into .agents/skills/ue-ui-umg-slate in your project. Codex loads it when a task matches its description.

Can I use Ue UI Umg Slate in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add quodsoler/unreal-engine-skills --skill ue-ui-umg-slate -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ue-ui-umg-slate, .gemini/skills/ue-ui-umg-slate, .github/skills/ue-ui-umg-slate and .opencode/skills/ue-ui-umg-slate in your project.

What does Ue UI Umg Slate need to run?

SKILL.md names no scripts, command-line tools or credentials: Ue UI Umg Slate is instructions for the agent only.

Does Ue UI Umg Slate access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Ue UI Umg Slate safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Ue UI Umg Slate use?

Ue UI Umg Slate is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Ue UI Umg Slate use?

About 7.4k tokens (SKILL.md is roughly 30k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 14k tokens, read only when the agent opens those files.

What are the alternatives to Ue UI Umg Slate?

Skills that share tags, products or a category with Ue UI Umg Slate: Ue Specifiers (fjz13/UnrealSpecifiers, 1.1k stars), Unreal Engine MCP (EpicGames/unreal-engine-skills-for-claude-code-plugin, 338 stars), Unreal Live Coding (Italink/UnrealClientProtocol, 127 stars) and Unreal Cpp Gameplay (ukanwat/overtime, 387 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Ue UI Umg Slate?

quodsoler (a GitHub user) maintains it in quodsoler/unreal-engine-skills, which has 362 GitHub stars. The repository holds 31 skills in this directory. The repository was last updated on September 28, 2026.

Source: quodsoler/unreal-engine-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.