Replicating Variables & Updating Changes

Replication only happens if you change the variable on the server.

If you want to instigate a replicated change in health from a client, you will need to RPC up to the server, and then have the server change the health variable.

https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Replication/RPCs/index.html

Hey Community,

I have another question for you guys. I’ve been messing around with replication abit and I seemed to have hit quite the stump. So maybe one of you guys can help me out.

Basically, I have a number that I want replicated to every single connected client. This number is increased by 1 during a function call and then that number is directly represented by a Text Render that is placed over the characters head… but for some reason I can’t get the number to replicate and I was wondering why and how to fix it? Thank you.

// My Character.cpp

void AMyCharacter::Jump()
{
	//....

    health = health + 1.0;

   &AMyCharacter::GetLifetimeReplicatedProps;

	nameTest(); // This is the function to update the variable

   //...

}

void AMyCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	// Replicate to everyone
	DOREPLIFETIME(AMyCharacter, health);

}



void AMyCharacter::nameTest_Implementation()
{
	FString VeryCleanString = FString::SanitizeFloat(health);
	TextRender->SetText(FString(VeryCleanString));
}

//////////////////////

MyCharacter.H

protected:

	UFUNCTION(reliable, client) // I've used server & NetMulticast , no change.
		void nameTest();

	UPROPERTY(Replicated)
		float health;

Alright so I did that and now the TextRender won’t actually update at all in a dedicated server. What should I do?

//My Character.CPP

bool AMyCharacter::nameTest_Validate()
{
	return true;
}

void AMyCharacter::nameTest_Implementation()
{
	FString VeryCleanString = FString::SanitizeFloat(health);
	TextRender->SetText(FString(VeryCleanString));
}

void AMyCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);

// Replicate to everyone
DOREPLIFETIME(AMyCharacter, health);
DOREPLIFETIME(AMyCharacter, TextRender);

}

// Constructor contains

TextRender = PCIP.CreateDefaultSubobject(this, TEXT(“NewTextRenderComponent”));
TextRender->AttachTo(RootComponent);
TextRender->SetNetAddressable();
TextRender->SetIsReplicated(true);

//My Character.H

	UFUNCTION(reliable, server, WithValidation)
		void nameTest();

	UPROPERTY(Replicated)
		float health;

UPROPERTY(Category=TextRenderActor, VisibleAnywhere, BlueprintReadOnly, Replicated)
	TSubobjectPtr<class UTextRenderComponent> TextRender;

This is also set for the TextRender. I don’t know why it isn’t updating or working.
TextRender->SetNetAddressable();
TextRender->SetIsReplicated(true);

There are too many things wrong with what you have setup that I think you need to go back to some basics before trying this. I recommend this tutorial series on networking first: Blueprint Networking Tutorials - Unreal Engine

You can’t replicate a text component like you are thinking. You should be updating the text field on all clients using a ReplicateUsing field on health, instead of trying to replicate a text render component. There aren’t any render components that actually support replication like you are thinking.

Actually I already have it figured out with the setup I have working. Basically I am sending commands to the server then using another function to MultiNetCast it to the rest of the clients. :slight_smile:

I’ll go ahead and post the answer on how I got it to work.

Here is the answer that I figured out with the help of cgrebeld’s link. It was actually pretty simple once you’ve got the know-how.

So anybody who is stuck on something like this i’ll explain: Basically what I do is I first send a command to the server from the client. Then I send a command from the server to all the clients and voila. Works like a charm.

//MyCharacter.CPP

void AMyCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	// Replicate to everyone
	DOREPLIFETIME(AMyCharacter, test);

}

bool AMyCharacter::ClientRPCCFunction_Validate()
{
	return true;
}

void AMyCharacter::ClientRPCCFunction_Implementation()
{
	TextRender->SetText(FString(test));
	ClientFunc();
}

void AMyCharacter::ClientFunc_Implementation()
{
	TextRender->SetText(FString("Name Here!"));

}

// In the constructor went this!

	TextRender = PCIP.CreateDefaultSubobject<UTextRenderComponent>(this, TEXT("NewTextRenderComponent"));
	TextRender->AttachTo(RootComponent);
	TextRender->SetNetAddressable();
	TextRender->SetIsReplicated(true);
	TextRender->AddLocalOffset(FVector( 0.0, 25.0, 110.0), true);


// MyCharacter.H

	UFUNCTION(reliable, Server, WithValidation) // Called on the client executed on the server
	void ClientRPCCFunction();

	UFUNCTION(reliable, NetMulticast) // Called on the server executed to all the clients
		void ClientFunc();

	UPROPERTY(Replicated)
		FString test;


	UPROPERTY(Category = TextRenderActor, VisibleAnywhere, BlueprintReadOnly, Replicated)
		TSubobjectPtr<class UTextRenderComponent> TextRender;

You don’t need to set your TextRenderComponent to replicated.