x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Custom NetSerialize on USTRUCT

I am attempting to create a 3dArray struct with a custom NetSerializer that compresses the array first, send the compressed data, then decompressed at the destination. This is what I have so far.

 USTRUCT()
 struct F3DArray
 {
     GENERATED_USTRUCT_BODY()
 
     F3DArray()
     {
         Data.Init(false, FMath::Pow(32, 3));
     }
 
     bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
     {
         UE_LOG(LogTemp, Warning, TEXT("Replicate"));
         bOutSuccess = true;
         if (Ar.IsSaving())
         {
             TArray<uint8> Compressed;
             TArray<uint8> UncompressedBuffer;
             FMemoryWriter ArWriter(UncompressedBuffer);
             ArWriter << Blocks;
 
             const int32 UncompressedSize = UncompressedBuffer.Num();
             const int32 HeaderSize = sizeof(int32);
 
             Compressed.Init(0, HeaderSize + FMath::TruncToInt(1.1f * UncompressedSize));
 
             int32 CompressedSize = Compressed.Num() - HeaderSize;
             uint8* DestBuffer = Compressed.GetData();
             FMemory::Memcpy(DestBuffer, &UncompressedSize, HeaderSize);
             DestBuffer += HeaderSize;
 
             FCompression::CompressMemory(ECompressionFlags::COMPRESS_ZLIB, DestBuffer, CompressedSize, UncompressedBuffer.GetData(), UncompressedSize);
 
             Compressed.SetNum(CompressedSize + HeaderSize, false);
 
             Ar << Compressed;
             return true;
         }
         else if (Ar.IsLoading())
         {
             TArray<uint8> Compressed;
             Ar << Compressed;
 
             TArray<uint8> UncompressedBuffer;
             int32 UncompressedSize = 0;
             const int32 HeaderSize = sizeof(int32);
             uint8* SrcBuffer = Compressed.GetData();
             FMemory::Memcpy(&UncompressedSize, SrcBuffer, HeaderSize);
             SrcBuffer += HeaderSize;
             const int32 CompressedSize = Compressed.Num() - HeaderSize;
 
             UncompressedBuffer.AddZeroed(UncompressedSize);
 
             FCompression::UncompressMemory(ECompressionFlags::COMPRESS_ZLIB, UncompressedBuffer.GetData(), UncompressedSize, SrcBuffer, CompressedSize);
             FMemoryReader ArReader(UncompressedBuffer);
 
             ArReader << Data;
             return true;
         }
 
         return false;
     }
 
 private:
 
     TArray<bool> Data;
 };
 template<>
 struct TStructOpsTypeTraits<F3DArray> : public TStructOpsTypeTraitsBase
 {
     enum
     {
         WithNetSerializer = true,
     };
 };

So, what happens is this - I have some generic Actor in my scene that has this struct as a member variable. I have set it to ReplicateUsing a function. This function IS being called as I have it printing a log statement to the console. The "Data" array is not being replicated though.

Here are some code snippets to show the implementation of a some of the things just mentioned:

     // These are in the actors class
     UPROPERTY(ReplicatedUsing = OnRep_MarkUpdate)
     F3DArray Data;
 
     UFUNCTION()
     void OnRep_MarkUpdate();

 // This is in the actor cpp
 
 void AReplicateTest::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
 {
     DOREPLIFETIME(AReplicateTest, Data);
 }
 
 void AReplicateTest::OnRep_MarkUpdate()
 {
     UE_LOG(LogTemp, Warning, TEXT("Replicated"));
 }

And OnRep_MarkUpdate() is being called as I do see the log print out from that - I do NOT however see any logging from the NetSerialize() function included in the USTRUCT. I have also test the compression on it's own else where, it works fine. I may be incorrectly using the FArchive in NetSerialize() though...

Also, if i place a break point in the OnRep_MarkUpdate() function it does break there, but if I put a break point in the NetSerlialize() function it is NOT hit.

Product Version: UE 4.12
Tags:
more ▼

asked Jul 27 '16 at 08:32 PM in C++ Programming

avatar image

S0rn0
71 8 13 12

avatar image Rumbleball Sep 12 '17 at 01:01 PM

Trying to increase unreals actor movement replication to 3 decimals and overriding FRepMovement. For debug I tried breakpoints, prints and logs in NetSerialize within my struct FRepMovementAdv and functions that are called from NetSerialize. No chance getting anything to work, as you decribed already. Gues those functions are called from another thread? But does it realy matter what thread it executes on in terms of breakpoints?

avatar image Spiris Sep 12 '17 at 07:39 PM

This may sound weird, but have you tried TStructOpsTypeTraitsBase2 instead of TStructOpsTypeTraitsBase?

avatar image Rumbleball Sep 14 '17 at 09:07 PM

In my case I was missing it completely. Though it enough for the parent structure to have it. Thanks.

 template<>
 struct TStructOpsTypeTraits<FRepMovementAdv> : public TStructOpsTypeTraitsBase2<FRepMovementAdv>
 {
     enum
     {
         WithNetSerializer = true,
     };
 };
avatar image soulsource_ag Sep 20 '17 at 02:18 PM

Not certain if it's related to your problem, S0rn0, but you've forgotten the call to Super::GetLifetimeReplicatedProps(), what might cause all kinds of weird behaviour.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question