Procedural Mesh Falls Through the Floor Despite Physics and Collision Settings

I’m working on generating a procedural mesh from a skeletal mesh at runtime and have hit a bit of a roadblock. I’m using UProceduralMeshComponent to create the mesh, and while everything appears to be set up correctly (gravity is enabled, physics is simulated, and collision settings seem fine), the mesh keeps falling through the floor.
Here’s the code:

UProceduralMeshComponent* USlicableCharacterComponent::GenerateProceduralMeshFromSkeleton(USkeletalMeshComponent* SkeletalMesh)
{
if (!SkeletalMesh)
{
UE_LOG(LogTemp, Error, TEXT(“SkeletalMesh is null!”));
return nullptr;
}

UProceduralMeshComponent* ProcMeshComponent = NewObject<UProceduralMeshComponent>(this, UProceduralMeshComponent::StaticClass(), TEXT("ProceduralMeshComponent"));

if (AActor* Owner = GetOwner())
{
    UCapsuleComponent* CapsuleComponent = Owner->FindComponentByClass<UCapsuleComponent>();
    if (CapsuleComponent)
    {
        ProcMeshComponent->AttachToComponent(CapsuleComponent, FAttachmentTransformRules::KeepRelativeTransform);
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Capsule not found!"));
    }
}


ProcMeshComponent->RegisterComponent();

ProcMeshComponent->bUseComplexAsSimpleCollision = false;

ProcMeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
ProcMeshComponent->SetSimulatePhysics(true);
ProcMeshComponent->SetEnableGravity(true);

ProcMeshComponent->SetCollisionObjectType(ECC_PhysicsBody);
ProcMeshComponent->SetCollisionResponseToAllChannels(ECR_Block);
ProcMeshComponent->SetCollisionResponseToChannel(ECC_Pawn, ECR_Ignore);



ProcMeshComponent->SetWorldTransform(SkeletalMesh->GetComponentTransform());


ConvertSkeletalMeshToProceduralMesh(SkeletalMesh, 0, ProcMeshComponent);

return ProcMeshComponent;

}

USlicableCharacterComponent::USlicableCharacterComponent()
{
}

void USlicableCharacterComponent::ConvertSkeletalMeshToProceduralMesh(
USkeletalMeshComponent* InSkeletalMeshComponent, int32 LODIndex, UProceduralMeshComponent* InProcMeshComponent)
{
FSkeletalMeshRenderData* SkMeshRenderData = InSkeletalMeshComponent->GetSkeletalMeshRenderData();
const FSkeletalMeshLODRenderData& DataArray = SkMeshRenderData->LODRenderData[LODIndex];
FSkinWeightVertexBuffer& SkinWeights = *InSkeletalMeshComponent->GetSkinWeightBuffer(LODIndex);

TArray<FVector> VerticesArray;
TArray<FVector> Normals;
TArray<FVector2D> UV;
TArray<FColor> Colors;
TArray<FProcMeshTangent> Tangents;

for (int32 j = 0; j < DataArray.RenderSections.Num(); j++)
{
    // Get number of vertices and offset
    const int32 NumSourceVertices = DataArray.RenderSections[j].NumVertices;
    const int32 BaseVertexIndex = DataArray.RenderSections[j].BaseVertexIndex;

    for (int32 i = 0; i < NumSourceVertices; i++)
    {
        const int32 VertexIndex = i + BaseVertexIndex;

        // Get skinned vertex position
        const FVector3f SkinnedVectorPos = USkeletalMeshComponent::GetSkinnedVertexPosition(
            InSkeletalMeshComponent, VertexIndex, DataArray, SkinWeights);
        FVector VertexPosition(SkinnedVectorPos.X, SkinnedVectorPos.Y, SkinnedVectorPos.Z);
        VerticesArray.Add(VertexPosition);

        // Calc normals and tangents
        const FVector3f ZTangentStatic = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.VertexTangentZ(
            VertexIndex);
        const FVector3f XTangentStatic = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.VertexTangentX(
            VertexIndex);

        Normals.Add(FVector(ZTangentStatic.X, ZTangentStatic.Y, ZTangentStatic.Z));
        Tangents.Add(FProcMeshTangent(FVector(XTangentStatic.X, XTangentStatic.Y, XTangentStatic.Z), false));

        // Get UVs
        const FVector2f SourceUVs = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.GetVertexUV(VertexIndex, 0);
        FVector2D ResUVs(SourceUVs.X, SourceUVs.Y);
        UV.Add(ResUVs);

        // Dummy vertex colors
        Colors.Add(FColor(0, 0, 0, 255));
    }
}

// Get index buffer
FMultiSizeIndexContainerData IndicesData;
DataArray.MultiSizeIndexContainer.GetIndexBuffer(IndicesData.Indices);

for (int32 j = 0; j < DataArray.RenderSections.Num(); j++)
{
    TArray<int32> Tris;

    // Get number of triangles and offset
    const int32 SectionNumTriangles = DataArray.RenderSections[j].NumTriangles;
    const int32 SectionBaseIndex = DataArray.RenderSections[j].BaseIndex;

    // Iterate over indices and add triangles
    for (int32 i = 0; i < SectionNumTriangles; i++)
    {
        int32 TriVertexIndex = i * 3 + SectionBaseIndex;
        Tris.Add(IndicesData.Indices[TriVertexIndex]);
        Tris.Add(IndicesData.Indices[TriVertexIndex + 1]);
        Tris.Add(IndicesData.Indices[TriVertexIndex + 2]);
    }

    // Create the procedural mesh section
    InProcMeshComponent->CreateMeshSection(j, VerticesArray, Tris, Normals, UV, Colors, Tangents, true);

    InProcMeshComponent->ContainsPhysicsTriMeshData(true);
    InProcMeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);

}

}

I’ve been stuck on this for days now, and honestly, it’s getting really frustrating. I’ve tried everything I can think of. IDK what to do at this point!..
Thanks in advance for your help.