Hello
I’m using Lyra’s Equipment Manager architecture in my game.
This system uses a FFastTArraySerializer to trigger PostReplicateAdd events on the client when a new equipment entry is added to the FFastTArraySerializerArray.
I have pretty much copied and pasted the system inside my project (i’m not using lyra’s project).
This is what the FFastTArraySerializer and the FFastArraySerializerItem looks like (exact same of lyra, except by the names):
USTRUCT(BlueprintType)
struct FSpawnedScorestreakEntry : public FFastArraySerializerItem
{
GENERATED_BODY()
FSpawnedScorestreakEntry()
{}
public:
FString GetDebugString() const
{
return FString::Printf(TEXT("%s of %s"), *Instance.GetName(), *GetNameSafe(ScorestreakDefinition.Get()));
}
private:
friend APRT_ScorestreakManager;
friend struct FScorestreakInstanceList;
UPROPERTY()
TSubclassOf<UPRT_ScorestreakDefinition> ScorestreakDefinition;
UPROPERTY(BlueprintReadOnly, meta=(AllowPrivateAccess=true))
TObjectPtr<UPRT_ScorestreakInstance> Instance = nullptr;
};
/* ACTUAL LIST*/
USTRUCT(BlueprintType)
struct FScorestreakInstanceList : public FFastArraySerializer
{
GENERATED_BODY()
FScorestreakInstanceList()
: OwnerComponent(nullptr)
{
}
FScorestreakInstanceList(AActor* InOwnerComponent)
: OwnerComponent(InOwnerComponent)
{
}
public:
//~FFastArraySerializer contract
void PreReplicatedRemove(const TArrayView<int32> RemovedIndices, int32 FinalSize);
void PostReplicatedAdd(const TArrayView<int32> AddedIndices, int32 FinalSize);
void PostReplicatedChange(const TArrayView<int32> ChangedIndices, int32 FinalSize);
//~End of FFastArraySerializer contract
bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
return FFastArraySerializer::FastArrayDeltaSerialize<FSpawnedScorestreakEntry, FScorestreakInstanceList>(Entries, DeltaParms, *this);
}
UPRT_ScorestreakInstance* AddEntry(TSubclassOf<UPRT_ScorestreakDefinition> scorestreakDef);
void RemoveEntry(UPRT_ScorestreakInstance* Instance);
private:
friend APRT_ScorestreakManager;
// Replicated list of equipment entries
UPROPERTY(BlueprintReadOnly, meta=(AllowPrivateAccess=true))
TArray<FSpawnedScorestreakEntry> Entries;
UPROPERTY(NotReplicated)
TObjectPtr<AActor> OwnerComponent;
};
Everything is working exactly the same as Lyra’s project. Except that when the PostReplicateAdd event triggers on the client, the instance uobject pointer is nullptr.
my project (nullptr on post replicate add):
lyra (valid on post replicate add):
The next frame however, the pointer will be valid and no longer nullptr.
I’m using an actor data channel to replicate the UObject (just like lyra does), it doesn’t matter if I’m using the replicated subobject list or the ReplicateSubobjects function. The problem persists.
In Lyra, when the postreplicateadd event triggers, the uobject pointer is already valid.
Is there any config regarding replication that I might be missing? thanks!