Here is the background. I create the interface in C++ and they are accessible from Blueprint (I can add Interface from the list within the Editor to my vehicle blueprint class - lets name it VehicleBP).
And in the base C++ of the vehicle class (I name it here as VehicleBase), I added the check if the interface is added (some vehicle blueprint doesnot add any interface). The simple check which is done within VehicleBase always fail:-
auto InterfaceVar = InterfaceCast<Type>(this);
if (InterfaceVar) {
InterfaceVar->Startup(); // this is the very core of my problem - I want to call this function directly (it is just a simple C++ function).
}
So I tried this instead:-
if (GetClass()->ImplementsInterface(UPawnInterface::StaticClass())) { // UPawnInterface is the interface class
IPawnInterface::Execute_Startup(this);
}
It gets thru the if block, but the Startup_Implementation was never called. Of course, I have changed the signature of the Startup function to this:-
I wish I can call the function directly in the interface, as if I call another C++ function. The second code is the workaround (as long as I can get the function call).
UFUNCTION(Category = "My Interface", BlueprintNativeEvent, BlueprintCallable, meta = (DisplayName = "On My Interface Call"))
void OnInitialized(const AMyActor* Context);
void AMyActor::OnInitialized_Implementation(const AMyActor* Context) {
if (Context != this) {return;}
TArray<AActor*> Interfaces;
// Pick only Actors with Interface, instead of iterating whole World:
UGameplayStatics::GetAllActorsWithInterface(this,UMyInterface::StaticClass(),Interfaces);
for (const auto &Actor : Interfaces) {
// Try to Execute on C++ layer:
const auto &Interface = Cast<IMyInterface>(Actor);
if (Interface) {**Interface->Execute_OnInitialized**(Actor,Context);} else
// Else, Execute Interface on Blueprint layer instead:
if (Actor->GetClass()->ImplementsInterface(UMyInterface::StaticClass())) {
IMyInterface::Execute_OnInitialized(Actor,Context);
}
}
}
void AMyActor::BeginPlay() {
Super::BeginPlay();
// Fire off the Native Event, which is going to be received by all the other Actors:
Execute_OnInitialized(this,this);
}
In that example “On Initialized” is at the same time both a sender and an event receiver when used on the Blueprint Graph. Anyone implementing the interface will receive a ‘context’ of where the interface call came from and everyone can call OnInitialied() on itself to message all the others, from the same function.
Hi,
Thanks for the reply. The code is not that much different, except it is calling GetAllActorsWithInterface and then iterate (vs me using explicit ‘this’ pointer).
But I am still not receiving the break in the _Implementation function. All others seem normal ie the ‘Execute_FuncXXX’ is call (but FuncXXX_Implementation was never invoked).
Make sure you call the native super of your NativeEvent from the Blueprint graph if you are overriding it on the Blueprint; otherwise your Blueprint will not call the C++ version of that event.
You have to right click the Event’s node and add a ‘Call to Parent Function’, named something like that, then an orange node is created…
I am not overriding at all using Blueprint (maybe so in future), but for now everything is done in C++. The only thing done in Editor is choosing which interface to use (from class settings) and those interfaces are all done using C++.
I think my requirement is quite different from others as I do not involve Editor (and overrride bp event or call function within bp). But somehow I think it should be doable.
However, I get this solved by not using Interface but using ActorComponent and use DECLARE_DYNAMIC_MULTICAST_DELEGATE_XXX and then broadcast so that parent will capture this event, and act appropriately. This is as elegant as Interface (it I can get it work lol).