I’m trying to execute a function on the server to fill in some blackboard values and cannot get it to execute. The general setup is that the player has a pawn which issues orders to other AI controlled characters. The relevant code is:
Some things which make this different from other questions I’ve seen:
I have set the owner on the Actor, on the server, and when I unset it I get a log saying that the RPC is rejected: “No owning connection for actor TopDownCharacter_C_0. Function Server_MoveToLocation will not be processed.”
When the owner of the Actor is set, I don’t get any error logs but the function does not get executed.
The AI Character is spawned on the server, in the player controllers OnPossess() callback
On the client, the actor is owned locally checked by using IsOwnedBy(UGameplayStatics::GetPlayerController(this, 0));
Using NetworkProfiler.exe I can see that the RPC is actually going over the network.
The code works fine in single player but launching with a dedicated server or with a listen server with a client it does not execute.
I have tried to verify whether the function is executing using logs, breakpoints and forcing null pointer exceptions, so it doesn’t even seem to be executed
Any help would be much appreciated. Are there any network debugging tools that I haven’t mentioned which might be useful?
client can only send ServerRPC to his owned actors. this is mostly because of security so that other clients can’t change your stuff buy calling those Server RPCs.
if your AI character has no owner or can be directed by anyone send the RPC from PlayerController.
class AMyPlayerController : public APlayerController
{
UFUNCTION(Server, WithValidation, Reliable)
void ServerMoveAIToLocation(ACharacter* aiChar, FVector destination);
void ServerMoveAIToLocation_Implementation(ACharacter* aiChar, FVector destination)
{
AAIController* ai = Cast<AAIController>(aiChar->GetController());
ai->GetBlackboardComponent()->SetValueAsVector("TargetLocation", destination);
}
}
Hi, thanks for the response. As I said in the question the actor is owned by the PlayerController, and if I don’t manually make it owned by the PlayerController it gives me an error message saying there is no owning connection.
You probably figured this out long ago, but to anyone else having this problem and landing here via a google search:
The issue is that APawn override’s GetNetConnection like so:
class UNetConnection* APawn::GetNetConnection() const
{
// if have a controller, it has the net connection
if ( Controller )
{
return Controller->GetNetConnection();
}
return Super::GetNetConnection();
}
So, if you have a pawn controlled by an AIController, it’ll use the NetConnection of the AIController even though you’ve set the network owner with SetOwner().
The fix is to override GetNetConnection yourself for pawns controlled by an AIController:
Thanks!! Worked perfectly. I don’t know if this is a good practice or not. I am passing all RPC calls (Client → Server) through the PlayerController and the PlayerController makes the call to the Actor that holds the necessary logic. It’s practically just a hop.