Announcement

Collapse
No announcement yet.

Interface Function is not called from C++

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    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:


    Code:
     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 ?

    #2
    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:

    Code:
    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);
      }
    }
    Able Ability System - A high performance, robust ability system for UE4. Now Available!

    Comment


      #3
      Originally posted by ExtraLifeMatt View Post
      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:

      Code:
      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:

      Code:
       
      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.

      Comment


        #4
        Can you post your interface header?
        Able Ability System - A high performance, robust ability system for UE4. Now Available!

        Comment


          #5
          Code:
          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);
          
          
          };

          Comment


            #6
            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.:

            Code:
            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.

            Comment


              #7
              I tried it also with an BlueprintImplementable and and BlueprintNativEvent and an _implementation. But both dont work, also note my comment above:
              But anyhow i did a cross check and implemented the following code in a blank C++ actor and that is working fine:
              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.

              Comment


                #8
                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.
                Last edited by Dominic.BW; 08-16-2019, 05:22 AM.

                Comment


                  #9
                  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

                  Comment


                    #10
                    Originally posted by TheJamsh View Post
                    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)

                    Code:
                    httpQueueHandler->OnEvent.AddDynamic(this, &ThisClass::OnDataReceived);
                    Code:
                    DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FHttpCommandEventDelegate,....);
                    ...
                        UPROPERTY(BlueprintAssignable, Category = "HTTP")
                        FHttpCommandEventDelegate OnEvent;
                    Code:
                    OnEvent.Broadcast(....);

                    Comment


                      #11
                      I think I see the problem.

                      Code:
                      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)

                      Code:
                      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.

                      Code:
                      UFUNCTION(BlueprintNativeEvent, Category = "GlobalEventSystem")
                      void OnDataReceived(FMeta Meta, FData Data);
                      virtual void OnDataReceived_Implementation(FMeta Meta, FData Data) {}
                      Last edited by TheJamsh; 08-16-2019, 09:11 AM.

                      Comment


                        #12
                        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:

                        Code:
                            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
                        Code:
                        AsyncTask(ENamedThreads::GameThread, [=]() {}
                        is also not working.
                        Last edited by Dominic.BW; 08-19-2019, 05:43 AM.

                        Comment


                          #13
                          this was asked to me by the interviewer in TCS. Glad i'm working there now

                          Comment

                          Working...
                          X