In the most simplest of terms communication requires a reference to the other actor/component (class). To really grasp communication between classes you need to understand class inheritance. Every class derives from a Parent class. Most commonly an Actor (Actor Object Reference).
Take for example the First and Third Person Template Characters. If you walk the inheritance chain backward you would end up at an Actor.
Actor → Pawn → Character → Your Specific Character Class
Hit results (Hit Actor) && Overlaps (Other Actor) are explicitly generic Actor Object References.
If you want to call a Custom Event/Function or get/set custom variables you’ll have to cast to the specific class.
Blueprint Interfaces (BPI) is a lighter weight bridge for function based communication that does not require casting. You just need to create specific functions in the BPI. Then implement them in the specific class.
Note, ONLY the class using the BPI functions (pic 2 & 3 below) needs to implement the interface in class settings.
Classes calling the BPI messages Do Not need to implement the BPI.
Then there’s Event Dispatchers which require class specific references (casted or get all actors of class) and Binding a delegate. This is mainly used for Many to One or One to Many communication.
A “One to Many” example would a be light switch that controls many lights.
In the above code EACH light Actor would get a reference to the Light Switch class and Bind Events to its Dispatchers.
Interacting with the Light Switch would execute the Toggle on/off events which calls the appropriate Event Dispatcher. This is essence broadcasts Turn Lights Off/On and any class that’s has a binding for those events will execute local logic.
A more practical approach would be having the ability to designate specific lights to specific switches.
Add an Actor Tag to the Light Switch instance, then use that tag in a Get All Actors of class with Tag node.
Here are DOC references to review.