Interface Function is not called from C++

Hello,

I have the problem that an Function of an Interface which both is implemented in Blueprint is not called when calling the Interface Function from c++ Code. Both Blueprint call and c++ call using the same function of an BlueprintFunctionLibrary which is looking like this:


 void UCallGlobalEvents::Call_Event1(struct Struct1 Meta, struct Struct2 InData)
  {
  TArray<AActor*> Actors;
  UGameplayStatics::GetAllActorsWithInterface(GWorld, UGlobalEvents::StaticClass(), Actors);
  for (AActor* Actor : Actors)
  {
  if (Actor->GetClass()->ImplementsInterface(UGlobalEvents::StaticClass())) {
  IGlobalEvents::Execute_Event1(Actor, Meta, InData);
  }
  }
  }
 


The crazy thing is the Pointer “Actor” is exactly the same if i call Call_Event1 from Blueprints and from c++, also both will execute the line “IGlobalEvents::Execute_Event1(Actor, Meta, InData);” but the interface call is only received when executing Call_Event1 from a blueprint but not if i execute Call_Event1 in c++.

What am I missing ?

Assuming your interface has “Execute_Event1” in it; you need to cast the Actor to your interface and then call the Actor’s Interface method:



void UCallGlobalEvents::Call_Event1(struct Struct1 Meta, struct Struct2 InData)
{
  TArray<AActor*> Actors;
  UGameplayStatics::GetAllActorsWithInterface(GWorld, UGlobalEvents::StaticClass(), Actors);
  for (AActor* Actor : Actors)
  {
     UGlobalEvents* CastedActor = CastChecked<UGlobalEvents>(Actor); // GetAllActorsWithInterface already did the ImplementsInterface check for us.
     CastedActor->Execute_Event1(Actor, Meta, InData);
  }
}


Thanks for the response. If I Try to compile this its failing:

if i change UGlobalEvents to IGlobalEvents its compiling but crashing on execution.

But anyhow i did a cross check and implemented the following code in a blank C++ actor and that is working fine:


 
TArray<AActor*> Actors;
  UGameplayStatics::GetAllActorsWithInterface(GWorld, UGlobalEvents::StaticClass(), Actors);
  for (AActor* Actor : Actors)

  {
  if (Actor->GetClass()->ImplementsInterface(UGlobalEvents::StaticClass())) {
  IGlobalEvents::Execute_Event1(Actor, Meta, InData);

  }
  }

So my Problem must be something else. Is a Class in a Gameinstance behaving any different in that regard ? because that’s where the call comes from.

Can you post your interface header?



UINTERFACE(BlueprintType, Category = "GlobalEvents",  meta = (DisplayName = "GlobalEvents"))
class UGlobalEvents : public UInterface
{
    GENERATED_BODY()
};


class AVE_APPLICATION_API IAVEGlobalEvents
{
    GENERATED_BODY()

public:

    UFUNCTION(BlueprintNativeEvent, Category = "GlobalEventSystem")
        void Event1(struct FMeta Meta, struct FData Data);


};


It’s a BlueprintNativeEvent and you’re using GENERATED_BODY, so you need to define the _Implementation for the function as well in the Interface, even if it’s just blank. E.g.:



UFUNCTION(BlueprintNativeEvent, Category = "GlobalEventSystem")
void Event1(struct FMeta Meta, struct FData Data);
virtual void Event1_Implementation(struct FMeta Meta, struct FData Data) {}


Classes which inherit the interface then need to override the _Implementation variant.

I tried it also with an BlueprintImplementable and and BlueprintNativEvent and an _implementation. But both dont work, also note my comment above:

So also calling it from the Class as a Function is working. Any idea if if a dynamic Delegate which is calling the Interface can cause problem ?

So Function “X” which is trigger via a Dynamic Delegate, is calling the Interface. And it is successful once at the first time the Function “x” is called. After That, the c++ Code is executed but the Interface Function is never called again.

You need the _Implementation code either way - and BlueprintImplementableEvent can’t have C++ code in the function body.

Show how your binding / broadcasting the delegate

I copied the relavant path and made some … where its not necessary to post a lot of unrelated code. OnDataReceived() is the function where the Interface call is executed (see first post)


httpQueueHandler->OnEvent.AddDynamic(this, &ThisClass::OnDataReceived);



DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FHttpCommandEventDelegate,....);
...
    UPROPERTY(BlueprintAssignable, Category = "HTTP")
    FHttpCommandEventDelegate OnEvent;



OnEvent.Broadcast(....);

I think I see the problem.



UGlobalEvents* CastedActor = CastChecked<UGlobalEvents>(Actor)


I’m farirly sure this will only pass if you use IGlobalEvents as the type and if the interface was implemented natively (not in Blueprint)



TArray<AActor*> Actors;
UGameplayStatics::GetAllActorsWithInterface(GWorld, UGlobalEvents::StaticClass(), Actors);
for (AActor* Actor : Actors)
{
    IGlobalEvents::Execute_OnDataReceived(Actor, Meta, InData);
}


Combine the above with the _Implementation stuff I mentioned earlier and you should be fine.



UFUNCTION(BlueprintNativeEvent, Category = "GlobalEventSystem")
void OnDataReceived(FMeta Meta, FData Data);
virtual void OnDataReceived_Implementation(FMeta Meta, FData Data) {}


@TheJamsh Thanks, but thats not the problem, as i tested i can successfully call the interface for example in the tick function or somewhere else.

So what i found out, if i call it with an timer in the OnDataReceived() function it works fine:



    FTimerDelegate TimerDel;
    TimerDel.BindUObject(this, &UCallGlobalEvents::Call_Event1);
    GetWorld()->GetTimerManager().SetTimerForNextTick(TimerDel);
 

I dont understand whats going wrong here when calling it without a timer, especially since calling it via


AsyncTask(ENamedThreads::GameThread, =]() {}

is also not working.