UStaticMesh* URuntimeAssets::CreateStaticMeshAtRuntime(UObject* Owner, const FName Name,
const FMeshDescription& MeshDescription,
UMaterialInterface* Material)
{
/******** InterchangeStaticMeshFactory.cpp *********/
// NewObject is not thread safe, the asset registry directory watcher tick on the main thread can trig before we finish initializing the UObject and will crash
// The UObject should have been created by calling CreateEmptyAsset on the main thread.
// Build static mesh
UStaticMesh* StaticMesh = NewObject<UStaticMesh>(Owner, Name, RF_Public | RF_Standalone);
StaticMesh->bAllowCPUAccess = true;
TArray<const FMeshDescription*> MeshDescriptions;
MeshDescriptions.Emplace(&MeshDescription);
UStaticMesh::FBuildMeshDescriptionsParams BuildMeshDescriptionsParams;
BuildMeshDescriptionsParams.bUseHashAsGuid = true;
// Do not mark the package dirty since MarkPackageDirty is not thread safe
BuildMeshDescriptionsParams.bMarkPackageDirty = false;
BuildMeshDescriptionsParams.bBuildSimpleCollision = false;
// Do not commit since we only need the render data and commit is slow
BuildMeshDescriptionsParams.bCommitMeshDescription = false;
BuildMeshDescriptionsParams.bFastBuild = true;
StaticMesh->BuildFromMeshDescriptions(MeshDescriptions, BuildMeshDescriptionsParams);
StaticMesh->GetStaticMaterials().Add(FStaticMaterial());
StaticMesh->GetStaticMaterials()[0].MaterialInterface = Material;
StaticMesh->GetStaticMaterials()[0].MaterialSlotName = Name;
StaticMesh->GetStaticMaterials()[0].UVChannelData = FMeshUVChannelInfo(1.f);
StaticMesh->bSupportRayTracing = true;
StaticMesh->bGenerateMeshDistanceField = true;
StaticMesh->GetBodySetup()->CollisionTraceFlag = CTF_UseComplexAsSimple;
StaticMesh->GetBodySetup()->CreatePhysicsMeshes();
FStaticMeshLODResourcesArray& LODResources = StaticMesh->GetRenderData()->LODResources;
if (LODResources.Num() > 0)
{
FStaticMeshSectionArray& Sections = LODResources[0].Sections;
if (Sections.Num() > 0)
{
Sections[0].MaterialIndex = 0;
}
}
StaticMesh->Modify();
return StaticMesh;
}