We found that when we use multiprocess cook, the NiagaraDataInterface property would have non-deterministic Cook result if the outer BlueprintClass is inherited from another BlueprintClass.
Let’s consider the following BlueprintClass and it’s NSComponent containing a NiagaraDataInterface property.
[Image Removed]
The cook result of B_BP_C is different whether the A_BP_C is cooked in the same cook worker. I dived into the cook process and find that this is because of the new NiagaraDataInterface instance generated in the cook process.
void UNiagaraComponent::CopyParametersFromAsset(bool bResetExistingOverrideParameters)
{
// DataInterfaces are unique per component so we need to make new instances if they are not already
for (int32 i = 0; i < AssetExposedParameters.GetDataInterfaces().Num(); ++i)
{
UNiagaraDataInterface* AssetDataInterface = AssetExposedParameters.GetDataInterface(i);
UNiagaraDataInterface* OverrideDataInterface = OverrideParameters.GetDataInterface(i);
if (AssetDataInterface != OverrideDataInterface)
{
// We must copy the data regardless as there is an expectation that data interfaces are always reset to the original state
AssetDataInterface->CopyTo(OverrideDataInterface);
}
else if(AssetDataInterface)
{
OverrideDataInterface = NewObject<UNiagaraDataInterface>(this, AssetDataInterface->GetClass(), NAME_None, RF_Transactional | RF_Public);
AssetDataInterface->CopyTo(OverrideDataInterface);
OverrideParameters.SetDataInterface(OverrideDataInterface, i);
}
}
}
Consider the two senarios when cooking WaterMesh in B_BP_C.
- WHen the A_BP_C is cooked in the same worker. The A_BP_C is generated the new waterMesh called waterMesh_1. When the generated waterMesh_1 of B_BP_C is serialized for cook, it compares to the archetype which is the waterMesh_1 of A_BP_C having loaded and the values are the same.
- When the A_BP_C is cooked in another cook worker, the DiffObject of the generated waterMesh instance (we called waterMesh_1) is the CDO, because the A_BP_C didn’t generate a new object called waterMesh_1, which leads the DefaultMesh to be compared is NULL.
My Questions are:
- Why the NiagaraDataInterface instances need to be genrated dynamically when cooking. The A_BP_C and B_BP_C should be deterministic after they are edited and saved. Why not just serialized the NiagaraDataInterface instances to the disk?
- Given the current situation, is there anyway to workaround this non-deterministic issue?