RPC from Interfaces not working?

Hello everyone,

I tried to define a Client RPC via an Interface and implement the interface in a PlayerController. It compiles, but if I try to call the Client RPC of the PlayerController from the server via a TScriptInterface, the target client RPC didn’t gets called.

If I implement the RPC directly in the PlayerController, the RPC is called on the client. So Interfaces or TScriptInterface do not support RPC handling?

Example:

Interface Header

UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UActionPlayer : public UInterface
{
	GENERATED_BODY()
};


/**
 * 
 */
class BOARDGAME_API IActionPlayer
{
	GENERATED_BODY()

public:

	UFUNCTION(BlueprintCallable, Client, Reliable, Category = "GameLogic")
	virtual void ClientActionsAvailable();
	virtual void ClientActionsAvailable_Implementation() = 0;
}

In PlayerController Header:

UCLASS()
class BOARDGAME_API AGamePlayerController : public APlayerController, public IActionPlayer, 
{
	GENERATED_BODY()
	
public:
	virtual void ClientActionsAvailable_Implementation() override;

UFUNCTION(Client, Reliable, BlueprintCallable)
	void ClientForwardThings();

}

In PlayerController Source:

void AGamePlayerController::ClientActionsAvailable_Implementation()
{
	UE_LOG(LogTemp, Log, TEXT(" ============== ClientActionAvailable Called =============="));
}

void AGamePlayerController::ClientForwardThings_Implementation()
{
	UE_LOG(LogTemp, Log, TEXT(" ============== ClientForwardThings Called =============="));
}

Called from the GameMode in PostLogin:

void AMyGameModeBase::PostLogin(APlayerController* NewPlayer)
{
	Super::PostLogin(NewPlayer);
    
	TScriptInterface<IActionPlayer> ActionPlayer(NewPlayer);
	if (ActionPlayer != nullptr)
	{
		// not working
	    	ActionPlayer->Execute_ClientActionsAvailable(NewPlayer);
	
		// working
		Cast<AGamePlayerController>(NewPlayer)->ClientForwardThings();
       	}
}

RPCs has to be called by an Actor and a Client RPC needs to know who is the owner of that Actor in order to call it on the correct Client. If you make a regular function in the interface and have the GameMode call that on the PlayerController then the PlayerController should have another RPC Client function that it forwards the call to(The actual RPC). That would be called on the individual Clients PlayerControllers. I know that it kind of spoils the idea of an Interface but I don’t think there is any way around it.

2 Likes