There are two widgets - ParentWidget
and ChildWidget
. ChildWidget
is created inside ParentWidget
. Both of that widgets are bound to the UUserWidget
child class. ChildWidget
has bool flag bBoo
with UPROPERTY(EditAnywhere)
specifier, so it can be changed either from the editor UI or from the C++ logic, so far so good.
I make bBoo=true
through the editor UI, and, after some time, I reset it back to false through the C++ logic. To make it clear, bBoo
is always gets the value true from the editor UI and false from the C++ code, and all changes are made in the editor, without starting the game.
Here the strange behavior:
When later I select this widget in editor UI, bBoo=false
(as it should be), but after changing the position of the ChildWidget
- flag bBoo
changes back to true . It seams that the widget blueprint caches fields, and prefers changes from the UI over changes from bound C++ class.
To sum up, all steps looks like this:
- Change
bBoo=true
in the editor - At some point
bBoo=false
in C++ logic - Move
ChildWidget
(bBoo
displays as false as it should be) - After releasing the mouse
bBoo
changes back true by itself (last assigned value from editor)
Here are some conclusion from my attempts:
- Adding Transient specifier only makes it worse, so the
bBoo
field always resets to false after moving theChildWidget
- Adding
ExposeOnSpawn=true
meta doesn’t affect anything InvalidateLayoutAndVolatility()
doesn’t affect anythingNativeConstruct()
doesn’t fire, because all actions are made in the editor, without starting the game.PostEditChangeProperty()
method doesn’t help, because the value set from C++ already has a lower priority than the value from the editor.
Is it possible in C++ code to clear widget’s cache after changing the bBoo
flag, or force it to refresh its cache?
This problem is also relevant for other fields. For example, the position of the ChildWidget
So, ObtainedPosition
returns the last “dragged” position in editor, but not the ExpectedPosition
from the example
Cast<UCanvasPanelSlot>(ChildWidget->Slot)->SetPosition(ExpectedPosition);
// ...
const FVector2D ObtainedPosition = Cast<UCanvasPanelSlot>(ChildWidget->Slot)->GetPosition();