x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

WorldSettings::Pauser doesn't always replicate when the game is paused.

I ran into this issue in current 4.15. I searched and found UE-34407. https://issues.unrealengine.com/issue/UE-34407

The issue shows Affect Versions 4.12.5 and the issue has been marked as resolved as of Feb 17, 2017.

The issue is marked as Won't Fix: with comment: This issue has been closed as 'Won't Fix' due to an extended period of time without updates. If this issue is important to you please let us know by posting on the AnswerHub or UDN, and Epic will re-open the ticket for further review.

Please reopen the issue and add version 4.15.

For clarification, I have overridden the PlayerController pausing functions to support multi player. I'm able to have my PlayerController clients call their PlayerControllers on the server and have the server call SetPause on the GameMode. SetPause and ClearPause succeeded as expected. I traced the problem to WorldSettings::Pauser. It is being set on the server. But the clients are (the vast majorly of the time) not getting updated.

Thanks

Product Version: UE 4.15
Tags:
more ▼

asked Mar 01 '17 at 04:32 AM in Using UE4

avatar image

HyperToxic
26 1 4 6

(comments are locked)
10|2000 characters needed characters left

2 answers: sort voted first

Here is my code, it works for single-player, multi-player and on dedicated server. No blueprints are required. Just call PlayerContoller.Pause() on the client or server or by blueprint.

[RTSGameMode.h]

 public:
     virtual bool SetPause(APlayerController* PC, FCanUnpause CanUnpauseDelegate = FCanUnpause()) override;
     virtual bool ClearPause() override;
 private:
     void CallAllClientsSetWorldSettingsPauser(APlayerState* Pauser);

[RTSGameMode.cpp]

 bool ARTSGameMode::SetPause(APlayerController* PC, FCanUnpause CanUnpauseDelegate /*= FCanUnpause()*/)
 {
     if (Super::SetPause(PC, CanUnpauseDelegate))
     {
         //hack because replication during pause is not working correctly.
         CallAllClientsSetWorldSettingsPauser(PC->PlayerState);
         return true;
     }
 
     return false;
 }
 
 bool ARTSGameMode::ClearPause()
 {
     if (Super::ClearPause())
     {
         //hack because replication during pause is not working correctly.
         CallAllClientsSetWorldSettingsPauser(nullptr);
         return true;
     }
 
     return false;
 }
 
 //hack because replication during pause is not working correctly.
 void ARTSGameMode::CallAllClientsSetWorldSettingsPauser(APlayerState* Pauser)
 {
     for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
     {
         ARTSPlayerController* PlayerController = Cast<ARTSPlayerController>(*Iterator);
         PlayerController->ClientSetPauser(Pauser);
     }
 }

[RTSPlayerController.h]

 public:
     UFUNCTION(BlueprintCallable)
     virtual void Pause() override;
 
     UFUNCTION(reliable, client)
     void ClientSetPauser(APlayerState* Pauser);
 
 private:
     UFUNCTION(reliable, server, WithValidation)
     void ServerPauseGame();

[RTSPlayerController.cpp]

 void ARTSPlayerController::Pause()
 {
     ServerPauseGame();
 }
 
 bool ARTSPlayerController::ServerPauseGame_Validate()
 {
     return true;
 }
 
 void ARTSPlayerController::ServerPauseGame_Implementation()
 {
     bool result = SetPause(!IsPaused());
 }
 
 void ARTSPlayerController::ClientSetPauser_Implementation(APlayerState* Pauser)
 {
     AWorldSettings * WorldSettings = GetWorldSettings();
     if (WorldSettings)
         WorldSettings->Pauser = Pauser;
 }
more ▼

answered Mar 02 '17 at 02:16 AM

avatar image

HyperToxic
26 1 4 6

(comments are locked)
10|2000 characters needed characters left

Hey HyperToxic,

I originally offered a suggestion to fix this by doing the following:

[MyGameMode.cpp]

 // Function Override
 bool AAH306237GameMode::SetPause( APlayerController* PC, FCanUnpause CanUnpauseDelegate )
 {
     if( Super::SetPause(PC, CanUnpauseDelegate)  )
     {
         for( FConstPawnIterator Iterator = GetWorld()->GetPawnIterator(); Iterator; ++Iterator )
         {
             ATCharacter *Character = Cast<ATCharacter>( *Iterator );
             if( Character )
             {
                 Character->RecievePauser( PC->PlayerState );
             }
         }
         return true;
     }
     return false;
 }

[MyCharacter.h]

 UFUNCTION( client, reliable )
 void RecievePauser( APlayerState *Pauser );

[MyCharacer.cpp]

 void ATCharacter::RecievePauser_Implementation( APlayerState *Pauser )
 {
     if( Pauser )
     {
         PauserName = Pauser->GetName( );
     }
 }

This should force the replication of the pause, prior to pause being set.

more ▼

answered Mar 01 '17 at 07:49 PM

avatar image

ImVawx ♦♦ STAFF
6.7k 114 16 126

avatar image HyperToxic Mar 02 '17 at 01:33 AM

Kyle,

Thank you so much. However, I'm not sure in my case how setting PauserName in some ATCharacter would help. As WorldSettings()->Pauser() is NULL on most of the clients most of the time. I do see how this would force the server to send Pauser to all ATCharacters on clients, but I fail to understand how it would force the replication of the WorldSettings()->Pauser(). As IsGamePaused() is basically { WorldSettings()->Pauser() != nullptr }.

I did find a hack solution after writing this Awnser Hub though, my solution was was to also to override GameMode::SetPause() and call the Super implementation, I also had to override GameMode::ClearPause() because that was also not replicated most of the time.

In my case I iterate the PlayerContollers in GameMode::SetPause() and GameMode::ClearPause() on the server and call a new client replicated function called APlayerContoller::ClientSetPauser(Pauser) which basically directly sets WorldSettings()->Pauser to Pauser or nullptr (in case of clear) on all clients.

Thank you again for posting your solution. I'm going to post mine here because, google showed hundreds if not thousands of people having the same problem.

I love Unreal, yet its insane to think that this broken pause behavior is still the default behavior everyone gets to see all the time. It smells like a bug, it acts like a bug it must be a bug.

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question