I’m not sure how metadata gets added to a package, but if you start with an asset A whose package contains metadata (UPackage::MetaData) that is keyed off an asset B and then:
- Move B to location C, leaving behind a redirector
- Run the Update Redirector References action in the editor
- Delete the redirector
- Save all
- Validate A
You will get validation errors because A’s MetaData is not updated inside FAssetRenameManager::RenameReferencingSoftObjectPaths. I believe I have a patch that fixes this by adding the following code inside the loop over packages in that function.
FMetaData& packageMetadata = Package->GetMetaData();
TMap<FSoftObjectPath, TMap<FName, FString>> newMap;
for (TMap<FSoftObjectPath, TMap<FName, FString>>::TIterator It(packageMetadata.ObjectMetaDataMap); It; ++It)
{
FSoftObjectPath redirectedPath = GRedirectCollector.GetAssetPathRedirection(It.Key());
if (redirectedPath.IsValid())
{
newMap.FindOrAdd(redirectedPath).Append(It.Value());
}
else
{
// Check whether the base package has been redirected but the object is missing.
FString oldPackagePath = It.Key().GetLongPackageName();
// Construct the main object path by reusing the package name as the object name
FString reconstructedObjectPath = oldPackagePath + TEXT(".") + FPackageName::GetShortName(oldPackagePath);
FSoftObjectPath redirectedMainObjectPath = GRedirectCollector.GetAssetPathRedirection(reconstructedObjectPath);
if (redirectedMainObjectPath.IsValid())
{
FSoftObjectPath redirectedActualPath = redirectedMainObjectPath.GetLongPackageName() + TEXT(".") + It.Key().GetAssetName();
if (redirectedActualPath.ResolveObject() != nullptr)
{
redirectedActualPath.SetSubPathString(It.Key().GetSubPathString());
newMap.FindOrAdd(redirectedActualPath).Append(It.Value());
}
else
{
UE_LOG(LogAssetTools, Error,
TEXT("The package metadata in %s references a redirected asset %s whose package exist but object does not."),
*Package->GetPathName(), *It.Key().GetAssetPathString());
// Object doesn't exist in redirected package
}
}
else
{
// No redirector case
newMap.FindOrAdd(It.Key()).Append(It.Value());
}
}
}
Package->GetMetaData().ObjectMetaDataMap = newMap;
Does this seem correct? I’m wondering also if it should ever even be possible to have package metadata referring to another package? It seems like the purpose is to embed metadata for subobjects on the package, so I’m guessing that the way you get into this bad state is by copying an object on disk or by branching in p4 rather than going through the proper editor copy operations. Does that sound right?
[Attachment Removed]