I haven’t played with UE4 network code, so I’m kinda flying blind here.
Do you think it’s just the use of “this”? Perhaps if you assign it to a variable and pass that?
if (HitPlayer)
{
APPlayer* KillingPlayer = this;
GEngine->AddOnScreenDebugMessage(-1, 20.0f, FColor::Green, this->GetName());
HitPlayer->Die(KillingPlayer);
}
Or perhaps have a mediating object on the server, in gamemode?
void AMyGameMode::AssignKiller(APPlayer* KillingPlayer, APPlayer* DyingPlayer) {
DyingPlayer->Die(KillingPlayer);
}
Depending on what you’re using the Killer pointer for, could you just pass the data needed from the killer, rather than the object pointer itself?
Are all players replicated on all clients? It may be the pointer is a reference to an object that doesn’t exist on that client; or perhaps the pointer data doesn’t marry up properly. It gets a memory address for the pointer on the sending client, and the receiving client has different data at that address?
Does the local player on each client end up being player1 locally? If all players exist on every client, could you use another identifier to grab the local instance of that player? Something like:
//.h
/** Array of all local player instances */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Players")
TArray<APPlayer*> Players;
//.cpp
void APPlayer::ServerFire_Implementation()
{
...
if (HitPlayer)
{
APPlayer* KillingPlayer = this;
HitPlayer->Die(this->PlayerID);
}
}
void APPlayer::Die(int32 KillerID) {
Killer = GetLocalPlayer(KillerID);
}
APPlayer::GetLocalPlayer(const int32& TargetID) {
for (auto* EachPlayer : Players) {
if (EachPlayer->PlayerID == TargetID) {
return EachPlayer;
}
}
return NULL;
}