Problem is that widgets are not actors (they do not inherit from Actor class).
So you need some master widget or actor they can always find. I use either hud blueprint or game mode (that depends on what my widget is communicating with). If its widget-widget or should be local to one player i use HUD (or player controller/pawn). If its communication with actor in level i use game mode. It can be done both ways for actors and widgets, i just prefer to separate this way.
So make dispatcher in HUD.
Widget that should receive information hooks to that dispatcher
Widget that sends information triggers dispatcher
This way you do not need to worry about finding other widget in whole stack of widgets.
I also did some type of communication system (was really tired of traversing parent of parent of parent of widget up and down) it was made for HUD display.
what i did:
- it was only for displaying information on screen, no input from widgets
- made enumerator that said who should read message
- every widget had that who enum variable and hooked to dispatcher in HUD bp.
- if message from dispatcher had same enum value as widget it read it and used to display
- messages were always sent as TEXT, because really handy FormatText node
- in blueprint interface of widget i implemented function that changed message into whatever widget needed to display be it color, int32, float etc.
Then everything that wanted update on HUD triggered that dispatcher. No more going up and down that silly widget chain. Widgets could be independent from where they placed etc.
However there is single problem with all this, if you use Event Construct in widgets you cannot be guaranted that Game mode exists (or rather is initialised and has proper valus). To battle this (instead famous 0.2 delay) check if pointer to HUD or game mode is valid if so hook to dispatcher, if not do it again on begin play or any other event that happens after construct. This way you see values in editor and then in gmae, without bad reference flood of errors.