Look into dispatchers, and blueprint interfaces. Blueprints are kind of hopeless with between actors communication.
So i always make global dispatcher that is in game mode (or something else easily accessed) that can be called and executed to dispatch “global” events.
Then everything that needs communication with more than one “hoop” to get trough uses that dispatcher.
Dispatcher sends structure that is for eg.: “sender name”, “message name”, “message value”, all as string (or text).
Works really well for UMG (where communication up and down is total mess), done that for damage system (yes unreal has build in, but my code i can easily change). etc.
And then Blueprint Interfaces allow you to call events (or functions) to objects you do not know what class they are.
And last trick (but sometimes it is not worth trouble) is making blueprintable components that have that dispatcher plus blueprintable interface codded in. So you have all communication is small container that you can just drag and drop on actors, or add as component. There is one problem with them though, you need to make more platter code, so they recognize all possible parent classes and know how to act.