Is it casting? Interfaces? References? Does it depend mostly on situation or is there the best solution? They all seem similar.
First of all i hope you understand that blueprints are classes from which you create objects and what you really communicating with is not blueprints but objects made form Blueprints… or C++, because Blueprint classes are same as C++ classes are both the same in editor envriament.
“Reference” is a object variable, regardless if it’s outputted form pin ot it’s variable it’s all the same and ultimately it is only way to communicate between objects, by using node, you calling function in object and you need to point witch object you calling by pointing a reference in to “Target” pin. Refrence has specific class type set and that refrence can only contain specific class of object, for example “Pawn” and by that refrence can only contain Pawns, because it can contain object of different classes then your blueprint, you can only call function that are in class" Pawn and parent classes behind it (in case of “Pawn”, it is “Actor” and behind it is “Object”), in order to call function from your blueprint you need to cast refrence to your blueprint class
Interface practicly has nothing to do with communicating if you look at it, it’s a thing that relates 2 unrealated classes, for example you got Pawn called “Cat” and Character “Human”, let say both can attack and you do that via “Attack” function you made. In normal case you would create base class from “Pawn” (lets call it “Creature”) and there place function “Attack”, which can be overrides in child classes like “Cat” or “Human”, now when you make “Creature” refrence you can contain “cat” or “human” in it and call “Attack” and it will react as they been coded to do. But when you want “Human” to be made from “Character” class to use it’s movement goodness it create problem because you can’t move “Character” class to “Creature” class to have common “Attack” function and "Cat and “Human” don’t have any relation to eachother so you can’t call same “Attack” function that they both contain using same node. Thats what Interface is to solve, you can make interface with “Attack” function and use it in as much classes you like and then all those classes that implements that interface can be contained in same refrence (set to interface, it has diffrent color not blue) ad you can call attack using same node.
In early days of UE4 (and i think there still lot of people thinking that way) complitly misunderstood what Interface really is, due to fact that with them you can avoid annoying casting (which you can avoid in diffrent ways btw). People been thinking that this is primary way to communicate between objects, where most basic form of communication is by calling function via “refrence”, interface only help in some difficult cases where classes are unrealated. This is also due fact that people didn’t understood that blueprints are classes and they didn’t know about class tree.
Now casting as i said is just changing type of reference, in progress it also check if object you inputing is related to class you trying to cast to, if it’s not it fails. You can avoid casting simply by keeping refrence of object as varable right away after you spawn actor, the “Spawn Actor” (or any other creation node) already do casting for you, so use it
I know my writing is quite hard to understand ^^’ because this was common issue i made video about reality of objects and classes in UE4, so watch it:Also read about "Object-oriented programming" this should give you ton of other sources about this, if you understand what it is and open "Class Viewer" in UE4, it should enlight you. It's a very basic concept that you need to know if you want to do any proper coding in UE4 on both Blueprints or C++ or else you become lost and really you have no idea what you doing.
And yes you right… they not only similar, they all part of same way of communicating, because in UE4 you only have one way really (well there also events dispatches which you can bind function to, events are also functions but they simply looks differently)
I would choose to state that Event Dispatchers are an efficient way to have blueprints communicate.
For the reference it’s back to ownership logic, if you use it and own it make it a variable.
The Interface is as you have suggested, to provide a common programming interface for a set of objects, not directly related to communication, but can be used to communicate.
Casting has no place in this conversation about communication, in my opinion.