Summary
We have quite complex variant sets, some include variants that modify actors from levels that might not be currently streamed. When we switch on these variants during a PIE or viewport session, the original level gets flagged as dirty. This seems to occur because SwitchOnVariantByName calls UVariantObjectBinding::GetObject(). Because the unstreamed PIE actors do not exist in memory yet, the standard path resolution fails, causing the function to fall back to a LazyObjectPtr lookup. The LazyObjectPtr then resolves to the permanent editor-world instance instead of the temporary PIE duplicate, and inadvertently dirties the level via the Variant Manager’s underlying Modify() calls.
What Type of Bug are you experiencing?
Editor
Steps to Reproduce
We have not been able to reproduce this issue in a clean project, something else other than the actors being in unstreamed levels is in play, but we have not been able to locate the cause. We cannot afford to alocate more time to this issue, we have implemented an engine fix that solves this problem by adding the following code to UVariantObjectBinding::GetObject()
{
UObject* LazyObject = LazyObjectPtr.Get();
if (LazyObject)
{
// Don't fall back to editor-world objects during PIE
auto objPackage = LazyObject->GetPackage();
if (PIEInstanceID != INDEX_NONE && objPackage && !objPackage->HasAnyPackageFlags(PKG_PlayInEditor))
{
return nullptr; // level not streamed in yet, don't touch editor world
}
ObjectPtr = LazyObject;
return LazyObject;
}
}
Expected Result
The original level is now marked as dirty, prompting the “Save changes” dialog when closing the editor, even though no editor changes were made.
Observed Result
Switching a variant on during PIE should only modify the temporary UEDPIE_0_ instances, leaving the original level completely untouched and clean.
Affects Versions
5.3
Platform(s)
Windows
Additional Notes
Affected versions are likely 5.3 and above as no changes have been made to this part of the code since 5.3