I have a laptop (actor) that has a 3D Widget component. When I’m setting up the widget (making it so you can press buttons) I can’t seem to find a way to cast back to the laptop and send it information from the widget. What do I plug into the Cast To’s ‘object’ (in the widget graph) in order to send information back to the laptop its self?
You can create a Blueprint variable on your Widget class. Make its type a reference to your Laptop Actor. Then, when your Laptop Actor creates the Widget, have it set itself as the as the value of the variable on the Widget. That way, whenever your Widget needs to access the Laptop it belongs to, it can get it from the variable.
Ah, that makes sense, though I’m having some trouble with it. I’m using a 3D Widget, so it isn’t created by the Laptop, it already exists.
I’ve added a var in the widget that is a Laptop type reference, and I’m trying to cast to it from the laptop (In order to set ‘self’ as the owner). Cast To Widget can’t find the new var, while Cast To LaptopScreen (the widget type) with the widget component as the ‘object’ gives the error “Does not inherit from ‘Widget Component.’” What should I Cast To? I’ll be the first to admit that Casting is still a bit confusing for me.
Ok, I think I might have it. I had to do some goofy ■■■■ I could have only found through trial and error, but I’m not getting any errors right now. Still testing to see if it sends. (PCDHD is a ref to the 3D Widget in the Laptop actor)
I think it should work without any problem, as long as you don’t change the widget on the fly by using UWidgetComponent::SetWidget
When you specify a widget in the Widget Component’s property, it only stores the widget’s generated class, the actual widget instance will be created in UWidgetComponent::OnRegister, which will already be called at any point of your laptop’s blueprint.
But it would be more readable and less error prone (at least for me), to not specify any widget in the widget component, and have the laptop actor create it in BeginPlay event and then manually set it as the UWidgetComponent’s widget. (EventBeginPlay->CreateWidget → Cast The resulting widget to LaptopScreen → call specific function or set some properties in the widget → and then set it as the Widget Component’s widget), that way all the references are guaranteed to be valid before the widget’s internal slate widget is created and added to the UWidgetComponent’s renderer. (to make it short, you already have a valid laptop reference even in the Widget’s Construct event which are called after UUserWidget::TakeWidget)
But, it’s just me, and I think he (cancel) also said the same thing:
when your Laptop Actor creates the Widget
UWidgetComponent is still experimental, the document said that the input handling is still not perfect (please correct me if i’m wrong, i think i’ve read it somewhere in the document).
And I see that you’re using 4.9, if the problem is with the mouse input, there’s a bug in UMG’s widgetcomponent where the mouse cursor location are transform incorrectly to the widget. You can fix this by setting UWidgetComponent::bUseLegacyRotation to true (the default is false). I don’t know if this bug has been fixed or not in the later version (4.11) or not
Might that be why the widget isn’t reacting to clicks? I can’t get buttons to work on it at all, and some elements don’t even appear.
I’m seeing a lot of questions talking about them being broken, so that is probably the case here.
Thanks for the help though. I’m now creating the widget at run-time as suggested, just to be safe. Sadly, I’m only fluent in Blueprint, so I can’t try the Legacy Rotation at this time
I used to have the same problem you asked. Now I think the best solution is using Event Dispatchers, but not make reference on each other, because this way is error prone and may easily crash your engine. (circular reference can’t be garbage collected, thus may make memory leak).
Solution: Add an Event Dispatcher in the widget, call the dispatcher when button pressed, in the Laptop actor get and cast to the widget, then bind your after button pressed event to the widget Event Dispatcher.