Description

The Soft Object Path loading code has special case logic for loading from Play In Editor, which tries to remap paths from the editor version of a map to instead point to an actor in a specific client or server play in editor world. This code is not supposed to run when loading a Blueprint Class Default Object, because those should always point to the editor version of the actor.

Due to a combination of other changes in 5.4, if a blueprint is loaded using the repro steps above, it will incorrectly update the blueprint CDO to point to the PIE-specific actor, which corrupts the path and will cause it to no longer work if that blueprint is then saved. This only happens if ZenLoader is disabled (with -nozenloader if it has been enabled by default in 5.5 or later). Here is the stack and details from the repro where the soft object path loading code corrupts the path. The problem here is that the UWorld::Tick sets GPlayInEditorWorld to 0 (meaning the first PIE world), and it is still 0 when it calls ResolveObject, so it returns the PIE object instead of the editor version:

/Game/ThirdPerson/Maps/UEDPIE_0_ThirdPersonMap.ThirdPersonMap:PersistentLevel.LevelSequenceActor_UAID_107C613EB0F220FC01_1586595903
AssetPath
    PackageName "/Game/ThirdPerson/Maps/UEDPIE_0_ThirdPersonMap"  FName
    AssetName   "ThirdPersonMap"  FName
    SubPathString   L"PersistentLevel.LevelSequenceActor_UAID_107C613EB0F220FC01_1586595903"  FString
