added little snippet from one of my products how to do it in c++ as well.
// Setup
void UDigitalClockWidget::NativeOnInitialized() {
Super::NativeOnInitialized();
// .... snippet of relevant code
// TimeSubsystem here would be your actor component to sync to instead.
// The function you bind to here would need the same signature (function parameters) as what the actor component broadcasts with.
TimeSubsystem->OnSecondChanged.AddDynamic(this, &UDigitalClockWidget::ActOnSecondChanged);
// Synchronize immediately.
ActOnSecondChanged();
}
You could say it makes most sense to have an actor component open up the widget, because if that actor component is not present, that widget should not be created in the first place (no data available for it). There doesn’t seem to be a point in decoupling that.
Otherwise you need some kind of identifier on the actor component.
Each player gets their own HUD and widgets, each player has their own playercontroller controlling a pawn. So you could have a widget scan (or store) relevant pawns on a level, check if their playercontroller matches the controller of the widget, then scan its components for a certain ID (component of class, or component with tag etc.) and move from there. Seems like the hard way to me.
I’d do something like ( pseudocode snippet ) :
UMyActorComponent::DoStuff() {
MyWidget = WidgetSystem::CreateWidget(MyWidgetClass);
MyWidget->InitializeForComponent(HealthActorComponent);
}
Then MyWidget continues to proceed setting up delegate bindings like the C++ snippet I posted earlier. Optimally you also create your widgets from one place so they remain managable. Like from a HUD or UMG based HUD.