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.