Does CopyProperties in PlayerState actually work?

I see that the player state has a CopyProperties event that is supposed to be used to copy data to a new player state when seamlessly travelling to another level. I’ve tried implementing this event in blueprint but it does nothing. It never gets called when using seamless travel. Is that right? Is it broken or is this not what it’s for, or do you need to do it in C++?

So I decided to implement it in a custom C++ PlayerState and it does get called there, but it does nothing. The properties don’t carry over to the next level after I’ve copied them to the NewPlayerState. I also tried implementing SeamlessTravelTo and it to does the same thing. Gets called, but the properties don’t persist. They are just reset back to their defaults when the next level is loaded.

I’m using my custom player state in the lobby, transition map and the game map and I have seamless travel turned on in all game modes. So there must be something else that is missing.

Finally got it working my changing my PlayerState variables from BlueprintReadWrite to BlueprintReadonly. I have no idea why that makes it work. Very annoying though as you now have to create a Set* UFUNCTION for each variable you want to be able to write to from Blueprint.

Now we just have to figure out how to do it in Blueprints

Are there any updates on this based on Blueprints? How does this event work in blueprints, as it seems like the event won’t even get called when using it.

Important to note you cannot use it in the editor because seamless travel does not work in the editor. And in order for copy properties to work, you need seamless travel and that only works in standalone or packaged build.

1 Like

**Important to note you cannot use it in the editor because seamless travel does not work in the editor. Your variable cannot be “BlueprintReadWrite”. And you also need to enable seamless travel and that only works in standalone or packaged build.

UPROPERTY(BlueprintReadOnly, Replicated, Category = "Preplan")
Test = "Original Value";  



void AShooterPlayerState::CopyProperties(class APlayerState* PlayerState)
{
	 Super::CopyProperties(PlayerState);

	 if (IsValid(PlayerState))
	 {
		this->Test = "New Value";
		
		 AShooterPlayerState* ShooterPlayerState = Cast<AShooterPlayerState>(PlayerState);        
		 if (ShooterPlayerState)
		 {            
			 ShooterPlayerState->Test = this->Test;            
		 }
	 }
}