I have the weirdest problem, a function call is going to a totally different function for some reason.
In my player controller, I am going through making functions that change some values on the playerstate to do with selecting units in an RTS. For speed, and because the server doesn’t really need to know what the player has selected clientside except for replays and spectators, the variables are set clientside then sent to the server via an RPC. I don’t know if this is relevant to the problem though.
To do this I have a pair of functions, like the usual RPC usage
UFUNCTION(BlueprintCallable, Category = "FCPlayerControllerActions")
void PlayerSelectUnits(const TArray<AFCUnit*>& NewUnits);
UFUNCTION(Server, Reliable, WithValidation)
void ServerPlayerSelectUnits(const TArray<AFCUnit*>& NewUnits);
Here’s the whole .h file FCPlayerController.h - Pastebin.com
void AFCPlayerController::PlayerSelectUnits(const TArray<AFCUnit*>& NewUnits)
{
AFCPlayerState* fcps = (AFCPlayerState*)PlayerState;
int32 i = 0;
if (fcps)
{
if (Role < ROLE_Authority)
{
ServerPlayerSelectUnits(NewUnits);
}
for (i = 0; i < NewUnits.Num(); i++)
{
if (NewUnits[i])
{
if ((NewUnits[i]->TeamIndex == fcps->PlayerTeamSlot) && (NewUnits[i]->ForceIndex == fcps->PlayerForceSlot))
{
if (fcps->SelectedUnits.Num() == 0)//if this is the first unit selected
{
PlayerChangeCommandMenuPage(0);//set the page back to root
TSubclassOf<AFCUnit> tempunitclass = NewUnits[i]->StaticClass();
PlayerChangeSubSelectionUnitType(tempunitclass);
}
fcps->SelectedUnits.AddUnique(NewUnits[i]);
}
}
}
}
}
bool AFCPlayerController::ServerPlayerSelectUnits_Validate(const TArray<AFCUnit*>& NewUnits)
{
return true;
}
void AFCPlayerController::ServerPlayerSelectUnits_Implementation(const TArray<AFCUnit*>& NewUnits)
{
PlayerSelectUnits(NewUnits);
}
This function calls fine, the problem is when I call some similar functions within this one, and again when the RPC happens. Specifically:
PlayerChangeCommandMenuPage(0);//set the page back to root
TSubclassOf<AFCUnit> tempunitclass = NewUnits[i]->StaticClass();
PlayerChangeSubSelectionUnitType(tempunitclass);
For both change command menu page and change sub selection unit type functions, instead of calling what I told it to call, the blueprint callable functions of that name, it calls ServerPlayerChangeCommandMenuPage(0), which gets called on the server. In the server version it again tries to call PlayerChangeCommandMenuPage(newpage) and unreal picks ServerChangeCommandMenuPage, meaning the other version is never called. I have absolutely no idea why it is doing this, but I can watch it in debugger calling the server version straight away every time. This puzzles me because the function and the server rpc to call it on server share nothing but similar names. I am unaware of a circumstance when unreal would automatically prefix my calls with Server instead of exec or whatever. Has me buggered.
Here is change menu page
UFUNCTION(BlueprintCallable, Category = "FCPlayerControllerActions")
void PlayerChangeCommandMenuPage(int32 newpage);
UFUNCTION(Server, Reliable, WithValidation)
void ServerPlayerChangeCommandMenuPage(int32 newpage);
And the function definitions, here is the whole .cpp file fcplayercontroller.cpp - Pastebin.com
void AFCPlayerController::PlayerChangeCommandMenuPage(int32 newpage)
{
AFCPlayerState* fcps = (AFCPlayerState*)PlayerState;
if (fcps)
{
fcps->PlayerCommandMenuPage = newpage;
if (Role < ROLE_Authority)
{
ServerPlayerChangeCommandMenuPage(newpage);
}
}
}
bool AFCPlayerController::ServerPlayerChangeCommandMenuPage_Validate(int32 newpage)
{
return true;
}
void AFCPlayerController::ServerPlayerChangeCommandMenuPage_Implementation(int32 newpage)
{
PlayerChangeCommandMenuPage(newpage);
}
Here is the generated header FCPlayerController.generated.h - Pastebin.com and cpp fieldcommander.generated.cpp - Pastebin.com