- Vrealmatic
- Unreal Engine Wiki
- Static Mesh
Working with Static Mesh in Unreal Engine
What is it Static Mesh, what properties does it have and how to work with it in the Unreal Engine?

Static Meshes
Static Mesh assets are the basic unit used to create world geometry for levels. These 3D models are created in external modeling applications (such as 3dsMax, Maya, Blender, and so on) that are imported into the Unreal Editor through the Content Browser. The vast majority of any level made with Unreal Engine will consist of Static Meshes, generally in the form of Static Mesh Actors.
Instanced Static Mesh
Import Static Mesh - .fbx file
#include "Kismet/BlueprintFunctionLibrary.h" // Engine, <mark>Editor only</mark>
/**
* Editor Only - Will not work in packaged build.
*
* Create and process a StaticMesh import task.
*
* @param SourcePath The path of the source file: "C:/Temp/MyStaticMesh.fbx"
* @param DestinationPath The path of the imported asset: "/Game/Folder/MyStaticMesh"
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*
* @return The imported StaticMesh
*/
UFUNCTION(BlueprintCallable, Category = "")
<strong>static class UStaticMesh* ImportStaticMesh(FString SourcePath, FString DestinationPath, bool& bOutSuccess, FString& OutInfoMsg);</strong>
.cpp file#include "Factories/FbxImportUI.h" // <mark>UnrealEd (Editor Only)</mark>
#include "Factories/FbxStaticMeshImportData.h" // <mark>UnrealEd (Editor Only)</mark>
UStaticMesh* UExampleClass::ImportStaticMesh(FString SourcePath, FString DestinationPath, bool& bOutSuccess, FString& OutInfoMsg)
{
<mark><a href="https://docs.unrealengine.com/5.2/en-US/API/Editor/UnrealEd/Factories/UFbxImportUI/" target="_blank">UFbxImportUI</a>* Options</mark> = NewObject<UFbxImportUI>();
// Required options to specify that we're importing a static mesh
Options->bAutomatedImportShouldDetectType = false;
Options->MeshTypeToImport = <mark>EFBXImportType::FBXIT_StaticMesh</mark>;
Options->bImportMesh = true;
// No skeletal mesh or animations
Options->bImportAsSkeletal = <mark>false</mark>;
Options->bImportAnimations = false;
Options->bCreatePhysicsAsset = false;
// More options
Options->bImportTextures = true;
Options->bImportMaterials = true;
Options->bResetToFbxOnMaterialConflict = true;
Options->LodNumber = 0;
// UFbxAssetImportData
Options->StaticMeshImportData->ImportTranslation = FVector(0.0f);
Options->StaticMeshImportData->ImportRotation = FRotator(0.0f);
Options->StaticMeshImportData->ImportUniformScale = 1.0f;
Options->StaticMeshImportData->bConvertScene = true;
Options->StaticMeshImportData->bForceFrontXAxis = true;
Options->StaticMeshImportData->bConvertSceneUnit = true;
// UFbxMeshImportData
Options->StaticMeshImportData->bTransformVertexToAbsolute = false;
Options->StaticMeshImportData->bBakePivotInVertex = false;
Options->StaticMeshImportData->bImportMeshLODs = true;
Options->StaticMeshImportData->NormalImportMethod = EFBXNormalImportMethod::FBXNIM_ComputeNormals;
Options->StaticMeshImportData->NormalGenerationMethod = EFBXNormalGenerationMethod::BuiltIn;
Options->StaticMeshImportData->bComputeWeightedNormals = true;
Options->StaticMeshImportData->bReorderMaterialToFbxOrder = false;
// UFbxStaticMeshImportData
Options->StaticMeshImportData->StaticMeshLODGroup = FName();
Options->StaticMeshImportData->VertexColorImportOption = EVertexColorImportOption::Replace;
Options->StaticMeshImportData->bRemoveDegenerates = true;
Options->StaticMeshImportData->bBuildReversedIndexBuffer = true;
Options->StaticMeshImportData->bBuildNanite = true;
Options->StaticMeshImportData->bGenerateLightmapUVs = true;
Options->StaticMeshImportData->bOneConvexHullPerUCX = true;
Options->StaticMeshImportData->bAutoGenerateCollision = true;
Options->StaticMeshImportData->bCombineMeshes = true;
Options->StaticMeshImportData->DistanceFieldResolutionScale = 0.0f;
// Create the import task
UAssetImportTask* Task = <a href="/unreal-engine/import-assets#CreateImportTask">UExampleClass::CreateImportTask</a>(SourcePath, DestinationPath, nullptr, <strong>Options</strong>, bOutSuccess, OutInfoMsg);
if (!bOutSuccess) return nullptr;
// Import the asset
UStaticMesh* RetAsset = Cast<UStaticMesh>(<a href="#ProcessImportTask">UExampleClass::ProcessImportTask</a>(Task, bOutSuccess, OutInfoMsg));
if (!bOutSuccess) return nullptr;
// Return the imported asset
bOutSuccess = true;
OutInfoMsg = FString::Printf(TEXT("Import Static Mesh Succeeded - '%s'"), *DestinationPath);
return RetAsset;
}Assign material for Static Mesh
Generate Static Mesh Collisions With C++
Auto generate a convex collision for a static mesh
.h
#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
* <strong>Editor Only</strong> - Will not work in packaged build.
*
* <mark>Auto generate a convex collision for a static mesh.</mark>
*
* @param StaticMesh Static mesh to add convex collision on.
* @param HullCount Maximum number of convex pieces that will be created. Must be positive.
* @param MaxHullVerts Maximum number of vertices allowed for any generated convex hull.
* @param HullPrecision Number of voxels to use when generating collision. Must be positive.
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*/
UFUNCTION(BlueprintCallable, Category = "<a href="https://www.youtube.com/watch?v=gh1ScZaiBDM" target="_blank">Alex Quevillon - Generate Mesh Collisions</a>")
<strong>static void AutoGenetateStaticMeshCollisions(class UStaticMesh* StaticMesh, int HullCount, int MaxHullVerts, int HullPrecision, bool& bOutSuccess, FString& OutInfoMsg);</strong>.cpp
#include "UnrealEdGlobals.h" // UnrealEd (Editor Only)
#include "StaticMeshEditorSubsystem.h" // StaticMeshEditor (Editor Only)
void UExampleClass::AutoGenetateStaticMeshCollisions(UStaticMesh* StaticMesh, int HullCount, int MaxHullVerts, int HullPrecision, bool& bOutSuccess, FString& OutInfoMsg)
{
// Make sure static mesh is valid
if (StaticMesh == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Auto Genetate Static Mesh Collisions Failed - Static Mesh is not valid."));
return;
}
// Get Subsystem
UStaticMeshEditorSubsystem* StaticMeshEditorSubsystem = GEditor->GetEditorSubsystem<UStaticMeshEditorSubsystem>();
if (StaticMeshEditorSubsystem == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Auto Genetate Static Mesh Collisions Failed - StaticMeshEditorSubsystem is not valid."));
return;
}
bOutSuccess = StaticMeshEditorSubsystem->SetConvexDecompositionCollisions(StaticMesh, HullCount, MaxHullVerts, HullPrecision);
OutInfoMsg = FString::Printf(TEXT("Auto Genetate Static Mesh Collisions %s"), *FString(bOutSuccess ? "Succeeded" : "Failed"));
}.Build.cs
if (Target.bBuildEditor == true)
{
PrivateDependencyModuleNames.AddRange
(
new string[]
{
// Required Modules
<mark>"UnrealEd"</mark>,
<mark>"StaticMeshEditor"</mark>,
}
);
}Remove collisions from a static mesh
.h
#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
* <strong>Editor Only</strong> - Will not work in packaged build.
*
* <mark>Remove collisions from a static mesh.</mark>
*
* @param StaticMesh Static mesh to remove collisions from.
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*/
UFUNCTION(BlueprintCallable, Category = "<a href="https://www.youtube.com/watch?v=gh1ScZaiBDM" target="_blank">Alex Quevillon - Generate Mesh Collisions</a>")
<strong>static void ClearStaticMeshCollisions(class UStaticMesh* StaticMesh, bool& bOutSuccess, FString& OutInfoMsg);</strong>.cpp
#include "UnrealEdGlobals.h" // UnrealEd (Editor Only)
#include "StaticMeshEditorSubsystem.h" // StaticMeshEditor (Editor Only)
void UExampleClass::ClearStaticMeshCollisions(class UStaticMesh* StaticMesh, bool& bOutSuccess, FString& OutInfoMsg)
{
// Make sure static mesh is valid
if (StaticMesh == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Clear Static Mesh Collisions Failed - Static Mesh is not valid."));
return;
}
// Get Subsystem
UStaticMeshEditorSubsystem* StaticMeshEditorSubsystem = GEditor->GetEditorSubsystem<UStaticMeshEditorSubsystem>();
if (StaticMeshEditorSubsystem == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Clear Static Mesh Collisions Failed - StaticMeshEditorSubsystem is not valid."));
return;
}
bOutSuccess = StaticMeshEditorSubsystem->RemoveCollisions(StaticMesh);
OutInfoMsg = FString::Printf(TEXT("Clear Static Mesh Collisions %s"), *FString(bOutSuccess ? "Succeeded" : "Failed"));
}.Build.cs
if (Target.bBuildEditor == true)
{
PrivateDependencyModuleNames.AddRange
(
new string[]
{
// Required Modules
<mark>"UnrealEd"</mark>,
<mark>"StaticMeshEditor"</mark>,
}
);
}Add Box Collision To Static Mesh
.h
#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
* <strong>Editor Only</strong> - Will not work in packaged build.
*
* <mark>Add Box Collision To Static Mesh</mark>
*
* @param StaticMesh Static mesh to add box collision on
* @param CollisionIndex Index of the collision to update. If invalid, will create a new collision
* @param Location Location of the box collision
* @param Rotation Rotation of the box collision
* @param Extents Extents of the box collision
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*/
UFUNCTION(BlueprintCallable, Category = "<a href="https://www.youtube.com/watch?v=gh1ScZaiBDM" target="_blank">Alex Quevillon - Generate Mesh Collisions</a>")
<strong>static void AddOrUpdateBoxCollisionOnStaticMesh(UStaticMesh* StaticMesh, int CollisionIndex, FVector Location, FRotator Rotation, FVector Extents, bool& bOutSuccess, FString& OutInfoMsg);</strong>.cpp
#include "UnrealEdGlobals.h" // UnrealEd (Editor Only)
#include "StaticMeshEditorSubsystem.h" // StaticMeshEditor (Editor Only)
void UExampleClass::AddOrUpdateBoxCollisionOnStaticMesh(UStaticMesh* StaticMesh, int CollisionIndex, FVector Location, FRotator Rotation, FVector Extents, bool& bOutSuccess, FString& OutInfoMsg)
{
// Make sure static mesh is valid
if (StaticMesh == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Box Collision On StaticMesh Failed - Static Mesh is not valid."));
return;
}
// Index invalid, need to create new collision
if (CollisionIndex < 0 || CollisionIndex >= StaticMesh->GetBodySetup()->AggGeom.BoxElems.Num())
{
// Get Subsystem
UStaticMeshEditorSubsystem* StaticMeshEditorSubsystem = GEditor->GetEditorSubsystem<UStaticMeshEditorSubsystem>();
if (StaticMeshEditorSubsystem == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Box Collision On StaticMesh Failed - StaticMeshEditorSubsystem is not valid."));
return;
}
// Add Collision
CollisionIndex = StaticMeshEditorSubsystem->AddSimpleCollisions(StaticMesh, EScriptCollisionShapeType::Box);
if (CollisionIndex < 0)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Box Collision On StaticMesh Failed - Failed to add collision."));
return;
}
}
// Place the collision where you want
StaticMesh->GetBodySetup()->AggGeom.BoxElems[CollisionIndex].Center = Location;
StaticMesh->GetBodySetup()->AggGeom.BoxElems[CollisionIndex].Rotation = Rotation;
StaticMesh->GetBodySetup()->AggGeom.BoxElems[CollisionIndex].X = Extents.X;
StaticMesh->GetBodySetup()->AggGeom.BoxElems[CollisionIndex].Y = Extents.Y;
StaticMesh->GetBodySetup()->AggGeom.BoxElems[CollisionIndex].Z = Extents.Z;
bOutSuccess = true;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Box Collision On StaticMesh Succeeded"));
}.Build.cs
if (Target.bBuildEditor == true)
{
PrivateDependencyModuleNames.AddRange
(
new string[]
{
// Required Modules
<mark>"UnrealEd"</mark>,
<mark>"StaticMeshEditor"</mark>,
}
);
}Add Sphere Collision To Static Mesh
.h
#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
* <strong>Editor Only</strong> - Will not work in packaged build.
*
* <mark>Add Sphere Collision To Static Mesh</mark>
*
* @param StaticMesh Static mesh to add sphere collision on
* @param CollisionIndex Index of the collision to update. If invalid, will create a new collision
* @param Location Location of the sphere collision
* @param Radius Radius of the sphere collision
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*/
UFUNCTION(BlueprintCallable, Category = "<a href="https://www.youtube.com/watch?v=gh1ScZaiBDM" target="_blank">Alex Quevillon - Generate Mesh Collisions</a>")
<strong>static void AddOrUpdateSphereCollisionOnStaticMesh(class UStaticMesh* StaticMesh, int CollisionIndex, FVector Location, float Radius, bool& bOutSuccess, FString& OutInfoMsg);</strong>.cpp
#include "UnrealEdGlobals.h" // UnrealEd (Editor Only)
#include "StaticMeshEditorSubsystem.h" // StaticMeshEditor (Editor Only)
void UExampleClass::AddOrUpdateSphereCollisionOnStaticMesh(UStaticMesh* StaticMesh, int CollisionIndex,
FVector Location, float Radius, bool& bOutSuccess, FString& OutInfoMsg)
{
// Make sure static mesh is valid
if (StaticMesh == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Sphere Collision On StaticMesh Failed - Static Mesh is not valid."));
return;
}
// Index invalid, need to create new collision
if (CollisionIndex < 0 || CollisionIndex >= StaticMesh->GetBodySetup()->AggGeom.SphereElems.Num())
{
// Get Subsystem
UStaticMeshEditorSubsystem* StaticMeshEditorSubsystem = GEditor->GetEditorSubsystem<UStaticMeshEditorSubsystem>();
if (StaticMeshEditorSubsystem == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Sphere Collision On StaticMesh Failed - StaticMeshEditorSubsystem is not valid."));
return;
}
// Add Collision
CollisionIndex = StaticMeshEditorSubsystem->AddSimpleCollisions(StaticMesh, EScriptCollisionShapeType::Sphere);
if (CollisionIndex < 0)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Sphere Collision On StaticMesh Failed - Failed to add collision."));
return;
}
}
// Place the collision where you want
StaticMesh->GetBodySetup()->AggGeom.SphereElems[CollisionIndex].Center = Location;
StaticMesh->GetBodySetup()->AggGeom.SphereElems[CollisionIndex].Radius = Radius;
bOutSuccess = true;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Sphere Collision On StaticMesh Succeeded"));
}.Build.cs
if (Target.bBuildEditor == true)
{
PrivateDependencyModuleNames.AddRange
(
new string[]
{
// Required Modules
<mark>"UnrealEd"</mark>,
<mark>"StaticMeshEditor"</mark>,
}
);
}Add Capsule Collision To Static Mesh
.h
#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
* <strong>Editor Only</strong> - Will not work in packaged build.
*
* <mark>Add Capsule Collision To Static Mesh</mark>
*
* @param StaticMesh Static mesh to add capsule collision on
* @param CollisionIndex Index of the collision to update. If invalid, will create a new collision
* @param Location Location of the capsule collision
* @param Rotation Rotation of the capsule collision
* @param Length Length of the capsule collision
* @param Radius Radius of the capsule collision
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*/
UFUNCTION(BlueprintCallable, Category = "<a href="https://www.youtube.com/watch?v=gh1ScZaiBDM" target="_blank">Alex Quevillon - Generate Mesh Collisions</a>")
<strong>static void AddOrUpdateCapsuleCollisionOnStaticMesh(class UStaticMesh* StaticMesh, int CollisionIndex, FVector Location, FRotator Rotation, float Length, float Radius, bool& bOutSuccess, FString& OutInfoMsg);</strong>.cpp
#include "UnrealEdGlobals.h" // UnrealEd (Editor Only)
#include "StaticMeshEditorSubsystem.h" // StaticMeshEditor (Editor Only)
void UExampleClass::AddOrUpdateCapsuleCollisionOnStaticMesh(UStaticMesh* StaticMesh, int CollisionIndex, FVector Location, FRotator Rotation, float Length, float Radius, bool& bOutSuccess, FString& OutInfoMsg)
{
// Make sure static mesh is valid
if (StaticMesh == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Capsule Collision On StaticMesh Failed - Static Mesh is not valid."));
return;
}
// Index invalid, need to create new collision
if (CollisionIndex < 0 || CollisionIndex >= StaticMesh->GetBodySetup()->AggGeom.SphylElems.Num())
{
// Get Subsystem
UStaticMeshEditorSubsystem* StaticMeshEditorSubsystem = GEditor->GetEditorSubsystem<UStaticMeshEditorSubsystem>();
if (StaticMeshEditorSubsystem == nullptr)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Capsule Collision On StaticMesh Failed - StaticMeshEditorSubsystem is not valid."));
return;
}
// Add Collision
CollisionIndex = StaticMeshEditorSubsystem->AddSimpleCollisions(StaticMesh, EScriptCollisionShapeType::Capsule);
if (CollisionIndex < 0)
{
bOutSuccess = false;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Capsule Collision On StaticMesh Failed - Failed to add collision."));
return;
}
}
// Place the collision where you want
StaticMesh->GetBodySetup()->AggGeom.SphylElems[CollisionIndex].Center = Location;
StaticMesh->GetBodySetup()->AggGeom.SphylElems[CollisionIndex].Rotation = Rotation;
StaticMesh->GetBodySetup()->AggGeom.SphylElems[CollisionIndex].Length = Length;
StaticMesh->GetBodySetup()->AggGeom.SphylElems[CollisionIndex].Radius = Radius;
bOutSuccess = true;
OutInfoMsg = FString::Printf(TEXT("Add Or Update Capsule Collision On StaticMesh Succeeded"));
}.Build.cs
if (Target.bBuildEditor == true)
{
PrivateDependencyModuleNames.AddRange
(
new string[]
{
// Required Modules
<mark>"UnrealEd"</mark>,
<mark>"StaticMeshEditor"</mark>,
}
);
}

