Description

Generated packages have to be constructed by the cooker via FGeneratorPackage::CreateGeneratedUPackage. Some fields on the UPackage are set and ICookPackageSplitter->PopulateGeneratedPackage is called to populate it.

But actors from the main map with references to objects in the generated package might convert those references to TObjectPtr and have the object deleted from under them during garbage collection, and then might try to reload the generated package from regular engine code when their map is saved, by calling LoadPackage. One example is UHoudiniInput::GetBounds() [HoudiniInput.cpp:428] which casts TObjectPtr LandscapeInputObjects[Idx] to a UObject* and thereby loads it.

LoadPackage will create the UPackage (without setting the proper fields) and then give an error that it failed to load because it does not exist on disk.

	LogGetPackageLinkerError(InExistingContext, InPackagePath, LOCTEXT("FileNotFoundShort", "Can't find file."), InOuter, LoadFlags);
	FText FullErrorMessage = FText::Format(LOCTEXT("FailedLoad", "Failed to load '{LoadingFile}': {ErrorMessage}"), Arguments);
Failed to load `%s`: Can't find file.

The cooker will then give an error later when it tries to create the package itself and then finds it already exists:

UE_LOG(LogCook, Error, TEXT("PackageSplitter found an existing copy of a package it was trying to populate;")

We need to change LoadPackage throughout the engine to call a delegate to allow the cooker to handle the loading of the package.

The way that most licensees encounter this problem is through HoudiniActors, which load the bounds of landscape objects, which can be in generated packages. The call to LoadPackage that causes the problem in that case comes from:

LoadPackage() [Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp:1983]
LoadPackage() [Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp:1960]
ResolveName() [Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp:1185]
StaticLoadObjectInternal() [Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp:1275]
StaticLoadObject() [Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp:1350]
FSoftObjectPath::TryLoad() [Engine\Source\Runtime\CoreUObject\Private\UObject\SoftObjectPath.cpp:536]
FSoftObjectPath::TryLoad() [Engine\Source\Runtime\CoreUObject\Private\UObject\SoftObjectPath.cpp:509]
FSoftObjectPtr::LoadSynchronous() [Engine\Source\Runtime\CoreUObject\Public\UObject\SoftObjectPtr.h:60]
UHoudiniInput::GetBounds() [Project\Plugins\HoudiniEngine\Source\HoudiniEngineRuntime\Private\HoudiniInput.cpp:428]
UHoudiniAssetComponent::GetAssetBounds() [Project\Plugins\HoudiniEngine\Source\HoudiniEngineRuntime\Private\HoudiniAssetComponent.cpp:2604]
UHoudiniAssetComponent::CalcBounds() [Project\Plugins\HoudiniEngine\Source\HoudiniEngineRuntime\Private\HoudiniAssetComponent.cpp:2559]
USceneComponent::UpdateBounds() [Engine\Source\Runtime\Engine\Private\Components\SceneComponent.cpp:1327]
UPrimitiveComponent::UpdateBounds() [Engine\Source\Runtime\Engine\Private\Components\PrimitiveComponent.cpp:3993]
USceneComponent::PropagateTransformUpdate() [Engine\Source\Runtime\Engine\Private\Components\SceneComponent.cpp:799]
USceneComponent::UpdateComponentToWorldWithParent() [Engine\Source\Runtime\Engine\Private\Components\SceneComponent.cpp:670]
USceneComponent::UpdateComponentToWorld() [Engine\Source\Runtime\Engine\Classes\Components\SceneComponent.h:922]
UActorComponent::OnRegister() [Engine\Source\Runtime\Engine\Private\Components\ActorComponent.cpp:1006]

The workaround that has worked for some licensees in that case is adding in UHoudiniInput::GetBounds, at the beginning of case EHoudiniInputType::Landscape, an early exit that returns an empty BoxBounds if (GIsCookerLoadingPackage). It would be nice to narrow it further to instead skip over just the CurInLandscape objects that have CurInLandscape->InputObject.GetLongPackageName().Contains(TEXT("Generated")), but no licensee has tried that yet.

Steps to Reproduce

Reported by licensee using houdini (see UDN link in Additional Info URL)

Have Comments or More Details?

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

39
Login to Vote

Unresolved
ComponentUE - Foundation - Core - Cooker
Affects Versions5.0
Target Fix5.5
CreatedMay 31, 2023
UpdatedFeb 29, 2024