Interface RPC?

Hey guys, I can’t figure this out for a few days now:

I am trying to create an “Interaction” interface that is using RPCs. Browsing the forums and the Answer Hub, I think it should be possible, but I haven’t found an actual working example.

I have created an interface called “I_Interaction” with a “StartInteraction()” and a “StopInteraction()” function:

“I_Interaction.h”


 #pragma once
 
 #include "I_Interaction.generated.h"
 
 UINTERFACE()
 class MYGAME_API UI_Interaction : public UInterface
 {
     GENERATED_UINTERFACE_BODY()
 };
 
 class MYGAME_API II_Interaction
 {
     GENERATED_IINTERFACE_BODY()
 
     //Interface Functions
 
     UFUNCTION(Server, Reliable, WithValidation)
     virtual void StartInteraction();
 
     UFUNCTION(Server, Reliable, WithValidation)
     virtual void StopInteraction();
 };

“I_Interaction.cpp”


 #include "MYGAME.h"
 #include "I_Interaction.h"
 
 //Constructor
 UI_Interaction::UI_Interaction(const class FObjectInitializer& ObjectInitializer) :Super(ObjectInitializer)
 {
 
 }

I am implementing the interface in an AActor derived class called “EQ_Overlord”

“EQ_Overlord.h”


 #pragma once
 
 #include "Interface/I_Interaction.h"
 #include "Entity/Entity_Overlord.h"
 #include "EQ_Overlord.generated.h"
 
 UCLASS(abstract)
 class MYGAME_API AEQ_Overlord : public AEntity_Overlord, public II_Interaction
 {
     GENERATED_BODY()
 
     //Declaring Constructor
     public: AEQ_Overlord();
 
 protected:
 
     virtual void StartInteraction_Implementation() override;
 
     virtual void StopInteraction_Implementation() override;
 };

“EQ_Overlord.cpp”


 #include "MYGAME.h"
 #include "EQ_Overlord.h"
 
 //Constructor
 AEQ_Overlord::AEQ_Overlord() :Super()
 {
 
 }
 
 //Interface Functions
 
 bool AEQ_Overlord::StartInteraction_Validate()
 {
     return true;
 }
 
 void AEQ_Overlord::StartInteraction_Implementation()
 {
 
 }
 
 
 bool AEQ_Overlord::StopInteraction_Validate()
 {
     return true;
 }
 
 void AEQ_Overlord::StopInteraction_Implementation()
 {
 
 }

I cannot compile this, I get the following errors:


  error C2509: 'StartInteraction_Validate': member function not declared in 'AEQ_Overlord'
 
 error C2509: 'StopInteraction_Validate': member function not declared in 'AEQ_Overlord'

Now what confuses me is that as far as I know, both an RPC and an Interface function should use an “_Implementation” suffix. How do I get around this? I have tried many other options, but I couldn’t even get it to compile.

Is even calling RPCs through an interface possible if the implementing class has the right ownership? If so, how? I hope someone can shine some light on this for me.

Thanks!

I haven’t done this before but, as a guess, have you tried dropping the “_Implementation( )” from the overrides in the AEQ_Overlord class?

Such as:



  #pragma once
 
 #include "Interface/I_Interaction.h"
 #include "Entity/Entity_Overlord.h"
 #include "EQ_Overlord.generated.h"
 
 UCLASS()
 class MYGAME_API AEQ_Overlord : public AEntity_Overlord, public II_Interaction
 {
     GENERATED_BODY()
 
public: 
     AEQ_Overlord();
 
 protected:
 
     virtual void StartInteraction() override; 
     virtual void StopInteraction() override;
 };
 



 #include "MYGAME.h"
 #include "EQ_Overlord.h"
 
 //Constructor
 AEQ_Overlord::AEQ_Overlord() :Super()
 { 
 }
 
 //Interface Functions 
 bool AEQ_Overlord::StartInteraction_Validate()
 {
     return true;
 }
 
 void AEQ_Overlord::StartInteraction_Implementation()
 { 
 } 
 
 bool AEQ_Overlord::StopInteraction_Validate()
 {
     return true;
 }
 
 void AEQ_Overlord::StopInteraction_Implementation()
 { 
 }
 

Hi,

Thanks for your answer! I have tried what you suggested, but unfortunately it didn’t solve the issue.

Now the “StartInteraction_Implementation” and “StopInteraction_Implementation” functions are listed in the error log as well as not being members. Another thing I noticed only now, is that it complains about not overriding any base class methods in “AEQ_Overlord”, which I find weird.

Here is the error output:

error C3668: ‘AEQ_Overlord::StartInteraction’: method with override specifier ‘override’ did not override any base class methods
error C3668: ‘AEQ_Overlord::StopInteraction’: method with override specifier ‘override’ did not override any base class methods
error C3668: ‘AEQ_Overlord::StartInteraction’: method with override specifier ‘override’ did not override any base class methods
error C3668: ‘AEQ_Overlord::StopInteraction’: method with override specifier ‘override’ did not override any base class methods
error C2039: ‘StartInteraction_Validate’: is not a member of ‘AEQ_Overlord’
note: see declaration of ‘AEQ_Overlord’
error C2039: ‘StartInteraction_Implementation’: is not a member of ‘AEQ_Overlord’
note: see declaration of ‘AEQ_Overlord’
error C2039: ‘StopInteraction_Validate’: is not a member of ‘AEQ_Overlord’
note: see declaration of ‘AEQ_Overlord’
error C2039: ‘StopInteraction_Implementation’: is not a member of ‘AEQ_Overlord’
note: see declaration of ‘AEQ_Overlord’

Any ideas what is going on?

Thanks

Last time I checked, you couldn’t have Server / Client functions as part of an interface.

That might have changed though. If so, try this:

Header



 class MYGAME_API II_Interaction
 {
     GENERATED_BODY()   // Use GENERATED_BODY()
 
     //Interface Functions
 
     UFUNCTION(Server, Reliable, WithValidation)
     void StartInteraction();
     virtual void StartInteraction_Implementation() {}
     virtual bool StartInteraction_Validate() { return true; }
 
     UFUNCTION(Server, Reliable, WithValidation)
     void StopInteraction();
     virtual void StopInteraction_Implementation() {}
     virtual bool StopInteraction_Validate() { return true; }
 };


Then try overriding _Implementation and _Validate in your otherclass.

If this doesn’t work, my suggestion would be to add Interaction functionality via an ActorComponent instead.

My guess was a shot in the dark; bummer it didn’t work out.

If I find some time, I will try and figure out a solution and respond here.

Thanks guys for the input!

Unfortunately none of the solutions compiled. I believe that the fact that both an interface and an RPC function should use an _Implementation suffix confuses the compiler somehow, when a function is both an interface and an RPC, but of course I could be wrong.

For now, I will try to run the “Interaction” key press handling event on the server (in the PC), and then call a normal interface function on “EQ_Overlord”. In my understanding, I should get the same results, the interface function is running on the server, called by a client, and this solution might be even more convenient from a design perspective.

Thanks again!