Where should i call an init function on a client ?

Hello,

My game is (steam) networked and i need to update my actors after connecting on the server.

My problem is that the state of the actors depends on the playerstate (more precisely they depend on the PS netID).

So:

  • i need the playerstate to be present and fully replicated
  • i need all the actors to be present and fully replicated

I made a function (let’s call it UpdateAllActors()) that does the job.
When i bind this function to a button and click the button on the client after connection, the actors are correctly setup.

Where should i call this function to ensure that everything is setup without any human intervention ?

I tried BeginPlay() and PostNetInit() in the playercontroller, in playerstate, and in all visible actors.
I tried PostSeamlessTravel() in the playercontroller.
It never works.

Is there a function on a client that would say “Ok buddy, every spawnings and replications i needed to do are done, i’m in the exact same state as the server, you can do your things now” ?

I have been struggling with that kind of problem pretty much everytime i needed to initialize anything and could always find a way out using the standards BeginPlay, but now my code is messy (i have initialization function for the visible actors in the PC, and initialization function for the PC in visible actors, same thing for the PS, and it’s a mess.
And this time, i can’t find a workaround and am stuck.

So is there a proper way to know when the client is completely ready for every initializations i need to do ?
Completely ready = gamestate, playercontroller, playerstate and all visible actors have been spawned and replicated.

Thanks

Cedric

Hey,

Still no clean and elegant solution but a working workaround i usually do in those cases and did again to keep things moving: create a timer calling the function every 10th of second until the player state is present.


// Called after spawning and reading replicated properties
void AYagPawn::PostNetInit()
{
    Super::PostNetInit();

    // try to refresh until the PS is available
    GetWorld()->GetTimerManager().SetTimer(RefreshPawnVisibilityHandle, FTimerDelegate::CreateUObject(this, &AYagPawn::RefreshPawnVisibility), .1f, true);
    //RefreshPawnVisibility();
}

And of course the update function (RefreshPawnVisibility) has to clean the handle when everything is ok:


void AYagPawn::RefreshPawnVisibility()
{
    //GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("RefreshPawnVisibility")));

    // check player state (needed in GetUint64PSNetId() )
    AYagPlayerController* ThisPC = Cast<AYagPlayerController>(ThisController);
    if (!ThisPC) return;
    if (!ThisPC->PlayerState) return;

    // clean refresh timer
    GetWorld()->GetTimerManager().ClearTimer(RefreshPawnVisibilityHandle);

    ...]
}

Again, this is just some ugly workaround, but it works.

If anyone has a correct way to do this, thanks in advance.

Cheers
Cedric