Description

The rules for delta serialization in UE4 are complicated, and the editor tries to hide them from you, which works 90% of the time but can lead to confusion and data loss in other situations. In the repro above, there is a parent blueprint with a single variable struct, and an array of the same struct (FEngineTestNativeSubStruct). The child blueprint modifies a single variable inside both the single struct and the first array struct. But when the child blueprint is saved, it only saves out the modified variable in the single struct, but saves the entire array including values that are the same as the parent. This means the single struct still mostly inherits changes from the parent, but the array is completely disconnected from any changes the parent would get. This causes the behavior seen in step 6, and is a very old engine decision dating back at least 10 years.

To compensate for this, when making changes to arrays inside the parent the editor tries to modify any child blueprints (and actor instances) it knows about, but this only works if they are open. It does not tell the user it is doing this, but does mark the child bps and levels as dirty. In the UI the behavior looks identical between arrays and single structs, but because of the delta save behavior this is a lie. This leads to very confusing behavior for end users when they modify arrays inside parent blueprints, as changes appear to work most of the time, but will randomly fail. Maps and static arrays work like single structs, this is only an issue with TArray properties.

There are several possible fixes, one is to change it so TArrays do delta serialization like everything else in the engine, this would be the cleanest fix but could theoretically cause problems the opposite direction. Another option is to try and load the child BPs/instances, but this would be very expensive. A third option is to add some sort of notification or indication this is happening, such as a ! tooltip on array properties that are disconnected from their parents.

 

Steps to Reproduce
  1. Create an actor blueprint and add two Struct variables of the same type that have multiple values, I used Engine Test Native Sub Struct. Set one of them to be an Array and the other to be a single variable
  2. Add 3 elements to the array, and set the single variable all 3 array elements to unique values
  3. Create a child blueprint from the parent. Modify the first value inside the single struct and the first value inside the first array struct. 
  4. Save both blueprints and reload the editor. Be careful to not load the child blueprint
  5. Open up the parent struct, modify the second value inside the single struct, and the second value inside the first array struct. Save blueprint
  6. Load the child blueprint, notice that second variable inside the single struct will be updated to match the parent, but the second variable on the first array struct will NOT and will now have the yellow revert icon
  7. While child BP is open, modify the second value on the second array struct. This time the change will be reflected in the child, and it will be marked dirty
  8. To summarize, changes to single variable structs will apply to child blueprints in all cases, but changes to array structs will only apply if the child struct happens to be loaded in the editor when the change is made 

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-96195 in the post.

16
Login to Vote

Backlogged
ComponentUE - Foundation - Core
Affects Versions4.26
CreatedJul 30, 2020
UpdatedNov 27, 2023