This question was created in reference to: [ResavePackages fixredirects commandlet crashes Assertion failed: [Content removed]
Hey, resurrecting an old thread here, but can we get an update on when Child Actor Components and the resave commandlets will work together
We’ve got a few usages of child actor components where we want to dynamically populate visual only actors along with functional actors.
We have pick ups which use a generic blueprint type which just apply different GAS effects, and we want to be able to spawn in different visuals for those without re-creating the visual logic per pickup type.
We also have a character customization setup which spawns in a visual character actor as a child of our Pawn, that visual actor is responsible for constructing the visual based on various player customization choices (We’re looking to port this over to use Mutable potentially)
Having these however, means we can’t use the resave packages commandlet to do things like cleanup redirectors, re-serialize assets to avoid bloating our CoreRedirects, or bake lighting in our CI builds, as these all run through the resavepackages commandlet
I spent some time debugging and found that the problem was related to the Child Actors being part of the same external package than their Parent. This made it that the Parent’s external package was processed multiple times in the loop and causes the check to fire. The following code should help:
//Engine\Source\Editor\UnrealEd\Private\Commandlets\ContentCommandlets.cpp (line 1962-1977)
// Load and Save Level's external packages
if (!bResaveWorldPartitionExternalPackages && bAllowExternalPackageResaves)
{
// Use a default GC frequency for external actors if GarbageCollectionFrequency is 0.
TGuardValue<int32> ScopedGCFreq(GarbageCollectionFrequency, GarbageCollectionFrequency ? GarbageCollectionFrequency : DefaultExternalActorGCFreq);
World->AddToRoot();
//for (UPackage* Package : World->PersistentLevel->GetPackage()->GetExternalPackages())
//Bug Workaround: Make sure the list of packages contains unique entries to avoid resaving the same package multiple times. Child Actors (ChildActorComponent) are being saved in their Parent's external package which will cause the check to fail.
TSet<UPackage*> UniquePackages(World->PersistentLevel->GetPackage()->GetExternalPackages());
for (UPackage* Package : UniquePackages)
{
++TotalPackagesForResave;
const FString PackageFilename = Package->GetLoadedPath().GetLocalFullPath();
check(FLinkerLoad::FindExistingLinkerForPackage(Package));
LoadAndSaveOnePackage(PackageFilename);
}
World->RemoveFromRoot();
}
The alternative would be to run the commandlet with the -NoExternalPackages argument to avoid resaving external packages during the commandlet and manually resave the affected levels from the Content Browser.
The engine team fixed the source of the problem so that GetExternalPackage returns an array of unique entries. You can integrate CL#51227171 or GH Commit.