Description

When using ComplexCollisionMesh of StaticMesh asset, at the time of hit, the physical material refers to the material of the drawing mesh side using the material index of the collision mesh side.
Therefore, if the number of materials of the drawing mesh is less than the number of materials of the collision mesh, it will crash when hit.

Below is the modified code from Licensee. Confirmed that reflecting this will avoid crash.

void FBodyInstance::GetComplexPhysicalMaterials(const FBodyInstance*, TWeakObjectPtr<UPrimitiveComponent> OwnerComp, TArray<UPhysicalMaterial*>& OutPhysicalMaterials)
{
if(!GEngine || !GEngine->DefaultPhysMaterial)
{
UE_LOG(LogPhysics, Error, TEXT("FBodyInstance::GetComplexPhysicalMaterials : GEngine not initialized! Cannot call this during native CDO construction, wrap with if(!HasAnyFlags(RF_ClassDefaultObject)) or move out of constructor, material parameters will not be correct."));

return;
}

// See if the Material has a PhysicalMaterial
UPrimitiveComponent* PrimComp = OwnerComp.Get();
if (PrimComp)
{
UStaticMeshComponent* StatComp = Cast<UStaticMeshComponent>(PrimComp);
if(StatComp && StatComp->GetStaticMesh() && StatComp->GetStaticMesh()->ComplexCollisionMesh)
{
UStaticMesh* Mesh = StatComp->GetStaticMesh()->ComplexCollisionMesh;

const int32 NumMaterials = Mesh->StaticMaterials.Num();
OutPhysicalMaterials.SetNum(NumMaterials);

for (int32 MatIdx = 0; MatIdx < NumMaterials; MatIdx++)
{
UPhysicalMaterial* PhysMat = GEngine->DefaultPhysMaterial;
UMaterialInterface* Material = Mesh->GetMaterial(MatIdx);
if (Material)
{
PhysMat = Material->GetPhysicalMaterial();
}

check(PhysMat != NULL);
OutPhysicalMaterials[MatIdx] = PhysMat;
}
}
else
{
const int32 NumMaterials = PrimComp->GetNumMaterials();
OutPhysicalMaterials.SetNum(NumMaterials);

for (int32 MatIdx = 0; MatIdx < NumMaterials; MatIdx++)
{
UPhysicalMaterial* PhysMat = GEngine->DefaultPhysMaterial;
UMaterialInterface* Material = PrimComp->GetMaterial(MatIdx);
if (Material)
{
PhysMat = Material->GetPhysicalMaterial();
}

check(PhysMat != NULL);
OutPhysicalMaterials[MatIdx] = PhysMat;
}
}
}
}

 
 

Steps to Reproduce
  1. Open attached project
  2. Move BP_LineTrace in Level to left 
  3. Crash

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-89830 in the post.

3
Login to Vote

Won't Fix
ComponentUE - Simulation - Physics
Affects Versions4.234.24
CreatedMar 2, 2020
ResolvedJul 19, 2022
UpdatedJul 19, 2022