Skip to content

Instantly share code, notes, and snippets.

@mossyblog
Last active October 5, 2023 06:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mossyblog/0dd716986c2f5e23568409201bbe7937 to your computer and use it in GitHub Desktop.
Save mossyblog/0dd716986c2f5e23568409201bbe7937 to your computer and use it in GitHub Desktop.
/*
The FPosition struct is defined with a NetSerialize function. This function handles the custom serialization logic for the struct.
The UMyHealthComponent class contains a Position property of type FPosition. This property is marked with the Replicated
specifier, indicating that it should be considered for replication.
The GetLifetimeReplicatedProps function is implemented to tell the Unreal Engine replication system which properties of the
UMyHealthComponent should be replicated. In this case, the Position property is added to the list.
When the Position property changes on the server, Unreal's replication system will recognize it as "dirty" and will use the
NetSerialize method of FPosition to serialize its data for transmission to clients. On the client side, the data will be
deserialized using the same NetSerialize method, and the Position property will be updated with the received values.
*/
USTRUCT()
struct FPosition
{
GENERATED_BODY()
UPROPERTY()
float X;
UPROPERTY()
float Y;
bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
{
// Capture the current state
float PrevX = X;
float PrevY = Y;
// Serialize the properties
Ar << X;
Ar << Y;
// Determine if there's a change
bool bHasChanged = false;
if (Ar.IsSaving())
{
bHasChanged = (X != PrevX || Y != PrevY);
}
// The bOutSuccess flag indicates if the serialization process was successful.
bOutSuccess = true;
// Return whether there's been a change.
return bHasChanged;
}
};
template<>
struct TStructOpsTypeTraits<FPosition> : public TStructOpsTypeTraitsBase2<FPosition>
{
enum
{
WithNetSerializer = true,
};
};
// --- MyFooComponent with FPosition property ---
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class YOURPROJECT_API UMyFooComponent : public UActorComponent
{
GENERATED_BODY()
public:
UMyHealthComponent();
// Replicated FPosition property
UPROPERTY(Replicated)
FPosition Position;
virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const override;
};
// Implementation of GetLifetimeReplicatedProps to specify which properties to replicate
void UMyFooComponent::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UMyHealthComponent, Position);
}
/*////////////////////////////////////////////////////////////////////////////////////////////////////////
If you wanted to say integrated this with say flecs::ecs
/////////////////////////////////////////////////////////////////////////////////////////////////////////*/
// Somewhere on your client you would have a function like this:
UFUNCTION()
void OnRep_Position()
{
SyncPositionToFlecs();
}
// Then in your MyFooComponent implementation cpp
void UMyFooComponent::SyncPositionToFlecs()
{
// Obtain the corresponding Flecs entity (this might vary based on your setup)
flecs::entity e = ...;
// Set the updated Position data in Flecs
e.set<FPosition>(Position);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment