I have menu where client can set nickname and set IP of server and connect.
I need to set entered nickname to RenderText (component of my character)
Menu blueprint:
I have GamePlayerState class and set it in AMenuGameMode and AMyGameMode
AMenuGameMode::AMenuGameMode(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
PlayerControllerClass = AMenuPlayerController::StaticClass();
PlayerStateClass = AGamePlayerState::StaticClass();
}
AMyGameMode::AMyGameMode(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
DefaultPawnClass = AGamePlayerCharacter::StaticClass();
PlayerControllerClass = AGamePlayerController::StaticClass();
PlayerStateClass = AGamePlayerState::StaticClass();
}
I try to save enterd nickname in instance of GameState (it in MenuPlayerController) - see image.
It have SetPlayerNick function:
GamePlayerState HEADER
#pragma once
#include "GameFramework/PlayerState.h"
#include "GamePlayerState.generated.h"
UCLASS()
class TOWN_API AGamePlayerState : public APlayerState
{
GENERATED_BODY()
public:
AGamePlayerState(const FObjectInitializer& ObjectInitializer);
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const;
virtual void CopyProperties(class APlayerState* PlayerState);
virtual void OverrideWith(class APlayerState* PlayerState);
UFUNCTION(BlueprintCallable, Category = "State")
void SetPlayerNick(FString nick);
UFUNCTION(BlueprintCallable, Category = "State")
FString GetPlayerNick();
private:
UPROPERTY(Transient, Replicated)
FString player_nick;
};
GamePlayerState SOURCE
#include "MyGame.h"
#include "GamePlayerState.h"
#include "Net/UnrealNetwork.h"
#include "NetworkingDistanceConstants.h"
AGamePlayerState::AGamePlayerState(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
player_nick = "no nick";
bReplicates = true;
}
void AGamePlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AGamePlayerState, player_nick);
}
void AGamePlayerState::CopyProperties(class APlayerState* PlayerState)
{
Super::CopyProperties(PlayerState);
if (PlayerState)
{
AGamePlayerState* state = Cast<AGamePlayerState>(PlayerState);
if (!state)
return;
state->player_nick = player_nick;
}
}
void AGamePlayerState::OverrideWith(class APlayerState* PlayerState)
{
Super::OverrideWith(PlayerState);
if (PlayerState)
{
AGamePlayerState* state = Cast<AGamePlayerState>(PlayerState);
if (!state)
return;
player_nick = state->player_nick;
}
}
void AGamePlayerState::SetPlayerNick(FString nick)
{
player_nick = nick;
}
FString AGamePlayerState::GetPlayerNick()
{
return player_nick;
}
In my AGamePlayerCharacter I have TextRender
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Text, meta = (AllowPrivateAccess = "true"))
UTextRenderComponent* FloatingText;
and some funtions:
Header AGamePlayerCharacter
void ChangeNickText(const FString& text);
UFUNCTION(Server, Reliable, WithValidation)
virtual void ServerChangeNickText(const FString& text);
void ServerChangeNickText_Implementation(const FString& text);
bool ServerChangeNickText_Validate(const FString& text);
virtual void PossessedBy(AController* NewController) override;
Source AGamePlayerCharacter
void AGamePlayerCharacter::ChangeNickText(const FString& text)
{
GEngine->AddOnScreenDebugMessage(-1, 200.2f, FColor::Red, FString("ChangeNickText: " + text));
FloatingText->SetText(text);
if (Role < ROLE_Authority)
{
GEngine->AddOnScreenDebugMessage(-1, 200.2f, FColor::Red, FString("ServerChangeNickText: " + text));
ServerChangeNickText(text);
}
}
void AGamePlayerCharacter::ServerChangeNickText_Implementation(const FString& text)
{
GEngine->AddOnScreenDebugMessage(-1, 200.2f, FColor::Red, FString("ServerChangeNickText_Implementation: " + text));
ChangeNickText(text);
}
bool AGamePlayerCharacter::ServerChangeNickText_Validate(const FString& text)
{
return true;
}
void AGamePlayerCharacter::PossessedBy(AController * NewController)
{
Super::PossessedBy(NewController);
AGamePlayerController* OwnerController = Cast<AGamePlayerController>(NewController);
AGamePlayerState* state = Cast<AGamePlayerState>(OwnerController->PlayerState);
FString nickname = "No defined";
if (state)
{
nickname = state->GetPlayerNick();
GEngine->AddOnScreenDebugMessage(-1, 200.2f, FColor::Yellow, FString("state->GetPlayerNick(): " + nickname));
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 200.2f, FColor::Green, FString("state == NULL !!!!!! "));
}
ChangeNickText(nickname);
}
But all this not work… I deal with it 6 days before write this answer and cannot understan why it not work.