Skip to content
PRODUCT GITHUB  ↗

RealtimeMesh Dynamic

URealtimeMeshDynamic owns a UDynamicMesh (an FDynamicMesh3) as its source of truth and, whenever that mesh changes, converts it to RMC streams — one section per material ID — for rendering and collision. It makes RMC a largely drop-in replacement for UDynamicMeshComponent, so if you already author geometry with the GeometryProcessing library or Geometry Scripting nodes, this is the type to use.

Header: Source/RealtimeMeshExt/Public/RealtimeMeshDynamic.h. This type lives in the RealtimeMeshExt module — see the build dependencies below.


URealtimeMeshDynamic is not in the core module. Add these to your module’s .Build.cs PrivateDependencyModuleNames (this is what the examples module uses):

"RealtimeMeshExt", // the Dynamic leaf itself
"GeometryCore", // UE::Geometry::FDynamicMesh3
"GeometryFramework", // UDynamicMesh

(Reference: Source/RealtimeMeshExamples/RealtimeMeshExamples.Build.cs.)


#include "RealtimeMeshDynamic.h"
#include "UDynamicMesh.h"
#include "DynamicMesh/DynamicMesh3.h"
using namespace UE::Geometry;
URealtimeMeshDynamic* RealtimeMesh = Component->InitializeRealtimeMesh<URealtimeMeshDynamic>();
// One material slot per triangle group (material ID) the converter will produce.
RealtimeMesh->SetNumMaterials(2);
// Move a FDynamicMesh3 in; SetMesh converts it and rebuilds the render data.
FDynamicMesh3 Mesh = BuildMyMesh();
RealtimeMesh->SetMesh(MoveTemp(Mesh));

In Blueprint, use the static InitializeRealtimeMeshDynamic(Owner) node.

The converter produces one section per triangle group / material ID, so enable triangle groups on your FDynamicMesh3 and size your material set to match. The ARealtimeMeshExample_Dynamic_Basic example (Source/RealtimeMeshExamples/Private/Dynamic/RealtimeMeshExample_Dynamic_Basic.cpp) hands a two-group grid to SetMesh.

  • SetMesh(FDynamicMesh3&& MoveMesh) — move-initialize the internal mesh from a FDynamicMesh3, then rebuild. (C++ only.)
  • SetDynamicMesh(UDynamicMesh* NewMesh) — replace the owned UDynamicMesh and take ownership of it. (Blueprint-callable.)
  • GetDynamicMesh() — returns the owned UDynamicMesh (created on demand), which you can then drive with Geometry Scripting nodes.

EditMesh hands you the internal FDynamicMesh3 to mutate, then updates render data according to the update mode:

RealtimeMesh->EditMesh([](FDynamicMesh3& Mesh)
{
for (const int32 Vid : Mesh.VertexIndicesItr())
{
FVector3d P = Mesh.GetVertex(Vid);
P.Z = /* ... */;
Mesh.SetVertex(Vid, P);
}
}, ERealtimeMeshDynamicRenderUpdateMode::FastUpdate);

ERealtimeMeshDynamicRenderUpdateMode mirrors EDynamicMeshComponentRenderUpdateMode:

  • NoUpdate — don’t touch render data.
  • FullUpdate — rebuild everything (use after topology / material / attribute-topology changes).
  • FastUpdate — update only vertex-attribute streams; falls back to a full rebuild if topology changed.

Animating with FastUpdate after an initial full build is what ARealtimeMeshExample_Dynamic_Edit (Source/RealtimeMeshExamples/Private/Dynamic/RealtimeMeshExample_Dynamic_Edit.cpp) does every tick.

  • ProcessMesh([](const FDynamicMesh3&){ ... }) reads the internal mesh under its lock.
  • GetMeshPtr() returns a raw FDynamicMesh3* (const and non-const), but prefer GetDynamicMesh() / EditMesh().
  • ApplyTransform(const FTransform&, bool bInvert) transforms positions and normals in place.

If you mutate the mesh through some other route (e.g. Geometry Scripting operating on GetDynamicMesh()), tell the component what changed so it re-streams the minimum:

  • NotifyMeshModified() — full rebuild; use after topology / material / attribute-topology changes. (The Blueprint node is named Notify Mesh Updated; NotifyMeshUpdated() is a C++ alias.)
  • NotifyMeshVertexAttributesModified(bPositions, bNormals, bUVs, bColors) — faster path for vertex-attribute-only changes (no topology change). Blueprint node Notify Vertex Attributes Updated.
  • FastNotifyPositionsUpdated(bNormals, bColors, bUVs), FastNotifyVertexAttributesUpdated(...), FastNotifyColorsUpdated(), FastNotifyUVsUpdated() — targeted C++ fast-update entry points.

  • ConfigureMaterialSet(const TArray<UMaterialInterface*>&, bDeleteExtraSlots) sets the whole material set; SetNumMaterials(N) and ValidateMaterialSlots(...) manage slot count.
  • SetTangentsType(ERealtimeMeshDynamicTangentsMode) chooses NoTangents, AutoCalculated (from positions/normals/UVs), or ExternallyProvided (use the tangents on the mesh’s attribute set — the default).
  • Baked-at-conversion niceties: SetColorOverrideMode (None / VertexColors / Polygroups / Constant), SetConstantOverrideColor, SetVertexColorSpaceTransformMode, and best-effort SetEnableFlatShading.
  • SetTwoSided(bool) is advisory only here — RMC has no per-section two-sided flag, so assign a two-sided material to render two-sided.

Dynamic supports whole-mesh complex collision plus simple shapes:

  • EnableComplexAsSimpleCollision() / SetComplexAsSimpleCollisionEnabled(bEnabled, bImmediateUpdate).
  • SetSimpleCollisionShapes(const FKAggregateGeom&, bUpdateCollision) / ClearSimpleCollisionShapes(...) / GetSimpleCollisionShapes().
  • SetDeferredCollisionUpdatesEnabled(...) and UpdateCollision(bOnlyIfPending) to batch cook work.
  • The bEnableComplexCollision, CollisionType, bDeferCollisionUpdates, and bUseAsyncCooking properties are editable in the details panel.

Because the source of truth is a UDynamicMesh, the Geometry Script library works directly on this type. Get the mesh with GetDynamicMesh(), run Geometry Script nodes against it, then let the change notify flow through — the node graph’s edits mark the mesh dirty and the component reconverts. For fine-grained control from C++, wrap your edits in EditMesh(...) with the appropriate ERealtimeMeshDynamicRenderUpdateMode.


URealtimeMeshDynamic covers the “core + common” UDynamicMeshComponent surface. Proxy-internal features are not carried over: secondary triangle buffers, render decomposition, render-mesh post-processors, live triangle-color / vertex-remap functions, wireframe overlay, override/secondary render materials, and raytracing / draw-path toggles. As noted above, bTwoSided is a material property here and flat shading is best-effort.