#slate
1 messages Β· Page 4 of 1
it does seem that default constructor is really empty constructor in this case. Need to get it from widget and then set it's size
Which default constructor?
FSlateFontInfo()
No, it has settings. Not many, mind.
But it is not rendering font properly
same as this
TSharedRef<SVerticalBox> widget = SNew(SVerticalBox)
+ SVerticalBox::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("PRESS ENTER TO MAIN MENU"))).ColorAndOpacity(FLinearColor::White)
];
FTextBlockStyle NewTextStyle = widget->GetSlot(0).GetTextStyle();
NewTextStyle.Font.Size = 36;
It is complaining that SVerticalBox doesn't have GetSlot as member
but it does
Line 417
Sorry wasn't around, have you figured it out?
earlier getslot was working but now it isn't
I figured it out. Setting font size in font of TextBlock would mess up rendering. Rather set the TextBlockStyle on the TextBlock.
STextBlock::FArguments Defaults;
FTextBlockStyle CustomTextStyle = *Defaults._TextStyle;
CustomTextStyle.SetFontSize(56);
Do it like this
So if you add some UStaticMeshComponents to a viewport, how do you select them? I found that the viewportclients ProcessClick will give a HHitProxy but I don't get one when I click in the area of the UStaticMeshComponent. So how do I get the same functionality like in the editor where you can click an actor and the gizmo is displayed?
Is there a way to add a HHitProxy to a UStaticMeshComponent or do they need AActor?
Does the ustaticmeshcomponent have a translucent material?
It shouldn't. let me take a look
Yeah it's opaque. But I have no clue how exactly HitProxies work, they might only be added automatically to Actors?
Maybe I just ducked up something in the setup because I saw that there is a a FEditorViewportTabContent which I don't use. Should there be a hitproxy by default for Components?
Static mesh components should generate their own hit proxies.
Are you making your own viewport?
Yeah making my own
You might want to look at how they add them in the regular ones!
Yeah, just hoped someone had some experience. Maybe there will be a miracle and someone else looks at the channel π
. Couldn't find anything before but now I found FStaticMeshSceneProxy::CreateHitProxies(UPrimitiveComponent* Component, TArray<TRefCountPtr<HHitProxy> >& OutHitProxies) override; so that looks like a starting point
Edit: So I changed it up and now spawn an actor with the UStaticMeshComponent . HitProxy is now created. Would've been great to make it work directly with the component but the StaticMeshEditor doesn't have any HitProxies either. So the actor approach is currently enough for me. I might take a crazy pill someday and look deeper until then πΊ
Is it possible to setup a custom BP Node layout in Slate? Or is that all baked into the generated code?
I believe custom node layout is done in Slate, yes.
Hi, could someone tell me how I can make an actor selector?
I'm creating a slate window, and I'm setting some texts/properties etc, and I want to be select an actor in the current open level, any idea how to do it?
The property editor module probalby has an actor picker you can use.
It'll be created via a method on the module.
PropertyCustomizationHelpers::MakeActorPickerAnchorButton / MakeActorPickerWithMenu
do you know where I can find the slate used for editing TMap and TArray?
trying to find it, but no idea what to search for
Open the editor, go to tools -> debug -> widget reflector
View a tmap/tarray in the details panel. Use the widget reflector to examine the details panel.
thank you
Been working on a UMG -> Slate presentation at work to explain things to other devs, but have been hitting some uncertainty on when things tend to occur. The main issue I am hitting is my understanding of RebuildWidget and SynchronizeProperties. My current understanding:
RebuildWidget
- Runs when the widget is first created, is in charge of the construction of the Slate widget, and will destroy and recreate the slate each time it is called. Not really sure what other times proc this to run, seems like a rare thing?
SynchronizeProperties
- Runs right after the RebuildWidget, is suppose to sync up any of the UMG properties with the Slate widget. In theory this seems like something that would run sometimes without the RebuildWidget for keeping the two in sync, but I have failed to find any widget modification that seems to trigger this without the RebuildWidget.
Slate OnPaint
- Runs on each tick effectively and handles the visual create of the widget. I have seen some documentation on how to have slate "sleep" so that it does not run this frequently, but that doesn't seem to be the default behavior (over running on tick).
How much of the above seems right, and is there anything big I am missing for the general UMG Slate behavior when it comes to updating?
You might find it doesn't sync properties without completely rebuilding the widget. Epic's view is, apparently, destroy and recreate, not update.
Yeah, which feels odd to me why both exist in such a case. Maybe just to allow for that other route in niche cases?
It's probably just encapsulation.
So you can inject your own code at the correct place.
Is there a way to initialize a FButtonStyle in one block to set a button style?
For custom editor widgets: Is there anyway to get access to the allottedgeometry before the first OnPaint call? I donβt want to enable tick on my widget. I thought OnArrangeChildren would be appropriate but that doesnt get called
It's not, no.
It needs to work out how much space is available / it needs before it has any geometry.
I dont get why onarrange is not called on the initial arrangement
the layout is computed first before paint - id expect to hook into layout changes before painting
yea its working but I need to get the extent to actually compute the data for my widget which i cant do since onpaint is const
Calling SetCanTick(false) seems ti be a decent workaround
const_cast<SYourWidget*>(this)->stuff
or make your variable mutable.
But, yeah, those aren't ideal.
nvm im just dumb - im making something similar to scurveditor what I wanted was to get start and end of the viewed x-axis which is already in ViewMinInput ViewMaxInput π€¦ββοΈ
Sorry Im coming in late, yeah the order(paraphrasing but I recommend looking at the source code):
- RebuildWidget
- SynchronizeProperties
- OnPaint
The referenced classes and functions to look at are:
- SObjectWidget: This is the UMG widget wrapper class, including UserWidget's
- ::OnPaint
- ::Construct
- UWidget: The base class for all UMG widget's including UserWidget's
- ::TakeWidget / TakeWidget_Private: This is where the widget is constructed, which means the widget first has to do the first pass of caching desired size and then next pass is painting which calls OnPaint.
BTW Paint has to be called because its regarding drawing the widget. Its relatively fast if your not changing properties and stuff constantly(which means re-caching stuff to draw everyframe). So its only a bottleneck if your pushing it to its limit. If you changing something everyframe then its recommended to make the widget volatile so its not wasting cycles caching and trying to optimize which itself is the optimization but the drawback is that it affects the widget tree and causes downstream effects to be careful
I don't understand what's going on. I have a numeric box that is changing the value accordingly if I use a function
SAssignNew(widthBox, SNumericEntryBox<int32>)
.Value(this, &CLASSNAME::GetWidth)
.OnValueChanged_Lambda([this](const int32& InValue)
{
width = InValue;
})
.OnValueCommitted_Lambda([this](const int32& InValue, ETextCommit::Type CommitType)
{
width = InValue;
})
But if I just use the width directly (int32 width) it is not updating
SAssignNew(widthBox, SNumericEntryBox<int32>)
.Value(width)
...
Because you're passing in a value, not a reference or anything.
It's a 1 time thing.
Ok that makes sense. Changing it to &width gives me another error. Now I have to read up on TOptional π
. Thanks
We might as well rename this channel to "Ask Daekesh"
Oh well, can't figure out how to use &width or FSimpleDelegate::CreateLambda([this](){return width;}) or FSimpleDelegate::CreateLambda([this]()-> TOptional<int32> {return width;})
You cant just do & width either.
That will work, yes.
Or you can do tattribute<float>::some stuff here.
Though I'm not sure you can pass a ptr that way...
Hi there, not sure if here is the correct place to ask but I wanted to define an viewport render area and someone online claims to be called via slate somehow, and I don't see any easy way.
So wanted todo something like this post online, but I don't see real replies and the feature request is gone since 6 years ago https://forums.unrealengine.com/t/how-to-render-to-a-section-of-the-screen/371778/2
Hi SullairVR, There is no easy way to alter the viewport in the way that you describe. Method (FOV) 1: In your widget Blueprint just add widgets that will block portions of the viewport and adjust your FOV settings on your camera to match the remaining view. (may be hard to get desired results if your screen isnβt centered) Method (RenderTarg...
Im creating a widget that gets added to a details panel. When a float property changes I pass the changes to my widget to issue a redraw via PostEditPropertyChange and a delegate. My issue is that whenever you drag the float property PostEditPropertyChange gets called thus rerendering the widget during the dragging of the float. Is there some event besides PostEditPropertyChange that achieves this or do I hqve to write custom logic?
No idea, mate. Try adding the viewport to an sbox and put that in the splitter slot?
I'll try again, but i think i tried this again yesterday.
Basically its almost as if the GameViewport / its widgets gets greedy and doesn't respect the FractionOfParent at 0.6.
I'll try SBox and ScaleBox... but i think it ignores them tooo...
The idea here is to host UI in the other Splitter slots.... I don't want to overlay my UI on top of the viewport like the usual UMG AddToViewport() method.
Basically the same way unreal engine and blender does with their viewports.
I'm making a video editing app, kinda...
Have you tried looking at what the level editor does in its 4 viewport mode?
Yeah, it uses a Splitter.
But it also uses Editor Module Classes... Eg Viewport Class and Splitter it uses are the specialized types for the Editor not runtime so can't ship with that..
I haven't taken a deep look at the actual implementations so. I saw the type of classes it uses and i can't use that...
Just look and see if it does and manual resize.
The SplitScreen approach was almost a solution , except it creates or requires 4 player controllers or local players ... i just need 1 to handle all screens..
Will do , thanks ππ½
Good luck!
Yeah no dice on both of these.
Another weird thing... IF i add the GameViewport Widget (SViewport) on the first slot of the SSplitter... All the other Slots are not added/rendered... It has to be the last, even then doesn't work properlly
I'm guessing the other approach would be to try to understand and create a custom GameViewport Client... class
Have you tried setting the size manually?
They've hidden that functionality under private and protected Variables and functions...
It would have been a cool thing to feature though... I think i'm just going to overlay with retractable UI like the Content Browser in UE5... It's a huge sacrifice in terms of UI/UX for the user but I don't even know if people will like the app or not. So maybe leave the slate headaches for V2.0 if there ever is any
By the way do you have any idea on how i can use the Widget Reflector on a Standalone Window...
Only works with pie and InEditor...
I do not.
I cant seem to find it in the docs. I have the IPropertyHandle to the property
Committed event of the slider.
https://docs.unrealengine.com/5.1/en-US/API/Runtime/Slate/Widgets/Input/SSlider/ i dont see that event here
Maybe tbr on mouse capture end?
I hope this is the right channel to post this, but I'm creating a widget that inherits from UserWidget on Event Construct and I then want to SetFocus on it (I'm doing this inside another UserWidget).
Doing this through C++ code or BP code, even if I use a delay or wait a long time during Tick, doesn't work because GetCachedWidget doesn't return a ValidWidget.
However, this UserWidget of mine has a UButton. If I call SetFocus using its OnHovered event, it works because at that point the CachedWidget is valid!
I have no idea why GetCachedWidget returns a valid SWidget in one scenario and an invalid one in the other π can someone explain why?
Not when it's involving umg (personally) . You might have luck in #umg, but I think the people that can answer that in there are also in here.
then Id have to create a custom slider class that overrides that method also not really ideal
Well yeah.
I am trying to add a SSceneOutliner , is that even possible?
Thought it would be a simple SNew(SSceneOutliner, FSceneOutlinerInitializationOptions()) to get something visible on the screen but I need to bind something to FSceneOutlinerInitializationOptions.ModeFactory . Not sure how to. tried #cpp message but that's not working
Got it. it's not that hard
FCreateSceneOutlinerMode MF = FCreateSceneOutlinerMode::CreateLambda([this](SSceneOutliner* Outliner)
{
FActorModeParams Params;
Params.SceneOutliner = Outliner;
Params.SpecifiedWorldToDisplay = IconEditorViewportClient->GetWorld();
Params.bHideEmptyFolders = true;
return new FActorMode(Params);
});
FSceneOutlinerInitializationOptions SceneOptions{};
SceneOptions.ModeFactory = MF;
```And then you can just pass it to the `SNew`
There's a Value_Lambda to which you can provide a function that does return width.
Would anyone mind looking at some code for a slate widget related to IInputProcessors? the HandleKeyDownEvent seems to keep listening inside the editor even if the game is not running
whats the best way to get a access a custom font (non-default engine)?
Im currently doing #define TTF_FONT( RelativePath, ... ) FSlateFontInfo( FPaths::ProjectContentDir() / "Slate" / RelativePath + TEXT(".ttf"), __VA_ARGS__ ) but it seems to be casuing random crashes
How are you storing the fontinfo object?
Can you post a minimal repro on Pastebin?
You should probably register and deregister the input processors when your game mode starts or something. Or maybe player subsystem?
ULocalPlayerSubsystem shouldn't exist in the editor.
Or use UWorldSubsystem and check if the world is of type "Game"
Good afternoon folks. I'm digging around in UI design and realized there was a severe gap in my understanding.
I'm attempting to make a UI that is primarily text based with a smaller viewport than the whole screen... How would I go about this? I can of course put my UI over top the viewport, but doesn't unreal fix a lot of things based on the center of the viewport?
This was the layout I was going for
I was thinking UI contains render target, but I'm utterly noob on slate.
Change the game viewport client class.
It creates the game viewport - hosts it, if you will.
So then am I trying to overlay two viewports?
No?
one to hold my UI, the second one to hold my actual viewport?
Or just to change the "center"
It depends what you want to actually put on the screen.
I don't think UMG will work without a viewport to exist on. You could move the viewport position in slate and add slate ui around the edge.
UMG might very well work without a viewport, but I don't know how you'd do it. I think you just use add to viewport, right? From BP?
Then you're good.
Just use Slate/c++ and create your own viewport client.
I think that's how that works anyway, I can never remember which hosts the other.
Or maybe it's the slate widget aht creates the viewport client which creates the viewport...
Start up pie and use the widget reflector to see what's going on!
I should know this, I literally work on this stuff for a living.
The Epic names are confusing.
"tractor no start."
"did you hit it?"
"yes."
"hit harder."
Sounds like my first PC.
ACtually most of them are very computerized and I spend most of my day tracking down diagrams, parts, and esoteric troubleshooting solutions ;p We also fix lithium ion based mowers, snowblowers, robotic lawn mowers, and all kinds of crap....
anyway...
But yeah, the widget reflector is the place to start. You can definitely move the viewport to a custom location within the game window.
I don't even know what the "widget reflector" is ;p
Debug -> tools -> widget reflector.
I assumed you could, because that's what the editor essentially does.
But I saw comments about rendering techniques being disabled.
Or Tools -> debug -> widget reflector.
I as of yet have no widgets. and wasn't touching UMG... yet.
I was in planning stages of it, per the shitty chart image I posted.
And I suddenly realized, nothing I read suggested how I might bifurcate my screen into UI and shrunken viewport.
My googlefu is strong, but apparently not this strong.
top result "creating a custom viewport without C++" which... doesn't help me none!
worst case i s uppose I can stick with standard viewport, and make my UI popout.
text displaying atop the bottom of the screen isn't the end of the world.
I'll give it a play with tomorrow, I at least should be able to find where it sets the size of the viewport.
I'm pretty sure you still need a viewport as render target for slate widgets. so setting the size would just move all that in without a primary viewport, wouldn't it?
Honestly it's probably just a case of finding which slate widget creates the viewport client and subclassing it to create the viewport inside a canvas thingy you can fill with other stuff.
yea
You don't.
Slate can exist without a viewport. A viewport is a view into a 3d world.
Slate draws directly to a window which can contain a viewport.
found \Engine\Source\Runtime\UMG\Public\Components\Viewport.h
The launcher is written in Slate, for instance, and that doesn't have viewports.
hm ok
I suppose it just, when you are writing hud for a game, you are targeting the viewport, which fills a window, and it needs the viewport to get the window handle.
For UMG, I think it has a specific rendering layer on top of the viewport.
That's the UMG viewport code.
SViewport is the slate host for viewports.
I'm sure there are others.
Sigh. Update VS. Recompile engine.
O.o
...and done!
hm... GameViewportClient.h uses canvas to set the size of the viewport.
... I think
no that uses FRenderTarget
which uses FViewportFrame... which has ResizeFrame.
that resizes the SWindow though
Forget bottomless rabbit holes, this is a maze xD
actually, that's an SWindow... what is an SWindow
top level window. ok
The slate representation of a window... yeah.
OK, so, SViewport has slate args, can I set those args...
class SLATE_API SViewport
: public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS( SViewport )
: _Content()
, _ShowEffectWhenDisabled(true)
, _RenderDirectlyToWindow(false)
, _EnableGammaCorrection(true)
, _ReverseGammaCorrection(false)
, _EnableBlending(false)
, _EnableStereoRendering(false)
, _PreMultipliedAlpha(true)
, _IgnoreTextureAlpha(true)
, _ViewportSize(GetDefaultViewportSize())```
I think you want to be dealing with IGameLayerManager
hmm
That's how the PIE window handles things.
I'm not sure if the game does as well.
GameViewportClient.h might also be helpful
Yeah that's where I was digging around
Of course, they've made it an interface without giving you the option of implementing it yourself.
Fantastic.
This seems like something that should be trivial xD
Except the class they use is hard coded in UGameEngine
But no one b uilds games with tiny viewports anymore ;p
oh. SViewport might work as is... I just need to pack it in a sized container.
Yeah.
You need to extend the viewport client so it creates a constraint canvas with the sviewport in a slot.
And then set the game viewport client class to that new class you craeted.
I think.
It's the "Canvas" from UMG.
The SCanvas in Slate is a different one.
SCanvas deals with absolutes (position, size)
SConstraintCanvas deals with relatives.
hmmm
Thanks, you've got me on a track... not sure if it's right or not, but we'll see where it leads! :D
oh, before you go.
ownership, who builds what here? am I building this canvas inside the game viewport, or adding the canvas to the gameviewport...?
or adding gameviewport to canvas?
That's a very good question.
Nuts.
It looks like it calls CreateGameViewport which then, in that method, calls CreateGameViewportClient
So take a look at those.
I hate good questions, t hey should all be stupid and simple and I should be shamed for asking such a stupid simple question ;p
will do
And the CGVC instantiates that game layer manager interface object
Which you may be able to replace with your own one to set geometry. Who knows?
Or maybe it just sets where the individual players are on the viewport as a whole, for widget purposes.
everything seems welded to the window. Without modifying engine code
.cpp
https://pastebin.com/wtY4kk4h
.h
https://pastebin.com/4NqsqTjN
I have tried to make a destructor and put the deregister inside that, but no dice
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
.cpp
https://pastebin.com/wtY4kk4h
.h
https://pastebin.com/4NqsqTjN
I have tried to make a destructor and put the deregister inside that, but no dice
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Ugh... this is infuriating.
My game is Text centric, and the text should be front and center on the UI, but if it's overlaying the viewport, it'll be even worse...
Wasted 4 hours after work now just trying to START writing UI code.
@hot notch FYI: I encountered the exact same problem and was able to solve it:
My AnalogSlider also broke gamepad navigation, but I was able to solve it by setting the Is Focusable flag to true on the CommonActivatableWidget which contains the slider.
(I know your question is from a long time ago, but wanted to share my solution for completeness π )
:/
Are you sure you need to modify engine code instead of overriding classes?
So the destructor isn't there at all in that code?
not sure at all, but I can't seem to find the property to modify that makes it work.
just gonna go with this instead
overlapping the bottom of the viewport is at least less heinous
Yeah.
You can place the slate stuff over the top if the viewport is centred really easily.
yeah that is the original code without adding the destructor
O.o That's the weirdest fix. We went to using an analog cursor movable with thumbstick anyhow. But I'll have to keep that in mind.
So why were you expecting the input processor to be removed when you stopped pie or whatever?
I looked at the CommonUI demo in the Content Samples.
They do it like that over there.
It's indeed a weird fix, as you would expect the Input router to pickup on the focus being released from the slider.
I didn't delve yet into the code to see exactly why this is not happening.
What messed with me was that DPad was working fine. π¦ I don't understand why the same code path isn't used for DPadDown and AnalogLeftStickDown
Well I thought it was being deregistered. But even putting the deregister into a destructor for that class didnt seem to work
Hmn
Common UI is destroying widgets if I call deactivate(). Seems like GC cleans shared pointers. How to prevent this?
GC doesn't clean shared pointers, it doesn't know about them. You should never have shared pointers to UObjects
Should be UPROPERTY() UObject* or TWeakObjectPtr<UObject> only
This is in the engine code, for some reason the widgets are getting destroyed after deactivating if there's a main menu and not getting destroyed after deactivating the pause menu but this is getting destroyed after reactivating. They shouldn't destroy on deactivating.
If something is in the smart pointer (non-uobject) system and every reference to them is cleared, they are deleted. That's just how they work.
And Epic's view on widgets is that they should be destroyed when not in use. So design your code around that.
And don't keep your own strong references to them when you don't need to.
How do I create a strong reference to the widget to prevent destruction? I can't activate / deactivate widgets if they get autodestroyed and there doesn't seem to be any way to destroy them manually either. So I'm stuck. I assigned them to class variables but that didn't prevent autodestroy.
What object type, specifically?
UCommonActivatableWidget
And how are you storing it?
Is it the UObject that's getting destroyed or its internal widget?
Or both?
It's in a UCommonActivatableWidgetStack container where I do AddWidget, this should still have the reference after I deactivate.
in the main menu it destroys it on deactivate and in the pause menu it destroys on reactivate. the only difference is the main menu has a background menu in the stack which is destroying it when it's getting activated.. a bit confusing.
It's getting destroyed in a thing called SObject
What is getting destroyed?
The Slate Object gets destroyed to free up memory.
So the SWidget (or subclass thereof)
There's not much you can do about that. It's just part of the system.
You should put a breakpoint in the NativeDestruct method to see why it's being called at different times. Or it seems you have? Idk.
In this call stack it found the deactivated widget in the stack and reactivating it causes autodestroy. π₯³
I can't say what 's causing it, it just decides the gc the widgets upon activating. there isn't anyhting happening between.
or if another widget activates then too.
That isn't a GC thing. That's the common ui widget destroying its slate widget (the ReleaseWidget() method)
or if i deactivate right after activating then it also autodestroys
Yeah it's common UI doing this.. i tried cleargarbage and setinternal flags didn't do anything.
Maybe a bug
So if you have CommonUI releasing its widget at different times, for no apparent reason, find out what is triggering it. You might have some functionality you didn't know existed or a setting you have set somewhere.
I attempted to force destroy them but there isn't any function to destroy them either.
Either way, you have to work with what CommonUI does. If your code isn't compatible with CommonUI, change your code.
I have no idea.. maybe I'm not adding the widget right.. I'm using AddWidget. There isn't any documentaiton on this.
I have no idea how.. i stepped through each line and it just jumps to memory stuff after doing a tick.
call stack is also limited in size can't say what happens befoer all those engine functions.
I got all of common ui working except for this one bug
It's unlikely to be a bug.
There's ZERO documentation on how to do this in C++ so I probably messed up somewhere.
or Epic did. Only two possibilities.
The issue is there's not much to mess up. my code is very simple unless I'm doing the wrong functions to add / remove the widget. I'm at my wits end.. it should just work.. adding a widget and then deactivating shouldn't destroy it. Tha'ts just not normal.. nothing i can dol.
It's like 3 paragraphs.
It says they hold the reference for one frame.. okay that helps! I do not understand the rest seems irrelevant. This may be related to the tick thing.
Okay so when I add the widget then do deactivate right after.. it was destroying it but waited for the tick. That clarifies it a bit.
That's why it's destroyed on the tick event you see there.
(in your callstack screenshot)
I'm surprised there's Zero tutorials on how to add / remove a widget in Common UI.. the most basic thing.
Yeah.. that explains the tick thing at least..
Because you're generally meant to use UMG in the editor, not c++.
...yes?
That's not a gc. That's just a referencer counter reaching zero.
The smart pointer system used by Slate is not related to the UObject GC whatsoever.
do you know if i can increase the displayed call stack?
maybe i put breakpoints on those engine calls to see what happened before.. that should do it
that's a big issue i can't see the earlier call stack before this stuff kicks in to see what causes it.
Run in debug editor, rather than debug game editor or development editor, might give you more debuggable locations. Or maybe not.
whgat's the difference between debug editor and debug game editor?
Debug Editor = engine and game are in debug configuration. Debug Game Editor = only game is in debug configuration.
Oh okay that should help Thanks!
Debug Editor is only available in source builds.
I only have DebugGame and DebugGame Editor. Which one does the engine?
Even this simple blueprint doesn't work.. It autodestructs upon deactivate. Seems to be a bug in 5.2.
Why is that an error?
It's not supposed to destroy upon deactivation. The whole point of activatable widgets is to reactivate them. This is impossible now.
I'm sure this was all working for me in 5.1. RemoveFromParent doesn't seem to work anymore either. Which is similar to Deactivate.
It's not supposed to. The docs say that it's deactivating it and that's what it does in code... the SOBJECT destructor gets called for some reason by the slate memory cleanup. It's not supposed to do this. It's not usable this way.
Can't explicity destory things, most menus are supposed to deactivate on ESC key but this is not always destroying either.
There must be some secret setting to prevent it from autodestroying or its a bug. There's nothing wrong with that simple blueprint.
I'm sure I tested this basic stuff in 5.1 and all those functions were working before. Have to see if someone else faces this.
I'm starting to see why laying out the UI in UMG is easier/better... xD but I still need to mix both. most of my data is in C++
You can expose data to Blueprints (and thus UMG)
yeah
I was actually going to ask about that canvas you mentioned earlier, there doesn't seem to be a blueprint equivalent
though I didn't poke it long enough to know if that was what I wanted to use.
constraint canvas
There is no UMG equivalent of SCanvas. The Canvas from UMG is SConstraintCanvas.
Which can work like SCanvas, it's just a lot more convoluted.
How would I go about making things scale based on resolution?
I'd like to simply divide the screen into regions, 1/4 here, 1/32nd there...
which is what I thought, but the blueprint doesn't seem to reference any positioning/ratio/percent methods
It's in the slots.
Add something to the canvas and you can then edit the slot details.
only in exact pixels it seems
No, there are other settings.
You have to use anchors for that, I think.
Anchors are 0->1 on X and Y.
ahhh
So if you want something in the top half of the screen, the top left anchor would be 0,0, bottom right would be 1,0.5.
Or some such.
Offset is then applied after that, so you could anchor to the top-half of the screen and then shift down 10 pixels from the top.
Etc.
I missed the expansion for the anchors
just the dropdown which... didn't do what I was expecting XD
There's also alignment apparently.
They all do something different.
If you want it to work exactly like the regular canvas, set the anchor to 0,0,0,0 and use the offset to set position and size.
If you want relative size/position... good luck π
thanks
If you have specific "how do I make this to go there?" questions, gimme a shout.
hmm... here's one... how do I make grid panel work inside canvas? xD
it goes buggy the second I wrap it
or at least, the display of it does.
oh... size is the problem I think
Use the widget reflector to work that out.
It shows you the desired and actual size of elements in the tree.
It's godly for Slate debugging.
hm, got any good tutorials on styling/configuring buttons?
Im a shitty artist, but anything is b etter than flat gray ;p
starship? you lost me.
I'm releasing a plugin that does exactly this in a week or 2 if you're interested and have the time...
I'll probably be well beyond this by that point XD
Yeah probably....
Starship is a window/editor in UE5 that shows all the editor widgets and styles
gotcha.
How do you open it?
Can't figure it out...
if anyone else is wondering
https://twitter.com/RyanJon2040/status/1434086331806846978?s=20
You can also get there like this
Starship is the name of the styles in the editor.
is there a way to get SGraphPinText to constrain its width? in the picture, the graph pin is inside a SBox with the max width set to 320. mousing over the graph pin shows the pink part of the pin has its width set properly but the STextPropertyEditableTextBox part is misbehaving
You were right, Common UI does reset widgets on activation and destroys deactivated widgets (which may be a bug because I think they're using the wrong release function). It does reactivate the Back key deactivated widgets somehow but I haven't figured out how to do this. The comment also say to avoid caching. Maybe they're not meant to reactivated manually or the destroying seems to be a bug as reactivating them would still reset them so there isn't any need for UE to destroy them. π€·
turns out its the wrap size which you cant change ... nicely. thats why this abomination exists ```cpp
StaticCastSharedRef<SMultiLineEditableTextBox>(PinToAdd->GetValueWidget()->GetChildren()->GetChildAt(0)->GetChildren()->GetChildAt(0)->GetChildren()->GetChildAt(0))->SetWrapTextAt(318);
I remember that something said that you are not supposed to save state in CommoUI widgets because the framework somehow decides which widgets to reuse and which not to. Can't remember if it was in documentation or comment
Pretty new to slate, I'm having linker errors trying to create:
SNew(SComboBox<TSharedPtr<FString>>);
LNK2019
Did you include the slate and slatecore modules in your build.cs?
And teh combo box header.
In your file.
@grave hatch Yup:
Build.cs:
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"UMG",
cpp headers:
#include "Widgets/SNullWidget.h"
#include "Components/ComboBoxString.h"
#include "UObject/EditorObjectVersion.h"
#include "UObject/ConstructorHelpers.h"
#include "Engine/Font.h"
#include "Styling/UMGCoreStyle.h"```
h. headers
#include "CoreMinimal.h"
#include "Components/ComboBoxString.h"
#include "NDAClass.generated.h"
I don't see the combo box include? It should be under Widgets somewhere.
Widgets/Input/ComboBox.h
oh, I just included ComboBoxString as it includes ComboBox too, but let me try thanks!
Don't rely on second-hand includes.
But if it's already included, prboably not.
Give the full compiler output.
So what is that telling you is missing?
SComboBox?
I have a viewport with an actor for which I set the UE::Widget::EWidgetMode inside of the ViewportClient. When I hit delete I Destroy the actor and set the WidgetMode to None, but for some reason the cursor will still change when I hover over the last position of the widget until I click into to the viewport. FSlateApplication::GetFocusedWidget is telling me the whole time that the viewport is focused
Another problem is that when I spawn a new actor the widget position will be set to the new location of the actor but I have to click once into the viewport before I can actually grab the axis
The more I describe the issue the more it sounds like the focus, but the output from SlateApplication tells otherwise π€
Uhhh that could be it. Will keep looking where to do that but if you happen to see the message before I find it, can tell me how to? π
Is it FScene::UpdateAllPrimitiveSceneInfos?
No.
It's on the viewport client somewhere I think.
virtual void RequestInvalidateHitProxy(FViewport* Viewport);
It might be this.
Oh wait.
That just calls the InvalidHitProxy() method on the viewport.
So yeah, call that on teh Viewport.
Well, that wasn't in the list of word I searched for
Yaaaay, that was the issue in both cases. Thanks Senpai πββοΈ
Np.
Is there a way to use a lambda as a delegate of a OnTextChanged or OnClicked? I am fine with wrapping it in a delegate or whatever.
Yes. Not sure if it's possible for everything but you can use WhatEverYouHave_Lambda([](){})
This one surprised me for example #slate message
For that to work the arguments have to match the delegate that is called right? Can the capture list have more than that?
I think that fixed it. Iβm not in a position to test right now. Thanks!
Is there a way to manually trigger the tooltip?
You can whatever you like in the capture list, I think. And yes, the arguments have to match
No experience with ToolTips but I would breakpoint the SToolTip::OnOpening and look at the call stack to see what functions are used. You should be able to figure out what you would have to call
ah thats a good idea, where can i find the stooltip inside the engine folders? rider doesn't seem to find it
nvm found it
Don't waste too much time though. I have no clue how tooltips work so I might be wrong. You can wait for our lord a savoiur/slatebender Daekesh to help you out
alright thanks π I already found something useful to debug, the actual widget path when hovering with the mouse over the viewport. might be helpful to debug if there is a way to show the tooltop from a widget underneath the dragged widget
this is what I've tried so far, didn't work as the widgettooltip ptr is null:
const FWidgetPath WidgetPath = FSlateApplication::Get().LocateWindowUnderMouse(UWidgetLayoutLibrary::GetMousePositionOnViewport(this), FSlateApplication::Get().GetInteractiveTopLevelWindows(), /*bIgnoreEnabledStatus =*/true, 0);
if(WidgetPath.IsValid())
{
if(const TSharedPtr<IToolTip> WidgetTooltip = WidgetPath.GetWindow()->GetToolTip())
FSlateApplication::Get().GetCursorUser()->ShowTooltip(WidgetTooltip.ToSharedRef(),UWidgetLayoutLibrary::GetMousePositionOnViewport(this));
}
perfect outcome would be if i can enable the tooltip from the widget below the top one as i want to display the tooltip from the widget underneath the drag widget
There's a "get widget under mouse" or some such function.
You could try using that code to get the widget under the widget under the mouse.
the problem is not really to get the widget under mouse, the problem is rather to trigger the tooltip
I thought you'd successfully done that, just with the wrong widget.
I don't think this is the correct way to do it
assuming the top level widget here is the drag widget, i also assigned a tooltip to the drag widget but it isn't valid
Are you sure it was instantiated?
I am doing this on the drag widget :
Hey, I already asked this on the #umg channel, and since I'm not even sure it's possible with UMG, I'm asking here also:
I want to create a simple rectangle "crosshair" (not really a crosshair since it's a rectangle) that inverts the colors behind it (similar to the minecraft crosshair, if you're familliar with that). I read about the retainerbox (https://benui.ca/unreal/ui-retainerbox/) and that it allows to render everything that's in the retainer box to the texture parameter of the material supplied, so I thought it would be a good fit for my choice (as seen from this reddit thread, with the guy having the same issue as me: https://www.reddit.com/r/unrealengine/comments/ydtrmq/any_way_to_invert_colors_through_a_umg_panel/).
I tried to setup a material that does 1-x on the texture parameter, and I set that material on the retainer box in my widget. If I don't put in the retainer box, nothing gets rendered. If I put an image, it's color does indeed get inverted, but not the color of the background (ie. the scene).
Is there any way to do what I want?
I know I could probably do it with a SceneCaptureComponent and use that as the texture sample for my material and just use the retainerbox texture as a mask for it, but it seems ridiculously complicated for something that sounds like it should be easy to implement.
Why not use a post process material?
Can a post process material be used on the retainerbox?
And even so, what would that change?
I mean, don't use a retainer box at all.
Just use a pp material to invert the centre of the screen.
One applied directly in the camera settings.
How can I apply it only to the center of the screen? Using a mask?
Or a little math.
I'm not really familiar with materials in general, so could you eleborate?
The size of the screen and the current viewport coordinates are available in materials.
Just do a bit of math to filter out the centre.
I don't know the nodes you'd use offhand.
Oh, thanks, I didn't known that
And then I can just add this post process material to the blendables array on the camera?
Something like that, yes.
Thanks for the idea, I'll try it out!
Np.
I'm unfortunately still stuck here, any further ideas on how to trigger the tooltip manually?
Does it need to be a tooltip?
If you can bend the tooltip system to your will, maybe try something else?
@grave hatch I found the node you mentioned, it's named ViewSize, but tbh I still feel kinda lost, as I have no idea how to overlay anything on the screen trough this PostProcess material. I know I have to start from the SceneTexture:PostProcessInput0 node, but how can I add an overlay to it? Even if not centered?
You would need to use some logic to 1) work out the area you want to invert 2) move that area based on a material parameter.
As I said, it will take some math.
And the branch node. Whatever it's called.
I understand that, what I'm asking is, I don't know how to even overlay an existing texture over the input
Yeah it does not need to be a tooltip but i need the "tooltip" to not clip and as I want to have the tooltip displayed over the drag widget, which is always at the top level, the "tooltip" needs to be part of the drag widget, so it is pretty hacky to adjust the tooltip position inside the drag widget to make it not clip outside of the viewport. Hope this makes sense to you π
Yes, but how do I overlay that on top of the PostProcessInput?
Yeah i would just prefer using the built in option instead of implementing a hacky workaround, but..
You have a branch thing. If it's within the area (or whatever) you use the texture sample, if it's outside the area you use the post process input.
Absolutely, I agree, there's no reason to use hacky shit if the inbuilt stuff will do it.
It's just a question of whether the inbuilt stuff will do it.
Oh, thanks, is it the DynamicBranch?
No.
It has 5 inputs, A, B, A < B, A == B and A > B
It should come up if you put "if" into the node search
I think?
Oh yeah, found it
So I'd probably solve that by using 4 of those nodes - you need to check if it's >= the start of the area and <= the end of the area on both axes.
Then you work out where the area is (using a bit of math - bear in mind the screen UVs will be in 0-1, not pixels)
And plug it into the right place.
Basically: ```
if (UV.X >= Area.X)
{
if (UV.X <= Area.X + Area.Width)
{
if (UV.Y >= Area.Y)
{
if (UV.Y <= Area.Y + Area.Height)
{
// it's in the area, return stuff here
}
}
}
}
return normal input```
It's really annoying to do math like this with nodes.
Thanks, it makes sense now. And this UV you mention I get trough the ScreenPosition node, right?
Not too sure.
In my 10 years with UE, I've made a single PP material.
If you want the "UV" of the area itself, you can do (UV.X - Area.X) / Area.Width (that would be the X coordinate of the area from 0-1)
You could, for instance, map that directly to a texture sample to replace the entire area with a texture.
Can I use SlateStyles in runtime as well or is it just editor only
I made my own style set for a plugin but the brushes are missing in the packaged game
Anything in the editor or development folders aren't usable at runtime.
The idea of styles themselves can be used, but individual ones? See above.
I think.
No
SRichTextBox? Or whatever it is.
The actual rich text element.
I mean you might have been trying to use an existing widget to do something more than it can.
A widget in somebody else's UI. Like details panel etc.
Yeah to daekeshβs defense when I read your question I assumed you were looking for an alternative of SRichTextBox
You have to define a style and stuff.
It's overly complex.
I think you can do it inline, too, maybe. I'm not sure.
Created by a java developer I'm sure.
Was something I found earlier.
Lol
RichTextBlockBoldStyleFactory
Just a joke about enterprise Java code. π
Friends don't let friends use enterprise java code.
Call Invalidate on teh window
can anyone recommend some good resources/documentation for basic slate usage? the official UE documentation isn't quite enough
Not sure if there is anything that gives a good introduction. Best you can do is probably just make a Plugin with the standalone window template and than add some widgets that you find interesting and inspect with the Widget Reflector
And the UMG/Slate compendium in the pinned messages
I have a World and add streaming levels to it. Is load/unload and hide/unhide them at some points. For some reason the actor of the scene will be visible but won't be displayed in my SSceneOutliner. If I call UWorld::RefreshStreamingLevels while the actor is not visible in the SSceneOutliner will add it to it BUT when I call it again the actor will disappear again. I am debugging it RN but maybe someone encountered that already
yeah thats what i've been doing. it's pretty terrible lol
so i'm following this guide and i'm trying to add a widget onto a window but it's not showing up??
the guide: https://docs.unrealengine.com/5.1/en-US/slate-editor-window-quickstart-guide-for-unreal-engine/
it shows blank
i tried commenting everything out and adding a single text block but that doesnt show either
if anyone responds to this please make sure the mention is on
Show your code
{
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("hi"))
];
}
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SSAToolMenu)
];
}
i can send the entire thing but i figured these are the important parts
can you try void SSAToolMenu::Construct(const FArguments& InArgs) { ChildSlot [ SNew(SBox) .HAlign(HAlign_Center) .VAlign(VAlign_Center) [ SNew(STextBlock) .Text(FText::FromString("hi")) ]; ] }
i'll try now
thanks, that worked. the guide literally tells you to remove ChildSlot
it being included in the commented code
the guide also tells you to test how it looks before it even gets you to implement it???
so stupid. thanks a lot
The pinned messages and the engine source code.
The way I've done Slate stuff is find something in the editor that looks like what I want to do, then go see the source code for that thing.
The tools -> debug -> widget reflector is super useful for that.
gotcha, thanks!
why is deleting an FSlateBrush pointer causing a crash
are they somehow GC'd and I shouldnt do this?
The pointer is used in the style (if you put it in one), so if you delete it, it will cause a stale memory crash.
It isn't copied.
If i wanna to a widget with scrollable screen like for instance the old finalfantsy where u can scroll the canvas (make it alot bigger then the screen size) what would i use then ? "Scroll box" or ?
YEah.
or ScrollPanel.
I can never remember which is the one you use.
They're both in the same file and one uses the other.
Has anyone had any luck with creating 3d viewports for custom assets? Just wondered if theres a good template or a basic asset in the engine I can copy from
I tried MaterialInstance and StaticMesh but theres still a fair bit of junk in those I dont need
Have you looked at this? https://twitter.com/codekittah/status/1638215963345559560?s=46&t=HTACR-PJmTG1D93BsYUKSg
Wrote over the last couple days an Asset Editor Template plugin. Has a simple asset along with a 3D View (Advanced Preview Scene), still more to comment but should act as a nice basis for making your own Asset Edtiors in #unrealengine.
#UE5
Link β¬οΈ
https://t.co/FRoUTfhaMF
β€οΈ
107
Itβs a template/example implementing a 3D viewport for custom assets
Thats purrfect, thanks! Surprised I didnt see this...
Follow them on Twiiter and read their Medium articles earlier but missed this one, doh
Hey, guys!
Is there a delegate like OnEditorOpened(there is no such, just guessing the name)?
I want to create a modal window as soon as editor opens, and provide root window(which is editor main) as parent to modal window.
Hmm. Maybe.
does any one know how to create moving texture UI
Either a sprite sheet or a material
Just some displacement UVs with a mask
hello i'm trying to do a slate widget that is in front of everything and receives touches but doesn't block the input, so widgets behind it will still trigger, like buttons. i have the visibility set to visible and have overriden OnTouchStart and OnTouchEnded with Unhandled reply, but it still blocks the input
what am i missing?
It might not work if they aren't in the same widget path.
For instance, an image on a button passes the click back to teh button which processes it. Or then passes it back to its containing widget, and so on and so on.
If the shared root of your 'on top' widget and the widget you want to receive the click is basically the window, it won't work?
What you might need to do is use an input processor which specifically targets the on-top widget.
But then make the on-top widget hit test invisible.
That should work without issue.
yes that what i ended up doing, thanks anyway π
Hello any idea why it does not want to accept my function and my parameters? : (
It is on a plugin class
For some reason it does not want to work I tried everything
Close the errors list.
Never open it again.
Open the output tab.
Copy+paste, not screenshot, the errors from the output tab.
Wow intellisense is actually working
would widget reflector works on things like the toolbar ui
Yes
thank you
What errors
???
Compile errors?
ok
''' Build started...
1>------ Build started: Project: CHLPlugin52, Configuration: Development_Editor x64 ------
1>Using bundled DotNet SDK version: 6.0.302
1>Running UnrealBuildTool: dotnet "....\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll" CHLPluginEditor Win64 Development -Project="D:\VideoGameProjects\UE\Ue5\UnrealEngine5.2\CHLPlugin\CHLPlugin52.uproject" -WaitMutex -FromMsBuild
1>Log file: C:\Users\neon\AppData\Local\UnrealBuildTool\Log.txt
1>Unable to build while Live Coding is active. Exit the editor and game, or press Ctrl+Alt+F11 if iterating on code in the editor or game
1>D:\VisualStudio\IDE\MSBuild\Microsoft\VC\v170\Microsoft.MakeFile.Targets(44,5): error MSB3073: The command ""D:\Engines\UnrealEngine 5.1\UE_5.2\Engine\Build\BatchFiles\Build.bat" CHLPluginEditor Win64 Development -Project="D:\VideoGameProjects\UE\Ue5\UnrealEngine5.2\CHLPlugin\CHLPlugin52.uproject" -WaitMutex -FromMsBuild" exited with code 6.
1>Done building project "CHLPlugin52.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Elapsed 00:01.833 ========== '''
''' code my code '''
How was it to post code in discord ?
and that is from live code
any idea slaters ?
The errors/warnings you get in the errors list are usually wrong
Only worry about compile errors.
What's the definition of PluginButtonClicked?
You need to close unreal engine before you build. Your error says that live coding is active (meaning the editor is open)
I will deliver soon
Wait like ue3 unrealscript mmmmmmh ok
I don't know what you are talking about but the answer is probably no
He figured that out, I think.
Hey this is code is that answering you what is the definition?
void FCHLWindowBlugin52Module::PluginButtonClicked()
{
FGlobalTabmanager::Get()->TryInvokeTab(CHLWindowBlugin52TabName);
}
thanks : D
Hey also this is the whole code for the plugin main class
cpp
// Copyright Epic Games, Inc. All Rights Reserved.
/* tasks
-1 create the basic keyowrds to create pawn
-2 try to find the class assigner but as object not just pawn
*/
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class FToolBarBuilder;
class FMenuBuilder;
//Convert these to a keywords array
FName Keywords("CHLWindowBlugin52");
TArray<FName> ArrayOfKeywords;
int a;
class FCHLWindowBlugin52Module : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
/** This function will be bound to Command (by default it will bring up plugin window) */
void PluginButtonClicked();
const UClass* SetCurrentClassOfContext() const;
void OnSetClass();
TSharedRef<class SDockTab> OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs);
private:
void RegisterMenus();
private:
TSharedPtr<class FUICommandList> PluginCommands;
};
.h
When you bind a function to a delegate, you have to match the signature.
You didn't.
match the signature with what ? You mean the parameters of the function?
in this case it's the return type.
Look at the delegate you're binding to.
Look at any other function that binds to that delegate.
/** Called when the button is clicked */
SLATE_EVENT( FOnClicked, OnClicked )
/** See OnClicked event */
void SetOnClicked(FOnClicked InOnClicked);
But FOnClicked I have no idea
how has it to be
Ignore the SetOnClicked
Just look at any other function that uses the OnClicked event. Search the engine source.
ok....
makes sense
FReply HandleNextButtonClicked()
{
Carousel->SetNextWidget();
return FReply::Handled();
}
Ok seems to be some like that Ima give it a try
ok no error now thanks
Still I have to get the ClassSelector to work this aint over
Thanks a looot
Is there a way to bind lambda to ontextchanged events? I have searched far and wide and the only solution I see is making a new event. When I try to make that the macro is broken.
OnTextChanged_Lambda(...)
Does that work on UEditableTextBox objects?
Ok it looks like that does work for slate only builds. I am doing an apparently highly cursed hybrid setup.
I have access to the slate widget, but the widget is created by UMG.
Close the editor, compile, restart editor, try again.
im using commonui, i cant figure out why gamepad buttons turn into mouse clicks
is there a setting for this? it seems to be messing up my 3d widget component input stuff
this Dan H guy has caused me a lot of pain
compiled
1> with
1> [
1> UserClass=FCHLWindowBlugin52Module
1> ]
1>D:\Engines\UnrealEngine 5.1\UE_5.2\Engine\Source\Runtime\Slate\Public\Widgets\Input\SButton.h(77): note: see reference to function template instantiation 'TDelegate<FReply (void),FDefaultDelegateUserPolicy> TDelegate<FReply (void),FDefaultDelegateUserPolicy>::CreateSP<UserClass,>(UserClass ,FReply (__cdecl FCHLWindowBlugin52Module:: )(void))' being compiled
1> with
1> [
1> UserClass=FCHLWindowBlugin52Module
1> ]
1>D:\VideoGameProjects\UE\Ue5\UnrealEngine5.2\CHLPlugin\Plugins\CHLWindowBlugin52\Source\CHLWindowBlugin52\Private\CHLWindowBlugin52.cpp(155): note: see reference to function template instantiation 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked<FCHLWindowBlugin52Module,>(UserClass ,RetType (__cdecl FCHLWindowBlugin52Module:: )(void))' being compiled
1> with
1> [
1> UserClass=FCHLWindowBlugin52Module,
1> RetType=FReply
1> ]
========== Elapsed 00:45.138 ========== hey guys why this? I am trying to bind A .OnClicked event with a function any help?
Help ? mmmmh Is there anyone ?
I had a similar issue but without code its difficult to offer a solution. Daekesh had some great advice about looking for similar code and copying what Epic do. I suggest changing your function return type from Void to FReply and returning FReply::Handled()
It does not recognize my command : O
and it gets called later? : P
well.... mmmh it was me XDDDD story not over slate is hard no next thing
Real issue becomes when you want to do something that isnt in the codebase already
Mmmmmmh like making slate work with stuff that is not defined?
Well Epic clearly have ideas on how they expect things to be worked with so the job becomes more one of mind reading than programming
What I find is people will get up on stage, whip through an example and give plenty of info but then when you try to apply that knowledge in a different context it all falls apart
You're trying to use a shared pointer bind on something which doesn't inherit from TSharedFromThis<type>
You need to change it to Whatever_Raw
So thats how its meant to work, I just ended up making functions on the shared pointer which wrapped through to the other object
No
What you should do is simply add , public TSharedFromThis<yourclasstype> to the end of the class yourclasstype line
Not even sure thats the correct way since its an object from a game module, trying not to include editor code
That isn't editor code.
That's how you bind to a shared pointer delegate with a random class.
Or you can use the _Raw bind, but then you have to unbind manually when your object is destroyed.
I like your confidence, I'll keep it in mind but I'll probably forget this
I do this as a job π¦
yeah as soon as Im back on gameplay the whole Slate context will get dumped from memory
no manual unbinding π
{
Weapon->Reload();
return FReply::Handled();
}```
This shared pointer is a details customisation for UWeapon so the chance of it being null is pretty slim π
You should still check
Maybe if it's performance critical code and you can be 100% sure weapon isn't null...
I dont understand why I cant bind to the UObject being customized though without raw ptr
Why wouldn't you be able to?
the details panel cant be created without the object π
I suppose it could draw incorrectly somehow, maybe there is a better accessor to the object which is a shared ptr already
I think I'm totally not understanding what you mean, btw.
What shared pointer?
I cast it from an array in the details panel to UWeapon, perhaps that array contains the shared pointers not raw objects
IDetailsView SetObject()
UObjects can never be shared pointers.
so I cant do that TSharedFromThis<>?
Not for uobjects, no
LevelEditorModule.OnLevelEditorCreated() someone was asking about a delegate for when the level editor opened.
Just happened across that
I dont do this for a living, my head hurts though lol
Pretty cool though when I hit the fire button I get line traces happening in my weapon editor. Soon I'll have abit more of the functional stuff
That is pretty cool.
I might run into some issues running real-time things in the viewport though especially when I exit out of the weapon editor window. I noticed with the more interactive editors they have alot of clean up
Done what?
Do anybody know about "How we can read data of JSON File from Local Storage and print it to Widget Text?"
I did i see on post
How do you fix that ?
that create sp dies not wanna work
finally I got it it was some sort of magical 0s and 1s and visual studio helping me like the retard I am π
oops now there are compile errors
Help? That sclassproperty.......... Hard
Does OnSetClass(this, &stuff:things) not work?
No
I mean no it does not work
Have you tried looking in the engine for how it's done?
Or looking at the error messages?
I will bring you soon the error
Help so, waht is the error what shall I fix ?
set there onRaw ?
or what thanks...
Unresolved linker errors are usually due to missing header files, missing modules in your build.cs file, or missing API export on the file youβre extending
I would double check all the modules youβre using are in the build.cs file
Same with any headers
Ok thanks ππ
It is exported, the module is PropertyEditor
My guess is they were missing the module in the build.cs then
Is this here the right way i.e using the setter after using SNew, or should that be before ?
TSharedRef<SWidget> UBetterButton::RebuildWidget() // UBetterButton extends from UButton
{
const FBetterButtonStyle& StyleSettings = UBetterDeveloperSettings::Get().ButtonData;
const FButtonStyle& ButtonStyle = ShouldUseSettings ? StyleSettings.ButtonStyle : GetStyle();
const FLinearColor& LocalColorAndOpacity = ShouldUseSettings ? StyleSettings.ColorAndOpacity : GetColorAndOpacity();
const FLinearColor& LocalBackgroundColor = ShouldUseSettings ? StyleSettings.BackgroundColor : GetBackgroundColor();
MyButton = SNew(SButton)
.OnClicked(BIND_UOBJECT_DELEGATE(FOnClicked, SlateHandleClicked))
.OnPressed(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandlePressed))
.OnReleased(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandleReleased))
.OnHovered_UObject(this, &ThisClass::SlateHandleHovered)
.OnUnhovered_UObject(this, &ThisClass::SlateHandleUnhovered)
.ButtonStyle(&ButtonStyle)
.ClickMethod(GetClickMethod())
.TouchMethod(GetTouchMethod())
.IsFocusable(GetIsFocusable());
SetStyle(ButtonStyle);
SetBackgroundColor(LocalBackgroundColor);
SetColorAndOpacity(LocalColorAndOpacity);
if (GetChildrenCount() > 0) Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
return MyButton.ToSharedRef();
}
This Slate thingy is still somewhat confusing me after seeing mostly non-slate UE code
Cuz apparently i'd need the SetStyle(ButtonStyle); call as this line here .ButtonStyle(&ButtonStyle) is not really doing that what i would expect
Something around that, yeah
void UButton::SetStyle(const FButtonStyle& InStyle)
{
WidgetStyle = InStyle;
if ( MyButton.IsValid() )
{
MyButton->SetButtonStyle(&WidgetStyle);
}
}
.ButtonStyle(&ButtonStyle) on the other hand just assigns the passed pointer
What is ShouldUseSettings meant to achieve?
Is it your value or does it come with the class?
I mean it's obvious what it does in that code there.
By default it will use the settings(style) i've pre-defined, as in how the button should look by default.
When you disable it you can apply a custom style right in place
But why?
Why not just set the style you want on the button?
That's how that's meant to work?
(on the UButton)
Basically to have a consistent style across the project when you add a button.
Otherwise you'd end up with the default UE look which you'd then need modify in order to get this consistent look
And that on every single button you gonna add xD
So i'm actually just re-creating CommonUI in that sense
So set the same style on each button?
Or derive from UButton and add a style.
It seems wrong to have a WidgetStyle variable and then totally ignore it when you could just set the widget style variable...
Same goes for the other settings
On each UBetterButton, yes
Kind of confused what you mean by that
UButton has a WidgetStyle varaible, no?
Or is that your variable?
Why aren't you using that variable instead of having a style and a second default style?
Just set the style variable.
Not sure if more context will help, but better than not enough context xD
So i'm extending from UDeveloperSettings in where i store the pre-defined style. (The style is only getting modified within the Project Settings)
And the RebuildWidget method is the only place i'm aware of to apply these settings dynamically. Like that i can change the style in the Project Settings to instantly see the results in my UUserWidget's without needing to restart the whole engine
But yeah, i kinda see now that this isn't really a great way of doing things
UDeveloperSettings has a delegate which fires when settings are getting changed, but i have no idea how i could call for instance UButton::SetStyle on every UBetterButton i have in my UUserWidget's
Actually, now when i look how CommonUI is doing it, it seems like the place i should use is SynchronizeProperties instead of RebuildWidget
void UBetterButton::SynchronizeProperties()
{
if(ShouldUseSettings)
{
const FBetterButtonStyle& StyleSettings = UBetterDeveloperSettings::Get().ButtonData;
WidgetStyle = StyleSettings.ButtonStyle;
ColorAndOpacity = StyleSettings.ColorAndOpacity;
BackgroundColor = StyleSettings.BackgroundColor;
}
Super::SynchronizeProperties();
}
Works now just as well as my first thing, so thanks for leading me to this here π
Dw, that's how it should be as the super method then starts to work with the data of WidgetStyle and similar
What do you mean?
Can you guys make tutorial on slate how to use the complicated widgets?
Please xd
There already is one.
It's called the engine source
You need to add PropertyEditor to your build.cs
Ok
Where is the link ?
These slate components are very hard to use i think but the architecture is great idk....
Finally i see π
β¬οΈ
β¬οΈ
Hey it worked but with errors
is that really working
well
From the visual studio build did
But popped up some breakpoints
But if I try from the editor it self without compiling previously there goes this
does anybody know how to use get property ?
In that particular instance, you need to use -> instead of .
ahhhhhhhhhhhh
let's see
why ?
abhh it is a pointer
Now?
what is that ESPMode:HreadSafe?
ThreadSafe?
Oh sorry.
You need to do .Pin()->
not just ->
But if you do .Pin() you might get a null ptr...
Ok
What you'd generally to is: cpp if (TSharedPtr<type> SomeObject = SomeObjectWeak.Pin()) { SomeObject->DoStuff(); }
Oh is that
#umg ?
I don't really use umg, so you're alone on that one unless someone from #umg helps.
oh ok
Still I cannot figure out how you make that work fine
this
how can I apply that to the code : P
if (LayoutBuilder.Pin()) gets the valeu but then instantly discards it.
Copy and paste the code I did, Put your types and variables in.
I am not trying to assign to null
I am trying to do this
DefaultGameModeClassHandle = LayoutBuilder::GetProperty(GameModePropertyName);
and that gives an error
Which is not even allowing me to compile
No
That is not the type.
That is part of the type.
What is the full type?
Hint: it's in the screenshot you pasted above
TwealPTR<IDetailLayoiutBuild,ESPMode::ThreadSafe>
It says that has no member getproperty
That'll do
if (TSharedPtr<IDetailLayoutBuilder> LayoutBuilderPinned = LayoutBuilder.Pin())
{
DefaultGameModeClassHandle = LayoutBuilderPinned->GetProperty(GameModePropertyName);
}```
It is like getProperty dies some mmh ok lemme try
wow no errors weord
let's try
pin is like for clearing it ? isnt it ?
No
Pin converts it from a weak pointer to a strong pointer.
No
If that weak pointer is invalid, it will be a null strong pointer
If it is valid, the strong pointer will keep the object alive while the strong pointer exists.
aha I see
if (TSharedPtr<IDetailLayoutBuilder> LayoutBuilderPinned = LayoutBuilder.Pin())
This line will only be true if the weak pointer was valid.
However
I strongly suggest you do not use this particular method because it's critical to your widget.
check(DefaultGameModeClassHandle.IsValid()); ok
It compiles
and runs
But it tells me there is an error
check(DefaultGameModeClassHandle.IsValid());
I woudl do this:cpp TSharedPtr<IDetailLayoutBuilder> LayoutBuilderPinned = LayoutBuilder.Pin(); check(LayoutBuilderPinned.IsValid()); DefaultGameModeClassHandle = LayoutBuilderPinned->GetProperty(GameModePropertyName);
When running the scripts
well
I learn soemthing new
All the variables that are processed
In the source code should be proecssed in your code to
Ok
lemme run with no
VS debug...
Why would you run without debugging?!
Assertion failed: DefaultGameModeClassHandle.IsValid() [File:D:\VideoGameProjects\UE\Ue5\UnrealEngine5.2\CHLPlugin\Plugins\WindowTest2\Source\WindowTest2\Private\WindowTest2.cpp] [Line: 154]
UnrealEditor_WindowTest2!FWindowTest2Module::OnSpawnPluginTab() [D:\VideoGameProjects\UE\Ue5\UnrealEngine5.2\CHLPlugin\Plugins\WindowTest2\Source\WindowTest2\Private\WindowTest2.cpp:154]
UnrealEditor_WindowTest2!TBaseRawMethodDelegateInstance<0,FWindowTest2Module,TSharedRef<SDockTab,1> __cdecl(FSpawnTabArgs const &),FDefaultDelegateUserPolicy>::Execute() [D:\Engines\UnrealEngine 5.1\UE_5.2\Engine\Source\Runtime\Core\Public\Delegates\DelegateInstancesImpl.h:408]
UnrealEditor_Slate
UnrealEditor_Slate
Ok now the error is the following one
assertion failed... mmmh
Did you change the code to the lines I suggested?
//DefaultGameModeClassHandle = LayoutBuilder.GetProperty(GameModePropertyName);
if (TSharedPtr<IDetailLayoutBuilder> LayoutBuilderPinned = LayoutBuilder.Pin())
{
DefaultGameModeClassHandle = LayoutBuilderPinned->GetProperty(GameModePropertyName);
}
check(DefaultGameModeClassHandle.IsValid());
//DefaultGameModeClassHandle = LayoutBuilder.GetProperty(GameModePropertyName);
if (TSharedPtr<IDetailLayoutBuilder> LayoutBuilderPinned = LayoutBuilder.Pin())
{
DefaultGameModeClassHandle = LayoutBuilderPinned->GetProperty(GameModePropertyName);
}
check(DefaultGameModeClassHandle.IsValid());
well
So you didn't change it
I did
Do this instead.
trying
Ok now the breakpoint is infinite
mmmh
any idea?
There is an error still
Exception thrown at 0x00007FFF51CF880D (UnrealEditor-WindowTest2.dll) in UnrealEditor.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
''
TSharedPtr<IDetailLayoutBuilder> LayoutBuilderPinned = LayoutBuilder.Pin();
check(LayoutBuilderPinned.IsValid());
DefaultGameModeClassHandle = LayoutBuilderPinned->GetProperty(GameModePropertyName);
In here it says
150
But in here
CustomizeGameModeDefaultClass(Group, GET_MEMBER_NAME_CHECKED(AGameModeBase, HUDClass));
CustomizeGameModeDefaultClass(Group, GET_MEMBER_NAME_CHECKED(AGameModeBase, PlayerControllerClass));
CustomizeGameModeDefaultClass(Group, GET_MEMBER_NAME_CHECKED(AGameModeBase, GameStateClass));
CustomizeGameModeDefaultClass(Group, GET_MEMBER_NAME_CHECKED(AGameModeBase, PlayerStateClass));
CustomizeGameModeDefaultClass(Group, GET_MEMBER_NAME_CHECKED(AGameModeBase, SpectatorClass));
}```
Takes 2 classes idk should not be that hard
/** Add special customization for the GameMode setting */
void CustomizeGameModeSetting(IDetailLayoutBuilder& LayoutBuilder, IDetailCategoryBuilder& CategoryBuilder)
{
Wow
In here it takes a IDetaulLayoutBuilder
/** Add special customization for the GameMode setting */
void CustomizeGameModeSetting(IDetailLayoutBuilder& LayoutBuilder, IDetailCategoryBuilder& CategoryBuilder)
{ ```
As paramter
I need one of those full of information and I might be able then
well I think i might be able to get it now that I understand the movements of data going on.... that layout builder is weird
It's probably python scripting.
It's probably not available outside of your CustomizeGameModeSetting method...
And you're trying to save it and use it to spawn a tab later.
Not gonna work.
Hm... not sure how I feel about python in UE especially because of verse. I have not a lot of experience but things get muddy
python is pretty well integrated, I feel. It has access to all the same things that BP does.
But also slate, apparently.
It has access to all the same things that BP does that's what I don't understand, why do they add python if you can do all the stuff with BPs? π
btw, are you a Tools Programmer? saw that you suggested as a career choice
python doesn't need to be compiled.
And it can be done via text.
I am.
You get to avoid all those nasty multiplayer issues π
Getting deprecation warning on this, what's the replacement?
AllottedGeometry.ToPaintGeometry(Offset, ImageBrush->ImageSize)
It seems to say use an FSlateLayoutTransform instead, but with that I don't see anything taking an offset/transform, only a float scale; of the ones not taking that, they seem to take some other deprecated thing:
FDeprecateVector2DParameter
release notes just say "Some legacy FGeometry::ToPaintGeometry and MakeChild overloads have been explicitly deprecated since they cause ambiguous overloads with FSlateLayoutTransform if it were to support implicit construction."
Basically UE::Slate::FDeprecateVector2DParameter means use FVector2f
if I had an offset and an image size before, how do I carry that over (scale is different than the size right, since it is scalar vs ImageSize a vector)? I'm assuming offset could go directly into the translation
FPaintGeometry ToPaintGeometry(const UE::Slate::FDeprecateVector2DParameter& InLocalSize, const FSlateLayoutTransform& InLayoutTransform) const
Your parameter order is flipped.
Which, to be fair, is probably the reason they did it.
ah, it's from ShooterGame SShooterDemoHUD
but, it looks like there is some other overload:
I changed it to this as hopefully the right thing:
Seems to be.
So you are saying it is basically useless to use that? mmmh ok but I will keep trying just for fun, It : P
It seems to be that this part of .SelectedClass(this, &FWindowTest2Module::GetCurrentClass)
Returns null and it cannot
Then I have to get a class reference which is not null but how ?
I try to reference this one which is
#include "CHLPluginGameModeBase.h"// idk why it is not detected
But the plugin does not detect it idk how to expose it
Another thing is How do you reference a specific blueprint from Cplus plus and say what is the best way ? and list all the blueprints of that kind.... which is what the SClassPropertyEntryBox class does
By the way guys BTW BTW how do you make that typical blueprint reference assigner ? is that easy ?
Like this but with blueprints?
Should be easy using SObjectPropertyEntryBox and setting .AllowedClass(...) not sure what class it would be but you can always use the WidgetReflector to look at things you want to implement yourself
Then you need to update it each tick.
That's why you need to update it on tick.
Not to the final value, but smoothly.
Also this seems like a #umg problem?!
To use a little slate code, I would do something like:
const float DesiredAngle = GetDesiredAngle();
const float CurrentAngle = GetCurrentAngle();
const float Difference = DesiredAngle - CurrentAngle;
const float Delta = Speed * DeltaTime;
if (Delta > FMath::Abs(Difference)) { SetAngle(DesiredAngle); }
else { SetAngle(CurrentAngle + FMath::Sign(Difference) * Delta); }```
Hello, I'm wondering how I can change the underlying slate widget of a UserWidget and keep the existing functionality.
What I want is to have a custom SObjectWidget with OnDrag/OnDrop etc events changed, without changing anything else.
In my current UUserWidget I have things like borders, overlays, text etc, and I would like to keep them there, but have some custom DnD functionality on Slate level.
I have been investigating some UUserWidget class code, and apparently the default UMG-Slate widget (the SObjectWidget) is created in UWidget::TakeWidget(), which is not virtual, and in the comment it says to look into UWidget::RebuildWidget, but I can't figure out how I use my custom slate widget and still keep the UMG widgets I have in my widget right now.
Does anyone know how to do so?
If you change RebuildWidget and then update something in your umg widgets, it should regenerate the slate widget.
So what should I do?
Change rebuild widget to be like you want.
Uh, the thing is that I don't know how I would make it do what I've described above π
If you want to start a drag and drop operation, you generally want to return FReply::Handled().DetectDragDrop(EKeys::LeftMouse); Edit: From OnMouseDown or OnMouseUp
Then in OnDragDetected, you start the drag and drop operation.
The easy way to do this is to subclass the actaul widget you're using and then override the methods.
Yeah, I know that, the thing is that I want to change how drag and drop works. I want it to not drop when the mouse is released, and to do so I need to override FDragDropOperation, but the SObjectWidget DnD events expect me to use FUMGDragDropOp, which is not exposed to other modules, hence I want to change what actually expects the FUMGDragDropOp. That's why I need to change the underlying Slate widget
That's a typical example of UMG DnD event:
void SObjectWidget::OnDragEnter(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
TSharedPtr<FUMGDragDropOp> NativeOp = DragDropEvent.GetOperationAs<FUMGDragDropOp>();
if ( NativeOp.IsValid() )
{
if ( CanRouteEvent() )
{
WidgetObject->NativeOnDragEnter( MyGeometry, DragDropEvent, NativeOp->GetOperation() );
}
}
}
They only make the FUMGDragDropOp to pass through to the widgets UMG DnD events, but I want to do it with my own FDragDropOperation instead
The only restriction there is using UDragDropOperation
(the last parameter)
Everything else is slate standard
Override SObjectWidget and use your subclass somehow?
Oh, I actually forgot to say that I need to override FDragDropOperation::AffectedByPointerEvent(), that's why I need a custom one
You can use your own FDragDropEvent.
I did override SObjectWidget, but I don't know how to actually use it in RebuildWidget.
Doing this:
TSharedRef<SWidget> UMyWidget::RebuildWidget()
{
return SNew(SCustomObjectWidget);
}
doesn't display anything
Yes, I can do so, but UMG DnD events would not be fired if I keep the SObjectWidget DnD implementation the same, but I do want the UWidget::OnDrop, OnDragEnter etc events to be fired
You may need to completely redo everything from the parent RebuildWidget, but just change the class.
What do you mean? What class?
My UMG widget is derived from UUserWidget
Yeah, I've been trying to do different things, but I couldn't make it work. Everytime the widget is empty, I mean visually
Right. You still need to add content to it, like a regular widget.
But, as I said, I don't know how exactly I would it. If I return SNew(SCustomObjectWidget) it would be empty, and all the UMG widgets, such as UBorder, UText etc, I have in the UMG widget that's changing inner SObjectWidget would not be shown
I'm pretty new to Slate, hence I'm kind of blind
All right, I've found out how I can make it.
I needed to make my SCustomObjectWidget act kind of SBox.
SCustomObjectWidget.h
class SCustomObjectWidget
: public SObjectWidget
{
public:
SLATE_BEGIN_ARGS(SCustomObjectWidget)
: _Content()
{
}
/** Widget contents. */
SLATE_DEFAULT_SLOT(FArguments, Content)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
{
ChildSlot
[
InArgs._Content.Widget
];
}
/** All DnD functions implementation... */
};
CustomUserWidget.cpp
TSharedRef<SWidget> UCustomUserWidget::RebuildWidget()
{
TSharedRef<SWidget> Inner = Super::RebuildWidget();
TSharedPtr<SWidget> UserRootWidget = SNew(SCustomObjectWidget)
[
Inner
];
return UserRootWidget;
}
Hello is there any documentation on how to use this, thanks.
Ahhhh ok well that was easy compared to the SClassPropertyEntryBox that was a hell.....
Wellll.... it is not showing me any class what so ever......
Any idea?
+ SHorizontalBox::Slot()
[
SNew(SObjectPropertyEntryBox)
.AllowedClass(AGameModeBase::StaticClass())
] ```
And so far It does not even find me blueprints
Hm... I had .AllowedClass(UStaticMesh::StaticClass()) which works just fine
but I tried .AllowedClass(AGameModeBase::StaticClass()) right now and it isn't showing up for me either. not sure what it could be
Took a little longer than I hoped but this should give you something visible
SNew(SClassPropertyEntryBox)
.MetaClass(AGameModeBase::StaticClass())
.SelectedClass(AGameModeBase::StaticClass())
.OnSetClass_Lambda([this](const UClass* SelectedClass) { })
I don't quite understand why it has to be a ClassProperty instead of a ObjectProperty though. Would be nice if anoyne could give a short explenation
AGameMode is a class.
Not an instance of that class.
ObjectPicker would let you pick an actor in a level or something
Hm... so UStaticMesh::StaticClass() displays all the meshes because they are instances in the content browser?
Yes.
Cannot load a different class
I click nothing happens
Also how do you know which class is loaded after all ? like I took tetrisGameInfo selected, then how do I get that, that was selected ?
I like to help but we are getting into hand-holding territory π
Looking at your other questions you seem like someone who is able to do it and considering that you are brave enough to look at slate proves it.
You can look at points where it is used by epic themselves. Just use
Then you can look for example inside of SmartObjectAssetToolkit.cpp - which is pretty neat to learn from if you want to make a custom editor -
It'll be on the widget. ->GetClass or something.
Ok thanks π