Download

Passing an IInterface as a parameter to an RPC function

Hi guys,

I have a function set up to play animations. One of the functions is an interface of IUsableAnimCallback - it’s just a simple interface I use that lets me pass in various types that all play animations. It looks like this:



UINTERFACE()
class UUsableAnimCallback : public UInterface
{
 GENERATED_BODY()
};

class IUsableAnimCallback
{
 GENERATED_BODY()

public:
 virtual void OnAnimUseSectionHit() = 0;
 virtual void OnAnimEnded() = 0;
};


The interface itself is adapted from what I had before, which was a pure virtual c++ class that didn’t inherit anything. I changed it to an interface so that I could pass it via RPC calls.

The signature of the function looks like this:


 void PlayAnimation(ARoguelikeCharacter* character, UAnimMontage* animName, float speed, IUsableAnimCallback* caller = NULL);


This then has a few other functions, one with the necessary server macro, and then one with a multicast macro. They are called accordingly based on the authority of the caller in question.

When I try to compile this, I get the following error:

This happens for the validate and implementation functions for the server/multicast functions, but not any of the others.

If I change the type from the interface to TScriptInterface… I still get similar errors.

What am I missing? Is there a specific certain signature that needs to be satisfied to compile the server/multicast functions?

I’m fairly certain you can’t pass native interfaces through RPC’s as they’re not a reflected type, personally I’ve never tried with a TScriptInterface.

What I would do personally, is pass a UObject through the RPC instead - then cast it to the interface on the other end (or if the interface is implemented in Blueprint, check if the class implements the script inteface). To me at least, this seems a little safer and isn’t too difficult. It also means the functions can be exposed to Blueprint if you like.



UFUNCTION(Server, Reliable, WithValidation)
void Server_DoSomething(UObject* Context);
virtual void Server_DoSomething_Implementation(UObject* Context);
virtual bool Server_DoSomething_Validate(UObject* Context) { return true; }   // Could also cast here - if it fails, return false and kick the client




void AMyThing::Server_DoSomething_Implementation(UObject* Context)
{
    IMyInterface* AsIFace = Cast<IMyInterface>(Context);
    if (AsIFace)
    {
        // Do thing
    }
}


While not fully ideal casting did work a treat. Thanks for the tip!