#slate
1 messages ยท Page 19 of 1
Isn't that creating tons of alpha space?
There is lots of UI parts that don't fit that rule at all
- when putting this into proper containers, it creates padding that might not be wanted :x
Well, like I said most our images are icons or analog
But we also never display images at their real resolution
We develop for 1080p with 4K assets scaled down, and support anything up to slightly less than 720p
Including 21:9 or 4:3 aspect ratios
So it doesn't matter if your image was meant to be 300x300 when it could be 512x512, since it gets scaled down anyway
is Canvas included into packaging process ? After package I got all c++/blueprint classess included, and their logic is executed, but I can't see any DrawTexture/DrawLine that has been executed in DrawHUD
It definitely is
@low bluff hey I just saw your post on top regarding loading scene. I've been trying to add a random "help" type umg to loading screen. I've got the default ue4 test screen that shows on loading but trouble finding any help on how to reference in c++ a umg and I guess convert it to slate? So it'll load. Does your fine self have an example?
SNew(SLoadingScreen_Base).InLoadingScreenImages(LoadingScreens); looks like it's pointing at something like I would need to
@primal sphinx I'm actively using slate
SLoadingScreen_Base is a slate widget
I'm not using UMG
figured, just trying to figure if i have to convert to slate or if its just a matter of knowing better what i'm doing to use umg in movieplayer
Well TECHNICALLY you can grab the Slate Widget from a UUserWidget
BUT, I heard that this doesn't 100% work
Anyone knows if you can use Slate args style for callbacks on a FSlot ?
Like MyType::FSlot().Callback(this, &MyUSerType::GetValue)
hmmmm i don't mind slate i'm not trying to animate or anything just a fullscreen image wit hsome "tips" but i'd like it to change so not always the same
Oh well, there it goes
.Visible(TAttribute<bool>::FGetter::CreateSP(this, &MainMenu::IsMemoryVisible))```
๐ค
@primal sphinx Well the easiest setup is really just a simple slate widget with an image
And then creating that in the GameInstance via the LoadingScreen stuff
And passing it an array of images
I can give you the code in DM if you want that
I'd definitely appreciate any help
Okay just gimma a few min, currently fixing some other stuff
no prob take your time ๐
Hey guys, I've defined style for table row FTableRowStyle. How can I update the ListView AssignNew(TasksListWidget, SListView<FTaskRow>) with new style? The style is assigned via .OnGenerateRow(this, &FTaskEditorDetailCustomization::OnGenerateRowForList) callback...I can't figure it out how to assign new style once the list is created...
@quaint zealot yes. But it has still the same style defined. I've tried to shutdown and reinit the style, but it's not clean solution I guess. Tomorrow I try to pass the .Style different way
What does STreeView want exactly to be able to expand items beyond first nested set?
It seems to obtain the children as intended, but it doesn't let me expand them beyond the root D:
@manic rampart If you're still stuck with this, it's probably down to the weird way they built their item system on shared pointers. Basically, you need to make sure you create a shared instance of each item only once.
If you recreate them each time it asks for children, you'll confuse it and things won't expand properly.
Yeah I figured that out, sorry for not posting it
I simply cached the list of generated children on first call and that was sufficient
No worries. Had the same issue recently and took me a while to work out what was going on.
I thought it was stupid at first, but I guess the pointer value of the child has some meaning internally
Basically their whole system (same for list/combo boxes) is built on the idea of the pointer value being used to identify items.
It's definitely pretty stupid as far as I'm concerned.
I think I want to start using Slate a little more than just adding a button to the editor UI. Any suggestions? I can create a new widget, sure, but that's like being able to write a class in C++. Big whoop.
Not really sure of the how things 'should' be done/structured, for example.
If ya'll got some preferred learning resource for Slate in gameplay, please sling it my way.
For example, the Helium Rain source has this MenuManager they pass around to all Slate widgets (https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/Player/FlareMenuManager.h), and which seems to be some central router/control for all UI. I have no idea if this is the norm or what.
Eheheh
@tropic sparrow For what it's worth, I would say this was working, but not super comfortable because we made this UI class responsible for gameplay - loading levels etc.
I've kept the approach in my next project, but the UI is now working more like an observer of the game
As far as organizing your UI goes, I think its good to have a single point of contact like that
@quaint zealot Ahh okay, cool. That's something to watch out for I guess! So each widget holds a pointer to the UI manager, but it's the UI manager that controls the widgets?
I guess it must be bidirectional
Basically the UI manager is responsible for creating the widgets and passing "open" - close" type commands to them, so acts as a high-level interface for the game
What we did wrong was this : for something like "load game", we want 1. Fade to black 2. load the game 3. Fade back from black, but the loading was done from the menu
And that's terrible design, we should have used a callback instead, as in 1. "fade to black, tell me when done" 2. callback, code still on caller's side 3. resume menu by fading back
Instead we have weird loops between gameplay code and the menu internals
Right okay, that's interesting. I see you just create all widgets and add them to the viewport up-front. I guess there are downsides to this?
And yeah I can see the gameplay stuff, you mean like this in AFlareMenuManager::Tick?
// Skirmish countdown
if (GetGame()->IsSkirmish())
{
if (SkirmishCountdownTimer >= 0)
{
SkirmishCountdownTimer += DeltaSeconds;
if (SkirmishCountdownTimer > SkirmishCountdownDuration)
{
SkirmishCountdownTimer = -1;
OpenMenu(EFlareMenu::MENU_SkirmishScore);
}
}
}
else
{
SkirmishCountdownTimer = -1;
}
I'm scared that this class ends up in essentially a bunch of huge if-else chains, but I guess it's hard to avoid?
Take a look at UT if you want to know how you could structure it
Yeah good call
Iirc their structure is:
- Menu per GameMode (GameMode holds class)
- Menu's can have Dialogs and something like "pages" (so the thing between top and bottom menu bar)
- Dialogs can be opened ontop of Menus and each other
- HUD holds Widgets that aren't interactable
- HUD goes over all class in the Widget Array (same parent) and add them to the canvaspanel + make sure they position themselves.
So in your example:
SkirmishCountdownTimer can just be "CountdownTimer", cause why an extra variable if there is always only one timer at a time active
OpenMenu would tell the LocalPlayer to ask the GameMode to open the MenuClass Widget that is stored in it
You can pass something along via Parameters (FString)
If you need the Menu to do something special than normal
We use that in Hoverloop to open the MainMenu directly to go into the Garage for Splitscreen players.
e.g. OpenMenu("Garage");
(Sorry, to be clear - the above example is from Helium Rain. I ain't that far along yet ๐ )
Alright
I should write a "tutorial" sorts of things for UMG UI structure and focus navigation with Gamepads >.>
But no time
Hell, even things on general UI structure wrt Slate would be neat. Before this conversation tonight the furthest I knew was to cram my widgets onto my HUD class and create in BeginPlay, and that was it.
Thanks for the help, folks. I have one last query with an example (more to try to understand the UI vs game split rather than "Help me write this").
This is an example of UI that's dependent on game state - there's a line drawn per unit so if a unit dies, the line is no longer drawn, the lines are dependent on unit positions, etc. Generally speaking, how is this split managed in Slate?
I doubt you'd directly give any widgets their own list of units... so some kind of callback maybe?
@tropic sparrow Well, actually, we typically pass a gameplay object as a pointer to a widget
As in "display stuff for that thing"
I would let each unit tell the UI that it wants that stuff to be drawn
Then you don't have to manage any lists
Cause each unit can manage that stuff
pass them as weak pointers if you are passing a reference to an actor
@tropic sparrow I would have a pool of widgets and a manager that activates/deactivates them based on the game state. Each widget would have the minimal amount of info it needs to display itself. Whether it gets it directly from a pointer ot the object, or from function parameters set by the manager (e.g. RefreshState(int32 health, FVector2D& direction )), depends on how much info.
@mild oracle right, in the above example I had envisioned a single widget for all of the lines, just using the line draw functionality in Slate. In that case I would hold all of the objects / have a RefreshState that passes all objects.
But for per-unit things in a game like health bars, they'd definitely be separate widgets, yeah?
@tropic sparrow Generally, separate widgets unless you have good reason to believe it's a performance bottleneck. But yeah, if you know you have to draw thousands of lines, you can pretty much see in advance that you'll need to deal with them in bulk.
Most important thing from design point of view is to minimize dependencies, and make them only one way. UI stuff has dependency on game objects (or an intermediate interface if you really want to go all out), game objects know nothing about UI widgets.
So your widgets pull data from game, and only when necessary by having delegates on your game object/interface that the widget subscribes to to get notifications when something changed.
@limpid atlas Thanks, that helps. What about in the case of needing to add/remove as units are created/destroyed? I've done that kind of thing before with static delegates for those cases in the base unit class and having some widget-creator subscribe to them
Do you end up with a whole bunch of widget managers? ๐ฟ
Yeah, I'd say same overall idea, but using a manager. So the manager subscribes to game delegates to get notified when it needs to create or destroy widgets.
You can have a bunch, or one manager to handle everything I guess. I think either is fine.
Okay cool, that works. For the case of showing/hiding those gameplay widgets (maybe when switching to another menu or something, or other transitions), does it make sense to add these individual unit widgets as children of some other widget? So you essentially have a single widget you can manipulate that contains all of those. Not sure if common.
If they're per-unit, would one stick with 3d widgets on the actual actors or is it common to keep them 2d and position based on projecting into screen space and possibly scaling based on distance manually?
@limpid atlas (forgot to tag reply)
Definitely project if you have a lot. Widget components won't let you do any kind of batching optimizations.
And yeah nothing wrong with parenting them all to one widget for easy manipulation I guess. They all have to be parented to some widget anyway.
Good point on batching - I wasn't aware you could do that (but makes sense). Is that just performing your widget draws manually, or setting some flags for the engine, or something else?
I'm gonna take a better look through Helium Rain and possibly UT. Any other decent, publicly-available resources or source code wrt Slate?
@tropic sparrow ShooterGame does Slate too
@quaint zealot Thanks! I just noticed your menu manager is an AHUD subclass, which you spawn manually. Did that make it easier somehow to work with your UI?
I've never seen that before
Pretty sure that's totally up to you
Never seen or heard anyone spawning a second HUD singleton
If that made it easier for them it doesn't need to make it easier for you
I would stick to the HUD that Epic already spawns for you
At least for now
It's a bti weird
For my next project I still use the HUD class, but it's the real HUD
I mean, having a Manager Singleton is kinda fine
Would be more interested why it hast to be an AHUD Child though
vs using the HUD that is already existing or using a Component on the PC
@low bluff Oh yeah, I know it's not necessary. I just figured there might be a good/interesting reason
Do you hang your widgets off of a HUD class as well? I was never quite clear on its purpose in the days of Slate/UMG
Not really
I do use the HUD for something, but not to store the Widgets
My Menu Widget is stored in the ULocalPlayer Class, after being created and returned by the DefaultObject of the GameMode
My Dialog Widgets are also stored in the LocalPlayer
My HUD Widget (not the AHUD Class) is created and stored in the PlayerController
And the Widets inside of the HUD are stored, well inside of the HUD (again WIDGET not AHUD class)
The only thing I use the HUD Class for is to react to MatchStates being changed and then tell the LocalPlayer to open/hide the menu etc.
I rooted this through the AHUD to the LocalPlayer (even though I'm going over the ULocalPlayer already in the OnRepMatchState function), cause LocalPlayer exists even in the MainMenu.
And there I didn't want it to react to the MatchState being changed. My AHUD only exists in the GamePlay GameModes, so that filters it
@tropic sparrow
Ahh cool, thanks for that. So you don't have some overarching 'manager' that can handle both main gameplay widget and menu widgets, main menu, etc?
I actually barely touch the HUD (gameplay) widgets
They handle themselves
They get added at the start of the game and then they get told to setup themselves
They basically have all the CanvasPanelSlot variables in them
So I can tell them upfront where they will be on the Screen
Everything after that is just hiding/showing them and that is something they do internally
I don't access them from outside, at least 95% of the time
And the Menu Widget is selfcontained. So it gets created through the GameMode DefaultObject
And then it handles everything within itself by itself
Right - they poll or otherwise subscribe to game events etc, and update their own displays and children?
Yeah
Could you explain
They basically have all the CanvasPanelSlot variables in them
So I can tell them upfront where they will be on the Screen
My HUD is empty by default
It only has a CanvasPanel in it
We have a lot of different GameModes and since Widgets aren't inheriting so well, I had to make it modular
Means the HUD Widget has an Array of "UHLWidget" Classes
Every UI element is a child of UHLWidget
The HUD loops over that array at the start of the game and adds all parts
So I can swap out the elements easily (even via ini config file)
Now to position them on the screen, I gave the UHLWidget class the variables that a Canvas needs to position them
Such as "Anchor", "Size", "Position", "Alignment" etc.
After the UHLWidget gets created, I tell it to "setup". it will then get itself as a canvasslot (cause that's what it gets added to, a canvas) and sets the Alignment etc. variables
These are setup for each individual UHLWidget child upfront in its defaults
Crosshair settings
(middle of screen)
void UHLWidget::SetupWidget_Implementation(UHLHUDWidget* InOwningHUD)
{
OwningHUD = InOwningHUD;
RetrieveGameState();
RetrievePlayerState();
UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(Slot);
if (CanvasSlot)
{
CanvasSlot->SetAlignment(Alignment);
CanvasSlot->SetAnchors(Anchors);
CanvasSlot->SetPosition(Position);
CanvasSlot->SetSize(Size);
CanvasSlot->SetAutoSize(bSizeToContent);
CanvasSlot->SetZOrder(ZOrder);
}
}
@tropic sparrow
@low bluff Yeah that's an interesting way to do it! I like it. I was concerned about how to make positions etc tweakable despite writing stuff in Slate. can't imagine a designer being happy without that ability.
I'm not clear on how UMG interacts with all of these Slate-based UI setups. Can a designer still tweak things?
Yeah the only downside is that you can't see what your settings do unless you press play
I'm not using slate here though
Ahh yeah, good point
But that doesn't matter much as it's just about the structure
I kinda know how our HUD should look like
And I know what Position,Anchor etc do
So I can set that up without the designer
Yepp, that makes sense
Comparing Slate <-> UMG to C++ <-> BP paradigm... how do you make your UI... tweakable? I'm not sure of the right language to describe it (and I'm not a designer so I don't know what they would want). Is building a Slate UI kinda like a set of C++ classes (vs doing things in BP) in that you're hardcoding the structure?
Well you have two ways of working with slate I assume
Either you just use slate, then it's basically like only using C++
So whatever has to be tweaked has to be done in slate
If you however want designers to work with it, you have to expose the Slate widget
All default widgets you see in the UMG palet are slate widgets being exposed
That is done by creating yet another class
a UWidget
(Not UUserWidget)
UWidgets wrap the SWidget and then allow you to add them via the UMG Palet
So you basically create your own set of Widgets to be used in normal BP widgets
If you need stuff inside of the Slate widget to be tweakable
then you need to expose that stuff
E.g. it first needs to be a variable of sorts in the slate widget
And then it needs to also be a variable in the UWidget, which is used to set the Slate one
The UWidget one will be visible in the UMG Details panel
@tropic sparrow
Right, so it'd be like trying to expose a third-party, non-UE4 class to BP - you're creating a wrapper and pass-throughs for the variables to get them into UPROPERTY form?
I used third-party as an analogy. Yes
(Just because I've had to do that recently so it's how I related ๐ )
Yeah basically, you always need to have some sort of BP variable for what you have in C++
If there is some thirdParty Enum in C++
Then you have to create a UENUM and expose that
And write a "converter" between both
Weird that Slate wasn't built to have UPROPERTYs
Welp
Thanks for your help @low bluff. I appreciate it ๐
Anybody had any luck creating custom rich text decorators? Documentation says to inherit from FRichTextBlockDecorator - but it's not exported so it's not possible...
Okay nevermind. UHT being dumb.
RIP the last three hours
FYI don't put this in a file called SomeType.h because UHT will throw a fit.
class FSomeType : public FSomeUnreflectedType {};
UCLASS()
class USomeType : public USomeReflectedType {};
Is there an easy way with Slate to draw something outside of its parents bounds? I want to customise a button so it kind of draws outside its regular bounds
I guess I gotta subclass SButton and change how OnPaint works
Ah true
Is there a standard way to load slate assets in C++ by name?
what do you mean? you have the class name
@mild oracle Have you looked into stylesets ?
Look at how ShooterGame handles that
I'm trying to use Slate to draw a brush in the centre of the "parent" brush, but it seems to break down when I zoom in in the editor. It looks correct when at 1:1 zoom but it's wrong when I zoom in:
FVector2D Position = AllottedGeometry.GetLocalPositionAtCoordinates( FVector2D( 0.5f, 1 ) ) * AllottedGeometry.Scale - FVector2D( Size.X * 0.5f, 0 ) + Style->NormalTabOffset;
FPaintGeometry PaintGeom = AllottedGeometry.ToPaintGeometry( Position, Size, AllottedGeometry.Scale );
FSlateDrawElement::MakeBox(
OutDrawElements,
LayerId,
PaintGeom,
TabArrowBrushResource,
DrawEffects,
BrushResource->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() * BorderBackgroundColor.Get().GetColor( InWidgetStyle )
);```
Fixed:
FVector2D Size = TabArrowBrushResource->GetImageSize();
FVector2D Position = AllottedGeometry.GetLocalPositionAtCoordinates( FVector2D( 0.5f, 1 ) ) - FVector2D( Size.X * 0.5f, 0 ) + Style->NormalTabOffset;
FSlateLayoutTransform LayoutTransform = FSlateLayoutTransform( Position );
FPaintGeometry PaintGeom = AllottedGeometry.ToPaintGeometry( Size, LayoutTransform );
Hmm that didn't work either
is there any actual reason to not enable GSlateFastWidgetPath in the editor?
Does it provide significant benefit?
it seems to make SetKeyboardFocus significantly faster
without it set, it takes over 2ms
(which is ridiculous btw)
Hey friends, I've hit a problem that I don't know how to solve... I want to be able to create buttons at any location on the HUD and have them autosize
First I tried that with SCanvas and slots and it worked out fine... Until I noticed the slots of the canvas have no autosize option
as far as I can tell there are no other elements that could help me (that I know of)
anyone have any suggestions? Thanks!
it's weird that UCanvasPanelSlot has an autosize feature, but the slate slot does not
so, the autosize from UCanvasPanelSlot comes from SConstraintCanvas::FSlot* Slot;
interesting
next time you can just look at the UMG wrapper and see what it calls, because UMG is just a wrapper around slate widgets
yeah, indeed. And as to answer my own question: Just use a SConstraintCanvas since it has autosize and use Offset
Is having a static variable in SWidget::Construction() considered an acceptable practice?
I'm trying to draw a brush in slate, but I want to be able to draw only part of it and clip the rest. Is there a way of doing that?
It seems like FSlateDrawElement::MakeBox doesn't quite support all the clipping features I need
Oh wait, setting ClipToBounds on the UWidget got the effect i needed
Can someone explain Slate's LayerID stuff in OnPaint? It's not making a lot of sense
I want to call MakeBox a few times and draw various brushes
I've tried leaving LayerID unchanged, I've tried incrementing it, and it seems kind of random whether my layers are drawn correctly
is it possible to inherit FArguments somehow?
I want SButton with one more additional argument. I may set it with regular setter but it would be nice to be able to set all SButton FArguments and some new as well
Yes it's absolutely possible
I can't say I've ever used args from a parent class ๐ค but adding args is trivial
{
SLATE_BEGIN_ARGS(SClassType)
: _ArgName(ArgDefaultValue) // optional init, don't forget the _
{}
SLATE_ARGUMENT(ArgType, ArgName)
SLATE_END_ARGS()```
Construct() makes this available as InArgs._ArgName
That doesn't inherit farguments of sparentclasstype as i understand it
Argnsme is available but argument from parent aren't available
Right. I haven't tried that
Look at some of the core Slate classes that do inherit
You're bound to find one that needed that I guess ?
I don't think SLATE_BEGIN_ARGS supports that, no. :/
#define SLATE_BEGIN_ARGS( WidgetType ) \
public: \
struct FArguments : public TSlateBaseNamedArgs<WidgetType> \
{ \
typedef FArguments WidgetArgsType; \
FORCENOINLINE FArguments()```
No ability to change the parent struct/class.
Time to redeclare all the things ๐ฉ
๐ค
is it possible to add a template specialization for TSlateBaseNamedArgs<WidgetType> so it inherits ParentWidget::FArguments ?
getting into
territory there
widget reflector is quite limited :v
would be really nice if it could display all the layout info from slots
Hi guys
I having problems with slate. with erro template-id
anyone has some tips abouyt it?
Hey guys, sup? Does somebody know how to fix this? I added the padding but it's clipping the text.
Code:
void SLoadingScreenWidget::Construct(const FArguments& InArgs)
{
ChildSlot
[
SNew(SOverlay)
+ SOverlay::Slot().HAlign(HAlign_Fill).VAlign(VAlign_Fill)
[
SNew(SVerticalBox)
.Visibility(EVisibility::Visible)
+ SVerticalBox::Slot().HAlign(HAlign_Center).VAlign(VAlign_Center)
[
SNew(SImage)
.Image(InArgs._BrushTexture)
]
]
+ SOverlay::Slot().HAlign(HAlign_Left).VAlign(VAlign_Bottom).Padding(2,0,0,5)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot().HAlign(HAlign_Center).VAlign(VAlign_Top)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
[
SNew(SThrobber)
.Visibility(this, &SLoadingScreenWidget::GetLoadIndicatorVisibility)
]
]
+ SVerticalBox::Slot().HAlign(HAlign_Center).VAlign(VAlign_Top).FillHeight(1.0f)
[
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::White)
.ColorAndOpacity(FLinearColor::Blue)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 30))
.Text(NSLOCTEXT("MoviePlayerTestLoadingScreen", "Loading", "Loading, please wait!"))
.Visibility(this, &SLoadingScreenWidget::GetLoadIndicatorVisibility)
]
]
];
}
I think you have to add .AutoHeight() to some of the slots? otherwise it doesn't know to care for the height of the text
@main hedge thanks for the tip. Actually I had to add .Clipping(Inherit) to my text and it worked.
Hey folks. Does anybody know if there's a super-fast way to batch-render text in Slate?
Something similar to SMeshWidget but for text?
I've done numbers before using SMeshWidget but it's a bit of a pain
Anyone know if / how you can sample scene depth in Slate?
I would have figured it possible, but apparently it's not (using the usual methods)
No, IIRC
Dammit
I want to draw UI in 2D, then mask out elements with the cockpit mesh
And I'd really rather avoid 3D widgets
I've done exactly that though :3
oo
How did you manage it?
I want to give the illusion that the UI is being project on the cockpit glass basically
Well technically I didn't
I used the HUD class
And drawn the UI on a texture used in post process
Ahhh
But I suspect you could use the 3D widget and just keep the Slate-to-texture part
Yeah I need to draw quite a lot, so wanna avoid the 3D widget. Seems odd that slate wouldn't let you sample the GBuffers since IIRC it's all drawn after that works been done
For a HUD, the HUD class primitives ended up okay
Try that : https://www.reddit.com/r/unrealengine/comments/4wcwq9/rendering_umg_to_texture_custom_pipeline/
Might be worth a stab
Ah nice. I'll dig into that
Thanks!
Man.. light grey text on white background
GG subreddit
MessagesTextBox = SNew(SMultiLineEditableTextBox).CreateSlateTextLayout(FCreateSlateTextLayout::CreateStatic(&FCustomTextLayout::CreateLayout))
error C2664: 'TBaseDelegate<TSharedRef<FSlateTextLayout,0>,SWidget *,const FTextBlockStyle &> TBaseDelegate<TSharedRef<FSlateTextLayout,0>,SWidget *,const FTextBlockStyle &>::CreateStatic<>(TSharedRef<FSlateTextLayout,0> (__cdecl *)(SWidget *,const FTextBlockStyle &))': cannot convert argument 1 from 'TSharedRef<FSlateTextLayout,0> (__cdecl *)(FTextBlockStyle)' to 'TSharedRef<FSlateTextLayout,0> (__cdecl *)(SWidget *,const FTextBlockStyle &)'
This worked in 4.19, trying to determine what changed, and not having a ton of luck.
To make it more readable
'TSharedRef<FSlateTextLayout,0> (__cdecl *)(FTextBlockStyle)' to
'TSharedRef<FSlateTextLayout,0> (__cdecl *)(SWidget *,const FTextBlockStyle &)'
When it comes to following the power of two rule, what is the proper method to import a 16:9 image intended for a loading screen?
what is the power of two rule? ๐ค
That your textures need to be 256, 512, 1024, 2048 ect
why tho?
gpus in the last 10 years have no problems with non power of two textures
I'm sure the optimizations are minor if anything in small projects, it can add up tho
For loading screens / UI images you can avoid power of two
For in-game textures, you should be using power of 2 whenever possible
The optimizations are in fact huge, especially as the project grows
But for UI it's generally quite difficult to retain power-of-2, and it's rare that you ever need to stream UI textures anyway.
@craggy holly it's not just optimizations, Apple is limiting textures by squares power of two only (https://en.wikipedia.org/wiki/PVRTC)
btw non power of two textures have acronym NPOT
on opengl NPOTs should be divisible by 4 (i.e. 1028 is ok)
huge pro of POTs are MIP maps, you can't generate them for NPOTs
Help
Anybody know if pins can change the connector colour too?
That blue is tickling my OCD
Oh ffs. It's in EdGraphSchema_K2... because of course it is.
Hey folks quick question how would I add a splash screen with transparency into the engine? I know where to set them but every file type I use doesn't display transparency :/
Nah made my own, some of the generic stuff is exposed but it's kinda... lame
is this a mistake (two calls to SetUserFocus)?
Source/ShooterGame/Private/UI/Menu/Widgets/SShooterServerList.cpp
300: return FReply::Handled().SetUserFocus(ServerListWidget.ToSharedRef(), EFocusCause::SetDirectly).SetUserFocus(SharedThis(this), EFocusCause::SetDirectly, true);
I thought it might be setting up two entries on a focus stack or something, but from code the second call to SetUserFocus just seems to overwrite the first:
FReply& FReply::SetUserFocus(TSharedRef<SWidget> GiveMeFocus, EFocusCause ReasonFocusIsChanging, bool bInAllUsers)
{
this->bSetUserFocus = true;
this->FocusRecipient = GiveMeFocus;
this->FocusChangeReason = ReasonFocusIsChanging;
this->bReleaseUserFocus = false;
this->bAllUsers = bInAllUsers;
return Me();
}```
I would guess it's a mistake
what is the easiest way to get swidget that allows edit of some custom ustruct? SDetailsView with some parameters?
You create a details panel customization
Essentially allows you to register a custom details panel widget for that struct
i don't need custom details, i need widget for regular ones
i just wanna create an instance of struct, give it to widget, allow user to modify it and get edited struct back
and kinda want it for free as actor details work
without writing widget for every actor class
@ivory adder do you mean in editor right
Yeah
I found skismetinspector already that works
And helper in propertyeditormodule that looks useful for that
If u want custom editor window
Your looking at x50 the work
Of just a err
Custom property window
Also AFAIK u can't have a custom editor for stricter
Structs
Has to be uobject type
Or they need to be nested in a uobject container
Regardless if it's temp or to save to content browser
It's possible to do what I want but
Your in for a shit storm
Would recommend cutom propvonly
Well i didnt test it good, but skismetinspector at least give me ability to edit struct uproperties without pain
Its kinda strange to get results from it by reintepret cast but it compiles. I ll check tomorrow if it works good when i read values
Hello, I would like to learn slate,
I never used it before.
Can you suggest some tutorials by examples that can kick start me ?
yeah thats a good way to learn on your own
use the widget reflector and click on any UI on the editor itself to see how it's implemented
please help I have been stuck for 2 months I have asked everywhere , I cant get a 3d widget to show widgets that have things generated inside of them like inventory items or texts from NPC chat
if you see on the 3d widget it wont update the inventory items
its suppose to show the icon of the item I just picked up
Any tips for making base slate class to derive from that has some say base constructor type of thing? since there is like no way to have inherited constructor stuff due to slate arguments, not like you can just add on more
I'm trying to create an IPropertyTypeCustomization for a custom struct in my project, and this is the code: https://gist.github.com/jorgenpt/19fc2b9647b356c8f1d6559037ad4a60
The problem I'm encountering is that while value part of the property renders correctly, the default name widget that I'm retrieving from row of the property handle isn't rendering at all -- it's just a blank space. I was expecting it to show the name of the property. Is there something I need to do to show the name of the property?
@small parcel Donโt know the answer to your question, but your gif link doesnโt work. I think itโs supposed to be https://giphy.com/gifs/c6X24mPhFsxK3pP1je ?
@small parcel u need to add child to the widget by casting the 3d widget from widget component in the actor bp
How would I go about adding one of these to a widget tab? Every attempt so far has me running face first into a wall
thats just a datatable
I meant how do I program a UI element like that using Slate
Use the widget reflector and navigate to the source code of it.
Slate barely has tutorials for that
Also be aware that some stuff might be editor only and not available in packaged versions of your game.
Every attempt so far leads me to code that is only in "Private" parts of the engine, sadly
didn't encounter private slate that i'd want to use yet...
i probably just copy paste them without even trying other ways:)
I get this error whenever I compile,need some help in fixing it
Error LNK2019 unresolved external symbol "__declspec(dllimport) public: __cdecl FSlateBrush::FSlateBrush(void)" (_imp??0FSlateBrush@@QEAA@XZ) referenced in function "public: __cdecl UInvetoryItem::UInvetoryItem(void)" (??0UInvetoryItem@@QEAA@XZ) Test E:\ProiecteUnreal\Test\Intermediate\ProjectFiles\InvetoryItem.cpp.obj 1
Sorry if this is the wrong place to ask this in
did you add Slate to Build.cs?
Yeah, it was my bad I forgot to uncomment it from the build.cs.Thank you for answering.
Any chance anyone knows about Propety handles and setting values when the flag EditInlineNew is there?
@pearl badger What's the issue?
Probably not going to work on more than one object at a time, if that's what you're trying to do.
Some reason c++ made Widget* variables(uprops) are getting marked with CanBeExpanded, EditInlineNew ,RequiresValidation in the property handle flags, and stops you using the Drop down selection combo box in UMGEditor Details panels to select target widgets, However this works fine if the variables are made in BP lmao
@pearl badger Ah so you don't want to create instanced objects, you just want regular references?
I think the issue is that UVisual (UWidget's base class) is marked DefaultToInstanced.
Blueprint properties are always non-instanced so that overrides it. Seems dumb, but I'm not aware of any way to override for C++ properties. I don't think there is any such thing as a NotInstanced property specifier.
You can do Instanced = false to override probs
But it did not work
You can actually = true or =false any pop if you didnt know
Yeah? I know with a lot of meta specifiers you can. Don't think I've ever seen it used for non-meta ones.
I wonder if you could manage some very dodgy hack by declaring your properties just UObject* instead, and then customizing the UI, either manually or maybe with some Meta to restrict the class?
Hmm good idea I'll take a look
Can we play a video in slate ?
Does anyone have a simple example for an Editor Style?
I looked at Paper2D but damn...
As far as I can tell, most of the stuff is auto linked via class an propertyname
StyleSet->Set("TileMapEditor.RotateSelectionCW", new IMAGE_PLUGIN_BRUSH(TEXT("Icons/TileMapEditor/icon_RotateCW_40x"), Icon40x40));
Which is fine I guess, but I wonder how I would create a simple brush that I can reference
All I can find are huge wiki entries with tons of stuff in them that I don't need
Also don't really get the connection
We have a command in some FClassNameCommand
That is used in FClassNameModule
But the Style uses StyleSet->Set("ClassName.Command")
I mean where the hell is that ClassName even remotely mapped to the command
There isn't even a class with that name
@low bluff You want to create custom icons etc?
I basically want the ability to add Icons whereever i want
E.g. adda Horizontal Box
Add a button into it
And an image next to it
I know I need a style for that to referecen the image
But well
@royal geode
so
Currently all I have given from another member on my team is the style that adds an icon to the toolbar button
That works so far
Do you already have a TCommands?
Yeah that exists
With a simple "OpenPluginWindow" command for the toolbar button
That's also the one that already receives an icon
via the stuff I posted above
Yeah but I have widgets that ahve nothing to do with commands
Ah
Hence why I'm missing how to simply define an image brush to then use in some random arse widget
I see
Let's say I have an EditorMode
That has a widget on the left side
Like evry other editor mode
Yop
Like those buttons?
Yeah kinda
Commands ๐
What if I just want to add an image next to the Undo button
Like you would do in UMG
HorizontalBox -> Image, Button
How do I get that Image
I know I can most likely do an SImage but the brush for it is the thing that I'm missing
So from the code I'm reading rn :
TSharedPtr<SMultiBoxWidget> MultiBoxWidget = OwnerMultiBoxWidget.Pin();
const ISlateStyle* const StyleSet = MultiBoxWidget->GetStyleSet();
return StyleSet->GetBrush( "MultiBox.GenericToolBarIcon" );```
SNew(SImage)
.Image(FEditorStyle::GetBrush("VerticalAlignment_Top"))
Yeah I find stuff like that too
But how to define what's behind that brush
Set( "MultiBox.GenericToolBarIcon", new IMAGE_BRUSH( "Icons/icon_Cascade_RestartSim_40x", Icon40x40 ) )
Same way?
Set("VerticalAlignment_Top", new IMAGE_BRUSH("Icons/UMG/Alignment/Vertical_Top", Icon20x20));
Seems so yeah
So you just put a unique name
Either that or something that routes to a command
Simple enough I guess
Unique name to your styleset
Yeah I can have my own VAlign Top
One other thing
Since you seem to know about the commands
Our command class is called: FPluginNameCommands
With the OpenPluginWindow command
And this is in the style: StyleSet->Set("PluginName.OpenPluginWindow", new IMAGE_BRUSH(TEXT("ButtonIcon_40x"), Icon40x40));
Where comes the connection from PluginName to FPluginNameCommands from?
Ah, FPluginNameStyle::GetStyleName() is in there
Still not 100% sure how the rest of the connection works
Macro magic
I'm really okay with slate, but the style stuff, uff
I need to know how that part works to understand how I have to name these to work with other commands
Paper2D has tons of different ones
๐
Yeah not doing that anyway
Much clearer to do stuff like that
Sorry but I still don't get how the PluginName or SpriteEditor name etc gets utilized -_-
I understand the linkage to the command name
hehe
When you register your command, it sets its icon to the combination of your TCommand context + the command name
The UI_COMMAND pulls that out of the TCommand again
Got it
There is the missing link
TCommands takes the ContextName as first argument
That's the thing infront of the .
Yep!
Yeah sadly not documentated, like most of the slate and editor stuff
Especially since the commands class comments seems to have been written without knowing what context was for ๐
It's fun to do that kind of reverse engineering, as you often find copy pasted comments
And you can follow the order of creation of the modules
^^
"." #CommandId
Whatever this shit is they pass in the macro
Have to learn about C++ Macros defines some day
Ah okay
So OpenPluginWindow gets .OpenPluginWindow where it's now .+string
Makes sense
Then it joins it with the context name
So the whole "Foo.Bar" thing is just a made up way of later joining the context with the command
When setting a previously 'Collapsed' widget to 'Visible', Slate seems to defer it's geometry update sometimes for several frames, and the widget can appear in the wrong position.
Any ideas how to circumvent that? It's infuriating. Collapsed is superior to Hidden in terms of performance, and it seems barmy that changing the visibility from collapsed wouldn't trigger an immediate geometry update.
SlatePrepass() ?
Does that not force rebuild the whole UI though?
Just the local one
IIRC
I use it everywhere, for what it's worth, so it might be quite fast
wouldn't it make sense for it to just do that automatically on the first frame a widget is visible?
I'll give that a shot, thanks!
I guess they don't do it automagically since if you can spare the brief out-of-date-ness, it's probably worth the perf I guess
mfw hot reloading details customization with live++ and it actually works
hmm. I have an array of structs with a ton of properties in each of these, and it makes it somewhat hard to see where each array element ends
does anyone have an idea for a simple way to add a visual separator between the array elements with a details customization or anything else?
it could be as simple as making these lines in the editor red but I can't figure out how to change the background
Check how fmenubuilder::addmenuseparator is converted into widget
hmm
this seems to have access to quite different things than what is available here
oh hold on
seems like there is more than one type of customization
I'm reading something on the docs but they have a virtual void LayoutDetails( IDetailLayoutBuilder& DetailBuilder ) override that I don't have
Menu separator creates simple separator line when you call makewidget from fmenubuilder. You may check there created widget (or just get it by widget reflector in editor from any menu)
Then you probably shall take idetailchildrenbuilder, addcustomrow to it and set separator widget into it
I didnt try that but think that it shall work or work after lil research about adding custom widgets
Addchildcontent is probably better choice
hmm
if I add row to the children builder, it'll go below the line with the array index won't it
I'll put the separator at the end then that works too
am I missing something here? why is this text not vertically centered?
now it works 
slate is so strange
What's the quickest way to reference a texture asset in slate?
I simply want to use a TextureAsset for a Throbber
Don#t want to create a freaking SlateStyle for that
@low bluff I've done that once in quick-and-dirty mode here : https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRainLoadingScreen/FlareLoadingScreen.cpp
Look for throbber
Hm I swear I tried the exact same thing
Only for to report me that the image couldn't be found
I now linked it from the ProjectSettings
.>
Thanks though!
Is there a nice way to force refresh a detail panel
SDetailsView::ForceRefresh()
hey there people
just wanted to share a snippet. I wanted to have a basic slate for HUD and over it to attach some other details via UMG since they are easier to customize
so I have to attach a child of UUserWidget to my slate parent
MainHUD = TWeakObjectPtr<UMainHUDWidget>(CreateWidget<UMainHUDWidget>(ownerHUD->GetPlayerController(), HUDStyle->MainHudWidgetTemplate));
if (MainHUD.IsValid())
{
//add it to the viewport
MainHUD->SetVisibility(ESlateVisibility::Visible);
MainHUD->SetHUDParent(ownerHUD);
MainHUDOverlay->AddSlot()
.VAlign(VAlign_Bottom)
.HAlign(HAlign_Fill)
[
MainHUD->TakeWidget()
];
}
Hey guys; I was reading in more for a controller that I am making, slate vs. umg. unreal recommends UMG... why?
@dusky saddle UMG is a layer on top of slate. It's best to start there for now, if you need more low-level control, look into slate
Does anyone know the correct way to load a material in slate?
you would load it as any other UObject
and give the slate brush the material object as its resource object
im not sure if there is a shorthand for this ๐คท
can I use custom HHitProxy in slate widgets? I would like to define my own. From what I see in engine code they are used in various curve editors and I would like to do the same. I would need to access UGameViewportClient and bind to some of delegates provided. From code I see I would need to implement my code in virtual void Draw(FViewport* Viewport,FCanvas* SceneCanvas) override; is there more direct access to this method in Slate? Or did anyone successfully implemented custom hit proxies in slate? I would appreciate any input on this. I need to detect clicks on curves and hit proxy look like best way how to do it.
or can anyone explain to me how hit detection should be handled in slate when i want to draw splines as UI objects?
Check fsplinecomponentvisualizer
It doesnt handle curve hitproxies but it uses regular ones
I did dig through all classes that handle curves in editor but I can't wrap my head around how to use it in slate. I know editor is done in slate but thing I want are working on FViewport and FCanvas, not SViewport and SCanvas, that's my main source of trouble. It would be awesome If we could define custom shape HitProxy even in Slate
Computing overhead might be well worth it in many cases
how to use it in slate how to use what @median basalt ๐ค
i want to draw splines in slate, curves of various types and would like to attach to them extra data, be able to pick, modify them with mouse in 2D
and it came to my mind that hitproxy might be best way to do it
Seems a good idea indeed
i noticed in code that handles wires in blueprints hit detection is done via iterative loop, i want to avoid that as things i want to display might get rather complex so hit proxy in slate would enable me to get rid of bloat load code
that way one could define arbitrary shape as mask for any button
among other things
And what's your issue?
how to make it work ๐
hehe
so i could draw any type of spline and attach extra data to its htproxy and then easily process click, drag, etc
spline is only my specific user case but having hitproxy could enable other stuff to happen
basically same stuff as actor picking in viewport but in 2d in slate
i could fake it by doing separate ortho camera and use worldspace geometry with regular hitproxy but i wanted to use it directly in slate without scratching right ear with left hand over head... ๐
hitproxies don't work well with orthocamera
you may switch to ortho and try to edit spline:)
I'm not sure you can use hit proxies directly in slate ๐ค
As the canvas is rendered as a single item
bummer
You could do some spatial hashing
you mean something like quadtree over bbox?
for instance
even splines are deconstructed to straight segments prior drawing so maybe at the end I will end up using brute force line point intersection
or what other spatial hashing you have on your mind? could you elaborate?
And ofc you don't just want to test intersection on anchors? ๐
my main issue are splines as for text and point data i can use what is already available
Yeah I'm out of ideas tbh
You could always render the splines on the CPU
You'd have a big array with the same size as your screen
oh that's no no as i need to do panning and zooming
haha
looks like old trusty bruteforce :/
i wanted hitproxy only because i could consume attached data that way and would not need to deal with extra complexity of storing and managing it, well then back to drawing board
@ivory adder my data would be purely planar so ortho might work? I know tangents in 3D would be pain in the ass indeed
I don't know anything about Slate. but for those who use it, why? I've used some UMG. I think it's great. I just am curious what benefits/difference Slate has. Thanks all!
@orchid atlas Slate is to UMG what C++ is to BPs. At least if you want a very rough picture.
It's mainly used when:
- Extending the Editor (at least before these UMG versions came out be their functionality is still limited by BPs)
- Exposing Widgets that UMG doesn't have (e.g. ColorWheel)
- Not liking UMGs inheritance
I guess the main difference is the way UMG and Slate handle their Inheritance.
If you inherit from a UMG widget, you can't modify the Widget Hierarchy if the Parent already has one.
This leaves you with only being able to utilize Functions and Variables.
I guess Slate is similar, but iirc it at least allows you to change and adjust the spawned widgets in the child.
@low bluff Thanks for the info eXi! Sounds like UMG is good for me for now. ๐
you can also use slate to optimize (reduce a UMG BP from 200 UObjects to a single one)
anyone know why the loading screen plugin doesn't do anything in 4.22?
Hello guys!
I made custom tab with SDockTab, any ideas how to get size of this tab?
Current, not desired
Okay, I just used cached geometry and it works for me
Is there a counterpart in FAssetEditorManager to OnAssetEditorOpened() ? There is only OnAssetEditorRequestClosed(), and that doesnt get called when the user just closes one editor window
hello can i make a my details panel customization for a struct instead of a class?
Do you know, where I can find the slate code for the 1D/2D blendspace diagrams? Want to try to build something similar for InGame UI (with slate or umg).
use the widget reflector to find out what widget it is
click pick painted, hover over it, press escape
@main hedge Thanks a lot!
Ctrl Shift W ftw
what's it do
Open the widget reflector ๐
oh that's very useful
Is there a trivial way to raise a umg drag drop op from a nested slate object?
Has anyone seen these type of crashes?
FDelegateBase::IsBound c:/users/nicho/documents/unreal projects/unrealengine/engine/source/runtime/core/public/delegates/delegatebase.h(127)
TAttribute<EVisibility>::Get c:/users/nicho/documents/unreal projects/unrealengine/engine/source/runtime/core/public/misc/attribute.h(130)
SWidget::SlatePrepass c:/users/nicho/documents/unreal projects/unrealengine/engine/source/runtime/slatecore/private/widgets/swidget.cpp(505)
UMG
It looks like you've got a visibility delegate that's unbound
Right, I don't know why that is tho
Do you do a lot of dynamic bind/unbind ?
yes we have bindings in our widgets
And they're dynamic ? I must confess I've never had dynamic delegates for slate
@craggy holly Given the demo of the SParticleMeshWidget from Nick, is that hte go to way of spawning particles in the UI?
I thought people might use Flipbooks, rather than this
I guess it depends on your use case
Flipbooks is probably easier... though the particle mesh thing is quite cool
So I'm trying to write a Slate method that does SNew, store the widget somewhere, and then proceeds - so that I can call .Stuff().OtherStuff() on it.
Pains me that I'm not getting anywhere here
What's SNew's return type even ?
Well, gonna rewrite the macro itself
What's wrong with SAssignNew @quaint zealot 
Well, SAssignNew does not add the button to a class member array automatically
Basically this is for a custom focus system, I want a macro that replaces SNew because it's going go be used on every widget
Yeah probably gonna work that way
NewFocusableButton<WidgetType>( #WidgetType, __FILE__, __LINE__, RequiredArgs::MakeRequiredArgs(__VA_ARGS__) ) <<= TYPENAME_OUTSIDE_TEMPLATE WidgetType::FArguments()
template<typename WidgetType, typename RequiredArgsPayloadType>
TDecl<WidgetType, RequiredArgsPayloadType> NewFocusableButton(const ANSICHAR* InType, const ANSICHAR* InFile, int32 OnLine, RequiredArgsPayloadType&& InRequiredArgs)
{
auto Button = TDecl<WidgetType, RequiredArgsPayloadType>(InType, InFile, OnLine, Forward<RequiredArgsPayloadType>(InRequiredArgs));
FocusableButtons.Add(Button._Widget);
return Button;
}```
Now, to specialize it by removing templates
Hello I'm trying to learn how to use slate and Im trying to add a textblock to a canvas. I have the canvas being created and Im able to add a throbber and image to it but I cant seem to add a textblock. Would anybody be able to help me with this?
My code:
// Constructs a canvas
SNew(SConstraintCanvas)
// Adds the text to the canvas
+ SConstraintCanvas::Slot()
.Anchors(TextAnchors)
.Offset(TextOffset)
[
SNew(STextBlock)
.Text(TEST TEST YO)
.Font(DefaultFont)
]
did you actually write TEST TEST YO there?
I mean.. why not?
because the Text() function takes a reference to an FText or a delegate that returns one
for testing, you can put INVTEXT("Hello") in it
oh yeah your talking about the actual message yeah no thats actually a variable with some stuff I changed for copy and pasting it here
what's the actual issue then
try if you can see it in the widget reflector
it will show what absolute position it ended up with for example
Im using it with the movie player stuff for a loading screen
does the widget reflector work with standalone?
are you using 4.22?
yup
how did you get the loading screen to display at all?
I've been wondering what's wrong with mine but haven't investigated it
working off of Nick Darnell's loading screen just fixed a few minor things with the setting structure not working
Figured out what the problem was
Was missing .AutoSize(true)
Full code: ```
// Constructs a canvas
SNew(SConstraintCanvas)
// Adds the text to the canvas
+ SConstraintCanvas::Slot()
.Anchors(TextAnchors)
.Offset(TextOffset)
.AutoSize(true)
[
SNew(STextBlock)
.Text(TextMessageVariableYO)
.Font(DefaultFont)
]
yeah makes sense
Thanks for your help ๐
you should be able to use the reflector in standalone, though I do not know how ๐ค
Has anyone been able to find a good optimisation for SlatePrepass? I know Epic are looking at it but has anyone made any Slate changes to improve it?
Btw - I know that Invalidation Boxes and using Collapsed improves things but I was wondering whether anyone has found a code optimisation
Which kind of optimization ?
Anyone has experience with software cursors ?
Whenever I call FSlateApplication::Get().ResetToDefaultInputSettings(), I often get one frame of default Windows cursor.
can you pause the render pass for that frame to workaround it?
I'd rather not pause anything tbh
I need to look into ResetToDefaultInputSettings and make a version that doesn't touch the cursor
yeah have you got an idea what its a side effect of exactly? Sounds a bit wierd
I'm pretty sure it's a side effect of PlatformApplication->Cursor->SetType(EMouseCursor::Default);
Trying a new approach...
It's not 100% either
I'm switching many things at the same time so it's probably too much
Well I'm a dumbass ! Works fine without it. ResetToDefaultInputSettings is only used by Console in UE4, so... That does not need soft cursor
anyone figured out how to get the loading screen to display in 4.22 yet?
oh yeah there is a new loading screen right?
what is this about a new loading screen?
this just looks like the video player when the app starts up?
not sure what he meant by new loading screen
but 4.22 broke the video player displaying when you put only a widget and no video
@main hedge are you talking about the loading screen plug-in?
The engine feature itself apparently
I mean.. I got it to work..
I haven't noticed any issue either, but my screen is just a black widget, so.
do you use movies?
I tested it with both an image widget and a movie
if you use only a widget and no movie, it doesn't spawn the loading screen
Just a widget
Sorry I guess poor phrasing on my part.. but it works if I just show the image widget and there's no movie
And vise versa
did you use the wild hax/workaround shown here? https://github.com/ue4plugins/LoadingScreen/issues/50
Is the issue plugin specific ?
No I used Nick Darnell's loading screen plug-in as a base, and just modified it so the circular throbber and text don't show up unless I specifically want it to
Yeah that sounds like a plug-in issue...
well are you sure you're using 4.22?
Yup
the issue is not related to the plugin
I've taken out most of the strange things the plugin does anyway
I'll check later if I have the issue.
I spent last week cleaning all of the default stuff in Nick's plug-in so my team could use more customizable stuff. It just fires the code for showing the loading screen when the level loads via a delegate, and when the game starts.
That delegate fires regardless of any movies being played
Or queued up
are you not using the movie player to display your loading screen widget then?
The movie player handles only videos, we have to manually add the Widgets we want via slate
well no, the movie player can display widgets too
the only problem is that they've broken this functionality in 4.22
Yeah that's specifically adding the slate widget when the movie player delegate fires
As long as the Boolean for showing UI is true, which you can set in the Project Settings. But it definitely works
what happens is that this code will spawn and register the widget and then... nothing
You may wanna check if the delegate is firing at all for you, cause it works fine for me and my team
because the movie player has been broken in 4.22
Right, doesn't work here either.
@quaint zealot What's broken with it?
@placid beacon Well I was answering the discussion
Basically loading screen for Slate widgets is broken in 4.22
ahh okay
I'm not sure if this is a bug with slate or what, but my widget blueprint designer is broken for all widget blueprints: https://i.gyazo.com/a149ccec1b13c7934a10a826f28c5219.gif
I'd really like to get that to work again
I've deleted DerivedDataCache and did a full engine rebuild, also reset my editor layout, but that all didn't help
I again deleted engine intermediate folder and did another full recompile... still no change ๐ฆ
its also same in all projects, I tried multiple ones
Did you make sure no file had an incorrect change time ?
yes, I searched for *.* with ultrasearch and made sure there's no file that has any incorrect change time
{
return FLinearColor(1.0f, 1.0f, 1.0f, CurrentAlpha);
}
FSlateColor SKelvinModalPanel::GetPanelBackgroundColor() const
{
return GetPanelColor();
}```
Well fuck you too, Slate

I still have not managed to make my UMG designer work, the UI is still missing...
@toxic trench Does that happen on a new Project with the custom engine?
@low bluff yes
every project
Do you maybe know where in the engine the code starts to create the designer?
unfortunately I don't
I mean, more than "Redownload the engine" I don't know either
But you have changes in it so hm
yeah, all changes I recently did were just to stuff like SteamVRHMD files etc, never slate stuff
I'm pretty sure I had that once with just normal bps or so
But def nothing with source engines
its super weird, yeah
what is the best way to add animation to slate widgets without manually creating Tick counters myself ๐ค
Materials, maybe
materials don't work without a world ๐คท
Do you mean UI domain material graphs don't have access to Time ?
yes
manul tick animations it is 
i have an error in compilation -
1>Failed to delete file 'D:\Unreal Engine\Epic Games\MyProject5\Binaries\Win64\UE4Editor-MyProject5.pdb'
1> Exception: Access to the path 'D:\Unreal Engine\Epic Games\MyProject5\Binaries\Win64\UE4Editor-MyProject5.pdb' is denied.
error exist only when i'm using FSlateDynamicImageBrush from texture
#define TEXTURE_BRUSH(PathName, Size) FSlateDynamicImageBrush(Cast<UTexture2D>(StaticLoadObject(UTexture2D::StaticClass(), nullptr, TEXT(PathName))), Size, PathName)
mMyUIResources->Set("WoodTexture", new TEXTURE_BRUSH("/Game/TestCubes/WoodTexture", Icon100x100));
other brushes have no probles
is this a known bug, or i'm doing something wrong?
@plain portal :D Maybe you can write a Material Node that accesses Time via the Slate SImage it's attached to
@pastel phoenix The error itself looks like a read/write issue?
๐ค over engineering, I like it
Or rather via the SWidget its attached to
Cause there is more than just SImage that can hold Materials
It would remove your need of always manually drive the material from outside
And you learn something :D
And no, I have 0 idea where to start for that, but it should work similar to the time variable that already exists
I know my way around the editor side, will see
Let me know how it turns out. (:
@low bluff it is read/write error after start of my game, closing it, and recompilation. looks like some resources busy after shutdown
Well the UE4Editor pdb file is basically the generated symbols
Afaik
But I don't want to say too much, as I'm not sure what the exact mistake is
Could totally be wrong usage of the slate brush
recompilation of project, it is cleanup
Are you waiting long enough after closing?
no. and error repeating 4 times, then it is gone, and compilation successful
o.o
Are you using Source Control?
no, git
Hm, then I'm clueless
it is depends exactly of FSlateDynamicImageBrush
you using FSlateDynamicImageBrush in your loading screen?
no, inside game
right now it is .png images with FSlateImageBrush
i want to use FSlateDynamicImageBrush with textures assets
but this bug is annoying me
@low bluff @quaint zealot actually materials work without a world, I completely missed the first parameter
and also I was using material functions from the engine that were using time, I just copied them and made time to ignore pause ๐คท
seems to work
Classic
any good way to stop visual studio from autoformatting slate code?
Not sure of a specific way for that but this might give you some ideas. https://github.com/hackalyze/ue4-vs-extensions
@meager abyss
meh, i'm not going to be in slate long enough to need to write my own vs extension ๐
I thought his code might be modifiable tho. quick fix add a macro extension thingy?
maybe, but is that more or less effort than just fixing it
I'm writing some code to change the way my node graph editor looks
once it's done, I probably wont ever touch it again
fair enough. ๐
@meager abyss I don't know but I want the same thing -_-
what do you mean by auto formatting? on paste?
On writing
If you keep VS's default settings of autoformatting when you write, which is desireable most of the time, Slate code gets really messed up
Slate being based on massive operator abuse with single statements going over hundreds of lines
Would be great if some macro or pragma disabled that
@main hedge sorry to bother you about this like a week later, but I had a chance to look at what you were saying about the loading screen not showing up for widgets only and found that they're checking if they have any movie paths before trying to show the loading screen. Anyway the fix to your problem is by adding an empty path to the loading screen's paths
LoadingScreen.MinimumLoadingScreenDisplayTime = Scr
eenDescription.MinimumLoadingScreenDisplayTime;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = ScreenDescription.bAutoCompleteWhenLoadingCompletes;
LoadingScreen.bMoviesAreSkippable = ScreenDescription.bMoviesAreSkippable;
LoadingScreen.bWaitForManualStop = ScreenDescription.bWaitForManualStop;
LoadingScreen.MoviePaths = ScreenDescription.MoviePaths;
LoadingScreen.PlaybackType = ScreenDescription.PlaybackType;
if (ScreenDescription.MoviePaths.Num() == 0)
{
// Incase its empty we just add an empty path anyway
LoadingScreen.MoviePaths.Add("");
}```
This is in the BeginLoadingScreen function in LoadingScreenModule.cpp
hmm interesting
The reason is because they dont actually add an active movie streamer which handles showing the widgets and such unless there is at least 1 movie path. Which I guess was a small mistake somebody missed
do SWeakWidgets do anything to clean themselves up if they are only referenced in the slate widget tree itself and their content goes away?
ran into some orphaned ones in shootergame causing issues for a vr/2d viewport transition I do
does anyone have any experience creating a RTS style minimap? I've been looking through the StrategyGame epic provides and was wondering if this is a particularly efficient way to accomplish that kind of thing considering it was written a while ago and their game has a relatively low number of enemies. My game has around 100 moving enemies and 100 static buildings which I'd like to represent on a minimap.
in the StrategyGame example they seem to use the FConstPawnIterator to iterate through every pawn, and then draw a FCanvasTileItem, which is just a white texture for every pawn in the game every frame. Would creating 200 Userwidgets on the minimap to represent the ingame things and then updating their position when they move in game be more or less efficient, fps wise than their method?
I'm also wondering if using FSlateDrawElement::MakeBox would be more efficient than UCanvas::DrawItem
Or maybe the performance impact is so small it doesn't matter anyway.
Does anyone know how to draw a textured poly in Slate? I've spent hours checking looking at MakeCustom and MakeCustomVerts and haven't had any luck yet.
Hmmm maaaaybe I can do it with AddTriangleRenderItem?
Or maybe I should be generating a mesh dynamically and passing that to SMeshWidget?
@mild oracle you could use the usual procedural mesh tools and render it to texture to get it into Slate but then im not sure if that works in editor, it probably does.
@urban bloom To do that I'd need to set up a camera & render it to a texture wouldn't I?
I think I tried that before and had issues with pink around the edges too
I guess the downside with SMeshWidget is it doesn't properly render complex meshes? It seems to convert the 3D data into some kind of 2D poly representation, so textures get messed up?
Does anyone know what causes this crash? I haven't touched any C++ for slate since my entire UI is done in Blueprints/UMG but whenever I package my game it gets this assert on launch. Runs completely fine in editor.
@brazen onyx Any chance you are using Steam and show UI based on some Steam callback?
Yeah, it is using steam subsystem and some ui elements require steam api calls
Since it runs fine in editor, I assume it's because of that.
Steam API Callbacks don't run on the gamethread
So when you receive a callback, such as "SessionInvite" or so, and you show UMG stuff, it crashes with an assert that you aren't on the GameThread.
The thing is, it crashes before it even gets to that point I think. I will try to cook a version of the game with steam features disabled and see if it works. Thanks for the help.
Yus, if you find out it's a steamcallback, ping me and I try to find the line of code to bring it back to the gamethread
Hmmm... even with the steam ui disabled it still crashes instantly on launch. Doesnt even play the startup video before it crashes.
@mild oracle correct - SMeshWidget just lets you take advantage of hardware instancing to draw lots of the same thing. It doesn't really draw meshes, the mesh just gets converted to slate vertices once and that's it
Well, I got it to cook and run by making a new blank project and migrating the content folder over. Some stuff didnt migrate properly so I have to manually fix it, but at least it packages and runs now.
@craggy holly When you say "once", does that mean you can't scale/rotate the mesh in real-time?
You cannot
It's all cached
I mean, you can sort of rotate the vertices in the material
But not easily
eugh so I guess I have to render to a texture
Unfortunately it's still the only way to render a mesh in UI really. I think they allow you to write depth into the render targets alpha channel now though, so you might be able to get cleaner masking
Or even select which actor is rendered to the RT at all
It's just such a hassle to set up a camera and the object and yadda yadda
anyone have a good toturial to make editor tools with c++?
There isn't much of a tutorial for that no. The UE4 doc has a Slate chapter covering the basics
Rest of it is searching through the editor code
rip ok
one more thing, our artists pulled in our new c++ classes but they're not showing up in editor and the derived blueprints are complaining
do they need to press the compile button?
Of course, just commit the game editor binaries.
They won't need VS or compile or anything like that
They'll just need the Visual Studio redistributable which is like half a megabyte (which your players also need installed when you ship)
which binaries are these exactly?
Binaries\Win64\UE4Editor-GameName.dll
Put the PDB as well, maybe the .modules file
The rest isn't needed IIRC, though frankly I have no idea
Best is to remove everything but the .dll and add files until it works
would there be an issue if I removed those files from the gitignore and just pushed them everytime or would that cause issues for the other developers?
or what's your approach on this
it's mainly just for the artists
That's what I'd do yes
Minor annoyance for developers (source control will tell you about local changes every time you build)
If it's Perforce it's even more annoying since it read-only's file that aren't checked out
yeah we're not using perforce, too expensive ๐
so they're in your changed files then but you don't push them every time, or do you?
You don't, because you want programmers to be able to pull changes while working on something (well I do anyway)
You would commit the binaries only when you want to update the artists
ok well that's quite annoying
@quaint zealot If you setup the typemap properly, you can have binaries readWrite, even if submitted.
there's no way to push a file once and ignore it after that again right
Yeah I don't use Perforce @low bluff
:P Just making sure you are up-to-date
Thanks, I didn't know about that feature
But yeah, in general you will be pushing the binaries every time you have an update that everyone needs.
You usually also have plugins for Editor stuff
So you only push the plugins binaries iirc
@maiden talon Branches allow you to do this in Git - you'd have a "stable" branch that does not gitignore binaries, merge from the master branch when you want to update the artist, build and commit, go back to master.
We went ahead and just made sure that our Artists know how to Regenerate Files and Compile.
well, they know how now, it just takes some time, which would be nice to not have to do it
Incremental changes don't take much time. If they simply start the project via VS in the first place then it's 2 clicks + a few seconds of compiling.
And usually Artists don't restart the Editor that often anyway
But yeah, if that's too much struggle, commit binaries and be done with it
Hi guys. Does anyone know how to create additive font material? Additive is okay with textures, but doesn't seem working with fonts
we have a dedicated build machine at the studio that submits engine and project bins
our artists/designers dont compile the editor
Hi guys
hi steve
I am learning cpp with UE4 and im editing the shooter game demo as i learn. Slate, is this going to be supported indefinitely or will it at some stage get ditched for only UMG? I want to make my game (in the future when i have learned enough) in all cpp where possible and i see that slate is pretty much all cpp.
So will slate always be in ue4 for the foreseeable future? i dont want to learn it if it will be removed...
(Reason i ask is because i seen a old forum post saying that umg is replacing slate so i wanted to check)
umg is implemented using slate, so yes
however, shooter game is quite ancient, a lot of the things it does using slate could be done using umg in much simpler ways
๐ Thanks @main hedge
whoever said UMG is replacing Slate, didn't understand that UMG is Slate ๐
i mean usage-wise that statement is not wrong
@main hedge funny thing is that shootergame gets updated with recent stuff too xD
epic updated shootergame to include a replication graph example not too long ago. yet still has ancient slate stuff
You can have 3d widgets
thanks for your info guys. Appreciate it!
Also I'm tampering with the shooter game demo to learn about CPP for unreal. How would I disable/hide the host game button on the main menu but not fully remove it? Everything I've tired breaks it.
change its visibility to hidden or collapsed
Uff, how does one get a Texture2D into a Slate Widget again?
FSlateImageBrush GradientBrush = FSlateImageBrush(TEXT("Texture2D'/Game/Textures/UI/T_UI_LoadingScreen_Gradient.T_UI_LoadingScreen_Gradient'"), FVector2D(3840, 2160));
That compiles but crashes in some ElementBatcher class
Any reason the brush needs to be dynamic ?
I usually reference brushes rather than textures
I simply have 0 idea what I'm doing here.
I got a Loading Screen widget and a Gradient UTexture2D
And that Gradient needs to be set on a Border
But I have trouble referencing the Texture that sits in the path above
Okay.
Which widget is this used for ? SImage ? SBorder ?
Try creating a new Slate brush in content browser and you'll be able to reference that and pass it to either of these directly
SBorder
How do I load that SlateBrush in Slate then?
Cause that Widget is created in the GameInstance for loading levels.
I need the widget itself to grab the texture
I might end up needing multiple images
A Throbber Image, a Border for the Tips, a Border for the Gradient that sits over the map image etc.
Currently I already worked around my problem with defining these in the projects ettings
But I can't just define all the Loading screen brusher outside of the loading screen
That's just wrong
If you want something simple with no dependency for a standalone loading screen, and you're not going to have more Slate stuff going on, here's what I used before : https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRainLoadingScreen/FlareLoadingScreen.cpp
Looks like what you wanted to do except it shouldn't crash ๐
Basically what you did except it won't garbage collect your texture immediately and crash
Right, so instead of a flat FSlateBrush you make it a TSharedPtr
The FFlareLoadingScreenBrush thing is basically a GC friendly dynamic image brush
Replace FSlateImageBrush in your code with that FFlareLoadingScreenBrush struct and it should "just work"
Well that and the MakeShareable(new x) stuff.
Right, but what's the "correct" way? Making a style etc?
There is more than one correct way, but what I use is a style set singleton that manipulates style asset objects, which are structs with settings, pointers to brushes in your content folder, pointers fonts, etc.
It's more involved, but nicer to use when you have many classes sharing content & settings
I mean, I used the existing styles of epic to do some stuff. It just completely goes beyond me why referencing a texture2D in UMG is a simple click and slate is just a shitshow
Slate is complicated, but let's just say you either don't use it, or you use it for everything and there is some required set up.
The code in Helium Rain to define styling is all here : https://github.com/arbonagw/HeliumRain/tree/master/Source/HeliumRain/UI/Style
StyleSet = singleton that you interact with to get Slate brushes, or the "theme" structure that has all settings
WidgetStyleCatalog = structure with all UI settings for the full game
Shared brushes, etc
So that part is exposed to bps?
The widget style is technically a BP, as in it's an asset in the content browser
Thought you meant UMG ๐
No, a bridge from Slate to the Content Browser would be okay to me
Just not having to define them in a random class
Simply put I have a concept of "style sheet" like in web development, I create a style asset in content browser and load it in the style set
I also have a concept of "load this random brush dynamically"
Which is the GetIcon, GetBrush methods
And finally, for the loading screen I just use the standalone class I shared earlier
