How to make PlayerController persist when joining a server?

Here’s my situation:

I have a main menu in which I can set a player name. From this menu, I can join an online game. I want my name set in the offline menu to persist to the online session. I am using this to travel to the server:

PlayerController->ClientTravel(TravelURL, ETravelType::TRAVEL_Relative);

Here’s what I tried:

  • Storing it in the PlayerState’s “PlayerName”: This seemed like it would work, because the PlayerName seems to be persisted in the PlayerState’s “CopyProperties” method. However, this doesn’t work. Seems like it is only persisted when you’re already in a server, but not when you go from an offline session to a server.
  • Storing it in the PlayerController. Since my PlayerController is the one traveling to the server, I was under the impression that it would be fully persisted. I added a replicated “playerName” variable in it and set it to some name. But it didn’t work. Once the player has joined the server, its name goes back to an empty string.
  • Storing my entire PlayerState in my GameInstance just before joining the server, and then getting it back from the GameInstance once we’ve joined. This didn’t work. I found out the GameInstance we get once we’ve joined is actually the server’s, and not the individual clients’.

I don’t really know what to try next. I can think of some disgusting hacky solutions, but I’d much rather understand how to do things properly

I don’t why you trying to more entire classes to server insted of just setting player name on PlayerController start up. PlayerController is not persistent not in client or server.

No sure if this gonna work with replication right but try using config, it will also handle storage for you. Mark your property to be config savable UPROPERTY(config) and then call SaveConfig() in that object.

I think argument are actually optional as i seen in engine code this function used without anything. This will store config of class in to ini file (in case of player controller it is set to store in Game.ini) and if i’m not mistaken it will automatically restore once PlayerController is spawn in client, if not you can do LoadConfig() on init

MAke sure htat this property replicates from client to server somehow, on server side you could set it to PlayerState, then it should work i think

Note that you can do this in any UObject so this is useful for all kind of things ;]

Seems like this would do the trick. I’ll try it later tonight and see if it works.

Still, i wonder if there’s a way to store game data between levels without having to save to a file. GameInstance would’ve been perfect for this normally, but it seems to get reset to the host’s GameInstance as soon as I join the server (or was that an incorrect observation on my part?). What I’d really need is a “LocalGameInstance”

Well all UObjects are persistent, all Actors (this includes PlayerController anf GameMode) are deleted together with world that they are assigned to. So you could create some kind of playercontroller-like UGameInstance and somehow sync it with server. Think out of the box, if engine missing something you can always add something, you making a same kind of code module as modules in engine, you have exact same access to all things and engine modules them selfs has same access to features and limitations

also check how to pass player name through joining url