ULandscapeHeightfieldCollisionComponent::RenderComponent Missing

After loading the level “ULandscapeHeightfieldCollisionComponent::RenderComponent” gone after the code below.

void ULevel::FixupForPIE(int32 InPIEInstanceID, TFunctionRef<void(int32, FSoftObjectPath&)> InCustomFixupFunction)
{
	FPIEFixupSerializer FixupSerializer(this, InPIEInstanceID, InCustomFixupFunction);
	Serialize(FixupSerializer);
}

The code above is called in the code below, and it is called when the game is executed in the editor environment.

void UWorldPartitionLevelStreamingDynamic::FinalizeRuntimeLevel()
{
	// ...

	// For RuntimeLevel's world NetGUID to be valid, make sure to flag bIsNameStableForNetworking so that IsNameStableForNetworking() returns true. (see FNetGUIDCache::SupportsObject)
	UWorld* OuterWorld = RuntimeLevel->GetTypedOuter<UWorld>();
	OuterWorld->bIsNameStableForNetworking = true;

	if (StreamingCell.IsValid() && !StreamingCell->GetIsHLOD())
	{
		TRACE_CPUPROFILER_EVENT_SCOPE(FixupIDs);

		if (OuterWorld->IsPlayInEditor())
		{
			int32 PIEInstanceID = GetPackage()->GetPIEInstanceID();
			check(PIEInstanceID != INDEX_NONE);

			RuntimeLevel->FixupForPIE(PIEInstanceID, [&](int32 InPIEInstanceID, FSoftObjectPath& ObjectPath)
			{
				// Remap Runtime Level's SoftObjectPath before each PIE Fixup to avoid doing 2 passes of serialization
				OuterWorldPartition->RemapSoftObjectPath(ObjectPath);
			});
		}
		else if (OuterWorld->IsGameWorld())
		{
			check(IsRunningGame() || IsRunningDedicatedServer());
			// Remap Runtime Level's SoftObjectPaths
			FWorldPartitionLevelHelper::RemapLevelSoftObjectPaths(RuntimeLevel, OuterWorldPartition.Get());
		}
	}

	// ...
}

I’d like to know if this is the intended action.
This action is causing me problems.

I did’t know why it was broken.

if I Used Debug Edit , it passed check line.

below code is Fix remap.

it was fix. ( when I ran build client , it didn’t happen )

save asset and play

or

delete LandscapeProxy

I went deeper to find the cause of this problem.

And I’ve made it this far.

In ULevel::Serialize using FPIEFixupSerializer, none of the conditional statements in FLazyObjectPtr::PossiblySerializeObjectGuid are caught.
Even though the address of the pointer to ULandscapeHeightfieldCollisionComponent::RenderComponent changes when “ULevel::Serialize”.

LazyObjectPtr.cpp

void FLazyObjectPtr::PossiblySerializeObjectGuid(UObject *Object, FStructuredArchive::FRecord Record)
{
	FArchive& UnderlyingArchive = Record.GetUnderlyingArchive();

	if (UnderlyingArchive.IsSaving() || UnderlyingArchive.IsCountingMemory())
	{
		...
	}
	else if (UnderlyingArchive.IsLoading())
	{
		TOptional<FStructuredArchiveSlot> GuidSlot = Record.TryEnterField(SA_FIELD_NAME(TEXT("Guid")), false);
		if (GuidSlot.IsSet())
		{
			FUniqueObjectGuid Guid;
			GuidSlot.GetValue() << Guid;

			// Don't try and resolve GUIDs when loading a package for diffing
			const UPackage* Package = Object->GetOutermost();
			const bool bLoadedForDiff = Package->HasAnyPackageFlags(PKG_ForDiffing);
			if (!bLoadedForDiff && (!(UnderlyingArchive.GetPortFlags() & PPF_Duplicate) || (UnderlyingArchive.GetPortFlags() & PPF_DuplicateForPIE)))
			{
				check(!Guid.IsDefault());
				UObject* OtherObject = Guid.ResolveObject();
				if (OtherObject != Object) // on undo/redo, the object (potentially) already exists
				{
					const bool bDuplicate = OtherObject != nullptr;
					const bool bReassigning = FParse::Param(FCommandLine::Get(), TEXT("AssignNewMapGuids"));

					if (bDuplicate || bReassigning)
					{
						if (!bReassigning && OtherObject && OtherObject->HasAnyFlags(RF_NewerVersionExists))
						{
							GuidAnnotation.RemoveAnnotation(OtherObject);
							GuidAnnotation.AddAnnotation(Object, Guid);
						}
#if WITH_EDITOR
						else if (Object->GetOutermostObject()->GetPackage()->HasAnyPackageFlags(PKG_PlayInEditor))
						{
							Guid = RemapGuid(Guid, Object->GetOutermostObject()->GetPackage()->GetPIEInstanceID());
							GuidAnnotation.AddAnnotation(Object, Guid);
						}
#endif
						else
						{
							if (!bReassigning)
							{
								// Always warn for non-map packages, skip map packages in PIE or game
								const bool bInGame = FApp::IsGame() || Package->HasAnyPackageFlags(PKG_PlayInEditor);

								UE_CLOG(!Package->ContainsMap() || !bInGame, LogUObjectGlobals, Warning,
									TEXT("Guid referenced by %s is already used by %s, which should never happen in the editor but could happen at runtime with duplicate level loading or PIE"),
									*Object->GetFullName(), *OtherObject->GetFullName());
							}
							else
							{
								UE_LOG(LogUObjectGlobals, Warning, TEXT("Assigning new Guid to %s"), *Object->GetFullName());
							}
							// This guid is in use, which should never happen in the editor but could happen at runtime with duplicate level loading or PIE. If so give it an invalid GUID and don't add to the annotation map.
							Guid = FGuid();
						}
					}
					else
					{
						GuidAnnotation.AddAnnotation(Object, Guid);
					}
					FUniqueObjectGuid::InvalidateTag();
				}
			}
		}
	}
}

So, even if you “Get” LazyObjectPtr, ULandscapeHeightfieldCollisionComponent::RenderComponent, it does not find the correct object.

PersistentObjectPtr.h

/**
	 * Dereference the pointer, which may cause it to become valid again. Will not try to load pending outside of game thread
	 *
	 * @return nullptr if this object is gone or the pointer was null, otherwise a valid UObject pointer
	 */
	FORCEINLINE UObject* Get() const
	{
		UObject* Object = WeakPtr.Get();
		
		// Do a full resolve if the returned object is null and either we think we've loaded new objects, or the weak ptr may be stale
		if (!Object && ObjectID.IsValid() && (TObjectID::GetCurrentTag() != TagAtLastTest || !WeakPtr.IsExplicitlyNull()))
		{
			Object = ObjectID.ResolveObject();
			WeakPtr = Object;

			// Not safe to update tag during save as ResolveObject may have failed accidentally
			if (Object || !GIsSavingPackage)
			{
				TagAtLastTest = TObjectID::GetCurrentTag();
			}

			// If this object is pending kill or otherwise invalid, this will return nullptr as expected
			Object = WeakPtr.Get();
		}
		return Object;
	}

LazyObjectPtr.cpp

UObject* FUniqueObjectGuid::ResolveObject() const
{
	UObject* Result = GuidAnnotation.Find(*this);
	return Result;
}