In HLODBuilder.cpp, the base class UHLODBuilder::Build(const FHLODBuildContext&) at line 324 separates components based on their HLODBatchingPolicy:
if (!ShouldIgnoreBatchingPolicy())
{
for (UActorComponent* SourceComponent : InHLODBuildContext.SourceComponents)
{
if (ShouldBatchComponent(SourceComponent))
{
ComponentsToBatch.Add(SourceComponent);
}
else
{
InputComponents.Add(SourceComponent);
}
}
}
Components in ComponentsToBatch are processed by BatchInstances() at line 406, bypassing the derived builder entirely:
if (!ComponentsToBatch.IsEmpty())
{
BuildResult.HLODComponents.Append(BatchInstances(ComponentsToBatch));
}
The problem is that UHLODInstancedStaticMeshComponent (created by first-level HLODs) sets HLODBatchingPolicy = EHLODBatchingPolicy::Instancing in its constructor (HLODInstancedStaticMeshComponent.cpp:45).
When the second-level HLOD builds using MeshApproximate:
1. Source components are UHLODInstancedStaticMeshComponent from level 0
2. These have HLODBatchingPolicy::Instancing
3. ShouldIgnoreBatchingPolicy() returns false (default)
4. All components go to ComponentsToBatch
5. BatchInstances() processes them, producing instances
6. UHLODBuilderMeshApproximate::Build() is never called
UHLODBuilderInstancing already overrides ShouldIgnoreBatchingPolicy() to return true (HLODBuilderInstancing.h:69), but MeshApproximate, MeshMerge, and MeshSimplify do not.
[Attachment Removed]