UnrealEditor-CoreUObject-Win64-Debug.dll!FSoftObjectPath::ResolveObjectInternal(const wchar_t * PathString) Line 595    C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FSoftObjectPath::ResolveObjectInternal() Line 590  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FSoftObjectPath::ResolveObject() Line 576  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FArchiveUObject::SerializeSoftObjectPtr(FArchive & Ar, FSoftObjectPtr & Value) Line 111    C++
UnrealEditor-Engine-Win64-Debug.dll!FArchiveUObject::operator<<(FSoftObjectPtr & Value) Line 31   C++
UnrealEditor-Core-Win64-Debug.dll!FBinaryArchiveFormatter::Serialize(FSoftObjectPtr & Value) Line 289   C++
UnrealEditor-Core-Win64-Debug.dll!FStructuredArchiveSlot::operator<<(FSoftObjectPtr & Value) Line 295 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FSoftObjectProperty::SerializeItem(FStructuredArchiveSlot Slot, void * Value, const void * Defaults) Line 96   C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FProperty::SerializeBinProperty(FStructuredArchiveSlot Slot, void * Data, int ArrayIdx) Line 428   C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UStruct::SerializeBin(FStructuredArchiveSlot Slot, void * Data) Line 1119  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UStruct::SerializeBin(FArchive & Ar, void * Data) Line 508 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FArchiveReplaceObjectRefBase::SerializeObject(UObject * ObjectToSerialize) Line 298    C++
UnrealEditor-Engine-Win64-Debug.dll!FArchiveReplaceObjectRef<UObject>::SerializeSearchObject() Line 233   C++
UnrealEditor-Engine-Win64-Debug.dll!FArchiveReplaceObjectRef<UObject>::FArchiveReplaceObjectRef<UObject>(UObject * InSearchObject, const TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0>> & InReplacementMap, EArchiveReplaceObjectFlags Flags) Line 195   C++
UnrealEditor-Engine-Win64-Debug.dll!UEngine::CopyPropertiesForUnrelatedObjects(UObject * OldObject, UObject * NewObject, UEngine::FCopyPropertiesForUnrelatedObjectsParams Params) Line 17415   C++
UnrealEditor-UnrealEd-Win64-Debug.dll!FBlueprintCompileReinstancer::CopyPropertiesForUnrelatedObjects(UObject * OldObject, UObject * NewObject, bool bClearExternalReferences, bool bForceDeltaSerialization, bool bOnlyHandleDirectSubObjects, TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0>> * OldToNewInstanceMap, const TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0>> * OldToNewClassMap) Line 3187  C++
UnrealEditor-Kismet-Win64-Debug.dll!FBlueprintCompilationManagerImpl::ReinstanceBatch(TArray<FReinstancingJob,TSizedDefaultAllocator<32>> & Reinstancers, TMap<UClass *,UClass *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,UClass *,0>> & InOutOldToNewClassMap, FUObjectSerializeContext * InLoadContext, TMap<UClass *,TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0>>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0>>,0>> * OldToNewTemplates) Line 2537   C++
UnrealEditor-Kismet-Win64-Debug.dll!FBlueprintCompilationManagerImpl::FlushCompilationQueueImpl(bool bSuppressBroadcastCompiled, TArray<UBlueprint *,TSizedDefaultAllocator<32>> * BlueprintsCompiled, TArray<UBlueprint *,TSizedDefaultAllocator<32>> * BlueprintsCompiledOrSkeletonCompiled, FUObjectSerializeContext * InLoadContext, TMap<UClass *,TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0>>,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UClass *,TMap<UObject *,UObject *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<UObject *,UObject *,0>>,0>> * OldToNewTemplates) Line 1597 C++
UnrealEditor-Kismet-Win64-Debug.dll!FBlueprintCompilationManager::FlushCompilationQueue(FUObjectSerializeContext * InLoadContext) Line 3696 C++
UnrealEditor-Engine-Win64-Debug.dll!UBlueprintGeneratedClass::ConditionalRecompileClass(FUObjectSerializeContext * InLoadContext) Line 697  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FScopedClassDependencyGather::~FScopedClassDependencyGather() Line 489 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FLinkerLoad::CreateExport(int Index) Line 5615 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FLinkerLoad::CreateExportAndPreload(int ExportIndex, bool bForcePreload) Line 4014 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FLinkerLoad::LoadAllObjects(bool bForcePreload) Line 4240  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!LoadPackageInternal(UPackage * InOuter, const FPackagePath & PackagePath, unsigned int LoadFlags, FLinkerLoad * ImportLinker, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext, const FPackagePath * DiffPackagePath) Line 1892 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!LoadPackage(UPackage * InOuter, const FPackagePath & PackagePath, unsigned int LoadFlags, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext, const FPackagePath * DiffPackagePath) Line 2068 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!LoadPackage(UPackage * InOuter, const wchar_t * InLongPackageNameOrFilename, unsigned int LoadFlags, FArchive * InReaderOverride, const FLinkerInstancingContext * InstancingContext) Line 2044    C++
UnrealEditor-CoreUObject-Win64-Debug.dll!ResolveName(UObject * & InPackage, FString & InOutName, bool Create, bool Throw, unsigned int LoadFlags, const FLinkerInstancingContext * InstancingContext) Line 1246 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!StaticLoadObjectInternal(UClass * ObjectClass, UObject * InOuter, const wchar_t * InName, const wchar_t * Filename, unsigned int LoadFlags, UPackageMap * Sandbox, bool bAllowObjectReconciliation, const FLinkerInstancingContext * InstancingContext) Line 1356  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!StaticLoadObject(UClass * ObjectClass, UObject * InOuter, const wchar_t * InName, const wchar_t * Filename, unsigned int LoadFlags, UPackageMap * Sandbox, bool bAllowObjectReconciliation, const FLinkerInstancingContext * InstancingContext) Line 1430  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FSoftObjectPath::TryLoad(FUObjectSerializeContext * InLoadContext) Line 538    C++
UnrealEditor-Engine-Win64-Debug.dll!FSoftObjectPtr::LoadSynchronous() Line 60   C++
UnrealEditor-Engine-Win64-Debug.dll!TSoftClassPtr<UObject>::LoadSynchronous() Line 652    C++
UnrealEditor-Engine-Win64-Debug.dll!UKismetSystemLibrary::LoadClassAsset_Blocking(TSoftClassPtr<UObject> AssetClass) Line 1430    C++
UnrealEditor-Engine-Win64-Debug.dll!UKismetSystemLibrary::execLoadClassAsset_Blocking(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 14119   C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UObject::execCallMathFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1075   C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FFrame::Step(UObject * Context, void * const Z_Param__Result) Line 479 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UObject::execLetObj(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 2876 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!FFrame::Step(UObject * Context, void * const Z_Param__Result) Line 479 C++
UnrealEditor-CoreUObject-Win64-Debug.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1234  C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UObject::ProcessInternal(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1304    C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 6847   C++
UnrealEditor-CoreUObject-Win64-Debug.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Line 2144    C++
UnrealEditor-Engine-Win64-Debug.dll!AActor::ProcessEvent(UFunction * Function, void * Parameters) Line 1092 C++
UnrealEditor-Engine-Win64-Debug.dll!FLatentActionManager::TickLatentActionForObject(float DeltaTime, TMultiMap<int,FPendingLatentAction *,FDefaultSetAllocator,TDefaultMapHashableKeyFuncs<int,FPendingLatentAction *,1>> & ObjectActionList, UObject * InObject) Line 332  C++
UnrealEditor-Engine-Win64-Debug.dll!FLatentActionManager::ProcessLatentActions(UObject * InObject, float DeltaTime) Line 236    C++
UnrealEditor-Engine-Win64-Debug.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1544 C++
UnrealEditor-UnrealEd-Win64-Debug.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 2015 C++
UnrealEditor-UnrealEd-Win64-Debug.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 550    C++
UnrealEditor-Win64-Debug.exe!FEngineLoop::Tick() Line 5921  C++
UnrealEditor-Win64-Debug.exe!EngineTick() Line 62   C++
UnrealEditor-Win64-Debug.exe!GuardedMain(const wchar_t * CmdLine) Line 183  C++
UnrealEditor-Win64-Debug.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 247  C++
UnrealEditor-Win64-Debug.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 298    C++
Steps to Reproduce

From user report:

  • Create a new ThirdPerson Game project
  • Add a LevelSequenceActor to the Level
  • Create a new Actor Blueprint
    • Add new variable to Actor Blueprint - Level Sequence Actor Soft Object Reference
    • Reference LevelSequenceActor in Level
  • In the Level Blueprint
    • Add Soft Class Pointer to Actor Blueprint
    • From Begin Play
      • Load Class Asset Blocking
      • Cast to Actor Class
      • Spawn Actor
  • Run PIE
  • Stop PIE
  • Open Actor Blueprint
  • Notice Soft Object Reference is wrong

To repro this on 5.5, you will need to disable zenloader with -nozenloader

Have Comments or More Details?

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

0
Login to Vote

Fixed
ComponentUE - Foundation - Core - EditorLoader
Affects Versions5.45.5
Target Fix5.4.35.5
Fix Commit34382676
CreatedJun 13, 2024
ResolvedJun 14, 2024
UpdatedJun 22, 2024
View Jira Issue