[UE4]Slate and Native UMG(C++) Notes
Keywords: UE4, Native UMG, Slate, Common API, Usage, Case
Native UMG APIs In Common
How to set UButton’s Image Texture for Normal, Hovered and Pressed state
MyButton->WidgetStyle.Normal.SetResourceObject(TextureRes);
How to get the size of widget
Get actual size of widget:
FVector2D UWidget::GetDesiredSize() const
Usage of GetDesiredSize
:
void UMyWidget::AddToScreen(ULocalPlayer* LocalPlayer, int32 ZOrder)
{
Super::AddToScreen(LocalPlayer, ZOrder);
Super::ForceLayoutPrepass();
FVector2D Size = GetDesiredSize();
}
GetDesiredSize()
isn’t usable before NativeTick()
triggered, if you want to get the widget size when widget initilized, you need to call function Super::ForceLayoutPrepass()
. If you add a child in widget and want to show it on viewport at this frame, you also need to call this function too.
Get size using slot:
//ImgIcon is a UImage widget.
if (UCanvasPanelSlot* Slot = Cast<UCanvasPanelSlot>(ImgIcon->Slot))
{
FVector2D Size = Slot->GetSize();
}
Get size from Texture2D resource:
//ImgIcon is a UImage widget.
if (UTexture2D* Tex = Cast<UTexture2D>(ImgIcon->Brush.GetResourceObject()))
{
int32 X = Tex->GetSizeX();
}
Using CachedGeometry:
const FVector2D& IconLocSize = ImgIcon->GetCachedGeometry().GetLocalSize();
const FVector2D& IconAbsSize = ImgIcon->GetCachedGeometry().GetAbsoluteSize();
How to set the size of widget
//ImgIcon is a UImage widget.
if (UCanvasPanelSlot* Slot = Cast<UCanvasPanelSlot>(ImgIcon->Slot))
{
Slot->SetSize(FVector2D(100.f, 100.f));
}
How to set the size of UserWidget(whole UMG UI)
void UUserWidget::SetDesiredSizeInViewport(FVector2D DesiredSize);
How to get the position of widget
//ImgIcon is a UImage widget.
if (UCanvasPanelSlot* Slot = Cast<UCanvasPanelSlot>(ImgIcon->Slot))
{
FVector2D Pos = Slot->GetPosition();
}
Using CachedGeometry:
ImgIcon->GetCachedGeometry().GetAbsolutePosition();
How to set the position of widget (Modify widget’s screen position at run-time)
void UWidget::SetRenderTranslation(FVector2D Translation)
How to set the position of UserWidget
void UUserWidget::SetPositionInViewport(FVector2D Position, bool bRemoveDPIScale )
How to scale the widget
void UWidget::SetRenderScale(FVector2D Scale)
How to get the screen size
auto geometry = MyWidget->GetCachedGeometry();
auto localSize = geometry.GetLocalSize();
auto screenPosition = geometry.LocalToAbsolute(FVector2D(0, 0)); //TopLeft
auto screenSize = geometry.LocalToAbsolute(localSize) - screenPosition; // BotRight-TopLeft = real size
How to rotate a widget
void UWidget::SetRenderAngle(float Angle); //Angle range: (-180, 180)
Mouse clicked position on widget
FReply UMiniMapUI::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
//Translates a screen position in pixels into the local space of a widget with the given geometry.
FVector2D ScreenPos;
USlateBlueprintLibrary::ScreenToWidgetLocal(this, InGeometry, InMouseEvent.GetScreenSpacePosition(), ScreenPos);
//Transforms AbsoluteCoordinate into the local space of this Geometry.
FVector2D LocalWidgetMousePos = USlateBlueprintLibrary::AbsoluteToLocal(InGeometry, InMouseEvent.GetScreenSpacePosition());
return FReply::Handled();
}
NativeConstruct’s trigger timing
if(UMyUserWidget* Widget = WidgetTree->ConstructWidget<UMyUserWidget>(UMyUserWidget::StaticClass()))
{
//UMyUserWidget::NativeConstruct() would trigger after be AddChild
MyCanvasPanel->AddChild(Widget);
}
UMyUserWidget::NativeConstruct()
would trigger after be AddChild
How to get content of TextBox (Textblock)
FText txt = TxtboxCmdInput->GetText();
Native UMG Cases
Create CanvasPanel As Root Wdiget at Run-time and Add Button Inside It.
void UMyUserWidget::NativeConstruct()
{
Super::NativeConstruct();
auto MyCanvas = WidgetTree->ConstructWidget<UCanvasPanel>(UCanvasPanel::StaticClass());
if(MyCanvas)
{
auto MyButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass());
MyCanvas->AddChild(MyButton);
WidgetTree->RootWidget = MyCanvas;
}
}
Reference: Create widget in pure C++
https://answers.unrealengine.com/questions/470481/create-widget-in-pure-c.html
Filling HorizontalBoxSlot At Run-time
void UBags::NativeConstruct()
{
Super::NativeConstruct();
//Get HorizontalBox in Widget Blueprint.
UHorizontalBox* HorBox = Cast<UHorizontalBox>(GetWidgetFromName(FName("HorizontalBox_62")));
if (HorBox)
{
//Load Item Blueprint
if (UClass* MyWidgetClass = LoadClass<UMyItemWidget>(NULL, TEXT("WidgetBlueprint'/Game/UI/ItemBP.ItemBP_C'")))
{
for (int i = 0; i < 5; i++)
{
FString ChildID = FString::Printf(TEXT("MyWidget_%d"), i);
UMyItemWidget* Item = WidgetTree->ConstructWidget<UMyItemWidget>(MyWidgetClass, ChildID);
UPanelSlot* Slot = HorBox->AddChild(Item);
if (UHorizontalBoxSlot* HorSlot = Cast<UHorizontalBoxSlot>(Slot))
{
//Set Size Mode as Fill
FSlateChildSize Size(ESlateSizeRule::Type::Fill);
HorSlot->SetSize(Size);
//Set Align as Center in Horizontal direction.
HorSlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Center);
//Set Align as Center in Vertical direction.
HorSlot->SetVerticalAlignment(EVerticalAlignment::VAlign_Center);
}
}
}
}
}
You must pass different argument WidgetName
for each child widget when create multiple child using WidgetTree->ConstructWidget()
, otherwise events (e.g. OnClicked) of child widget will not work.
Filling UniformGridPanel At Run-time
void UMyUserWidget::NativeConstruct()
{
Super::NativeConstruct();
//Get UniformGridPanel in Widget Blueprint.
UUniformGridPanel* UniGrid = Cast<UUniformGridPanel>(GetWidgetFromName(FName("UniformGridPanel_01")));
if (UniGrid)
{
UButton* MyButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass());
if(UUniformGridSlot* Slot = UniGrid->AddChildToUniformGrid(MyButton))
{
//Set the horizontal index and vertical index of Grid.
Slot->SetRow(5);
Slot->SetColumn(5);
}
}
}
Get And Set index of Grid of UniformGridPanel In Batch
TArray<UPanelSlot*> Slots = UniformGridPanel->GetSlots();
int index = 0;
for (UPanelSlot* Slot : Slots)
{
UUniformGridSlot * UniSlot = Cast<UUniformGridSlot>(Slot);
if (UniSlot)
{
UniSlot->SetRow(index);
UniSlot->SetColumn(1);
}
index++;
}
How to scale or zoom a widget?
For Mouse Zoom:
- override onMouseWheel
- add Wheel Delta to Panning Canvas’ Render Transform Scale
- clamp min result to something above 0 (widgets flip if scaled below 0) and max to your desired max zoom
- Set Render Scale of the Panning Canvas with the result of the above
Reference: How to scale/zoom a widget with blueprints?
https://answers.unrealengine.com/questions/815202/how-to-scalezoom-a-widget-with-blueprints.html
How to clip widget display area?
Steps:
- Add a CanvasPanel as the parent of your target widget
- set the
Clipping
of CanvasPanel toClip to Bounds
then the part outside CanvasPanel of your target widget would be clipped.
How to alter widget self’s anchor to the center of itself.
Put the widget into a UCanvasPanel, then set Alignment of this UCanvasPanel as (0.5f, 0.5f):
CanvasPanelSlot->SetAlignment(FVector2D(0.5f, 0.5f));
Alignment
may not work properly in PIE(I think it’s a bug), you’d better test it in package.
If UserWidget A is child of UserWidget B, UserWidget A’s Alignment need to be set in UserWidget B, not UserWidget A!!!
How to fade in / out widget
Event for fade begin:
LerpTime = 0.f;
LerpDuration = 1.5f;
FLinearColor SrcColor = MyTextBlock->ColorAndOpacity.GetSpecifiedColor();
FLinearColor DestColor = SrcColor;
DestColor.A = 0.f;
in Tick()
if (LerpTime < LerpDuration)
{
LerpTime += DeltaSeconds;
FLinearColor Color = FMath::Lerp<FLinearColor>(SrcColor, DestColor, LerpTime / LerpDuration);
MyTextBlock->SetColorAndOpacity(Color);
}
Why UMG’s Event OnKeyDown/OnKeyUp is not fired
Solution:
Set Is Focusable
enable, and execute SetKeyboardFocus()
.
void UMyUserWidget::NativeConstruct()
{
Super::NativeConstruct();
bIsFocusable = true;
SetKeyboardFocus();
}
How to get Widget by Class in current UserWidget
Get all Widget first.
use:
void UWidgetTree::GetAllWidgets(TArray<UWidget*>& Widgets) const
or:
void ForEachWidget(TFunctionRef<void(UWidget*)> Predicate) const;
Then check Widget type:
if(ChildWidget->IsA(UButton::StaticClass()))
{
}
Example:
void UMyUserWidget::NativeConstruct()
{
Super::NativeConstruct();
if (WidgetTree)
{
TArray<UWidget*> Widgets;
WidgetTree->GetAllWidgets(Widgets);
for (UWidget* Widget : Widgets)
{
if (Widget && Widget->IsA(UButton::StaticClass()))
{
if (UButton* Btn = Cast<UButton>(Widget))
{
FScriptDelegate Del;
Del.BindUFunction(this, TEXT("PlayBtnOnClickSound"));
Btn->OnClicked.Add(Del);
}
}
}
}
}
How to make WidgetComponent looks like a billboard?
UWidgetComponent::SetWidgetSpace(EWidgetSpace::Screen);
example:
if (!WidgetComp)
{
WidgetComp = CreateDefaultSubobject<UWidgetComponent>(TEXT("WidgetComponent"));
WidgetComp->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
WidgetComp->SetWidgetClass(MyUIClass);
WidgetComp->SetVisibility(true);
WidgetComp->SetWidgetSpace(EWidgetSpace::Screen);
}
UWidgetLayoutLibrary
How to get the scale of viewport
FVector2D UWidgetLayoutLibrary::GetViewportScale(UObject* WorldContextObject);
How to get the viewport size
FVector2D UWidgetLayoutLibrary::GetViewportSize(UObject* WorldContextObject);
void APlayerController::GetViewportSize(int32& SizeX, int32& SizeY) const;
How to get the Geometry of all widgets in Viewport or PlayerScreen
FGeometry UWidgetLayoutLibrary::GetViewportWidgetGeometry(UObject* WorldContextObject);
FGeometry UWidgetLayoutLibrary::GetPlayerScreenWidgetGeometry(APlayerController* PlayerController);
How to get mouse position
//Gets the platform's mouse cursor position. This is the 'absolute' desktop location of the mouse.
FVector2D UWidgetLayoutLibrary::GetMousePositionOnPlatform();
//Gets the platform's mouse cursor position in the local space of the viewport widget.
FVector2D UWidgetLayoutLibrary::GetMousePositionOnViewport(UObject* WorldContextObject);
How to removes all widgets from the viewport
void UWidgetLayoutLibrary::RemoveAllWidgets(UObject* WorldContextObject);
UMG Blueprint Case
How to center my widgets
Set up the widget as follows:
- Parent it to your main widget.
- Anchor it to
(0.5, 0.5)
. - Set Alignment to
(0.5, 0.5)
. - Set position to
(0, 0)
.
Reference:
https://answers.unrealengine.com/questions/342663/view.html
How to set the scrollbox child button size?
Using a Size Box to wrap the button, and set the Width Override
and Height Override
of Size Box.
Reference:
https://forums.unrealengine.com/t/how-to-set-the-scrollbox-child-button-size/151275/2
Issues
TextBox doesn’t reset input data even re-create widget (UMG cache)
Caused by:
Parameter WidgetName
isn’t null. e.g.:
MyWidget = CreateWidget<UBaseUserWidget>(MyPlayerController, widgetClass, TEXT("TestWidget"));
Solution:
Pass parameter WidgetName
with default value:
MyWidget = CreateWidget<UBaseUserWidget>(MyPlayerController, widgetClass);
Cursor disappeared after clicking button
If there is a button in UMG and the mouse cursor disappears as soon as the mouse is placed on it when the game is running, the reason is that the IsFocusable
property of the button is set to false.
你讨厌的昨天,是再也回不去的从前。你喜欢的未来,是某一天会怀念的现在。 ---莫书