Hi.
I was having trouble with replication in my project, so I created a mini project just to get the replication stuff right.
So, here’s my setup:
I created a C++ project based off of the third person template. Default player character… etc
I added an input action that basically performs a trace hit and determines whether it hit a “pickable” item (a class that I created).
if it did, it calls a function on that item called “used()” which basically hides the mesh component from view (it’s for an inventory system).
When I run it as a single player, it works great. I get to an item, press G, the item’s gone.
But when I try to play with 2 players, and a dedicated server (in the editor), it doesn’t work correctly.
The action happens on the server. I know this because after performing the action, I can actually walk through the item as if it wasn’t there but it’s still showing.
However, all the players (including myself) still see the mesh. It’s just not replicating to all the actions.
Here are the main points of my code:
ReplicationCharacter.h
I have these functions defined:
void Grab();
UFUNCTION(Server, Reliable, WithValidation)
void ServerGrab();
void ServerGrab_Implementation();
bool ServerGrab_Validate();
ReplicationCharacter.cpp
void AReplicationCharacter::Grab()
{
//It only performs this action on the server. Hence the "else" part. This is just for easier debugging
//If I remove the else so that the code still executes on the client, it does work but it still doesn't replicate to the other players
if (Role < ROLE_Authority)
{
ServerGrab();
}
else
{
FHitResult Target = PerformTractHit(); //This is just a simple function that perform a trace hit and returns the result
if (APickable * ItemTarget = Cast<APickable>(Target.GetActor()))
{
if (ItemTarget)
{
ItemTarget->Used();
}
}
}
}
void AReplicationCharacter::ServerGrab_Implementation()
{
Grab();
}
bool AReplicationCharacter::ServerGrab_Validate()
{
return true;
}
And now for the Pickable class:
Pickable.h
It has a static mesh variable which I then use to hold the static mesh. I set it to replicated. The rest is not important
UPROPERTY(Replicated, VisibleAnywhere, Category = "Mesh")
UStaticMeshComponent * MeshComp;
virtual void BeginPlay() override;
void Used();
And the .cpp file:
APickable::APickable(const FObjectInitializer& ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = true;
MeshComp = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Mesh"));
MeshComp->SetIsReplicated(true);
= MeshComp;
bReplicates = true;
bReplicateMovement = true;
}
void APickable::Used()
{
if (Role == ROLE_Authority)
{
MeshComp->SetHiddenInGame(true);
MeshComp->SetSimulatePhysics(false);
SetActorEnableCollision(false);
}
}
void APickable::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(APickable, MeshComp);
}
A bit of a tl;dr. Sorry about that, but if anybody could tell me where I went wrong, It’d be great.
ps, as you may’ve guessed, I’m new to replication in UE4.
Thanks!