How can I add/remove vertices and indices of a static mesh?

Hi all,

I am new to UE4 and this community. I made some brief searches beforehand and couldn’t find anything that answered my questions. I did spend more than a few hours searching online. Basically I have a static mesh (default UE4 cube) and I can successfully retrieve its vertices and indices. My goal is to be able to modify the mesh by removing/adding vertices at runtime. I know about the UProceduralMeshComponent but I saw that it is experimental and usually used to build a mesh from scratch, so I haven’t gone that way.

I have several issues:

One of the problems is that after calling Init() on the PositionVertexBuffer the number of vertices doubles (e.g. 24 → 48), instead of just refreshing.
I also change the IndexBuffer with SetIndices() - in terms of index count it seems to work, but the change somehow persists between PIE instances until I decide to restart the editor.
Nothing changes visually - I don’t see anything extra from the double vertices and I don’t see a missing face on the cube (removing the last 3 indices that form a face).

What am I doing wrong?

Here’s the code:

//get the mesh component(s)
	for (int32 i = 0; i<Components.Num(); i++)
		UStaticMeshComponent* StaticMeshComponent = Components[i];
		UStaticMesh* StaticMesh = StaticMeshComponent->StaticMesh;

	TArray<FVector> vertices = TArray<FVector>();
	TArray<uint32> indices = TArray<uint32>();

	FStaticMeshVertexBuffer* VertexBuffer = &Components[0]->StaticMesh->RenderData->LODResources[0].VertexBuffer;
	FPositionVertexBuffer* PositionVertexBuffer = &Components[0]->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
	FRawStaticIndexBuffer* IndexBuffer = &Components[0]->StaticMesh->RenderData->LODResources[0].IndexBuffer;

	if (PositionVertexBuffer)
		const int32 VertexCount = PositionVertexBuffer->GetNumVertices();
		for (int32 Index = 0; Index < VertexCount; Index++)
			//const FVector WorldSpaceVertexLocation = _actor->GetActorLocation() + _actor->GetTransform().TransformVector(PositionVertexBuffer->VertexPosition(Index));
			//if I get the vertices in world space and then feed the array list back, in addition to doubling the vertices all the walls and the cube change their position
	if (IndexBuffer)

	TArray<uint32> newIndices;
	count = indices.Num();
	for (int32 Index = 0; Index < count - 3; Index++)    //remove one face
	Components[0]->StaticMesh->RenderData->LODResources[0].IndexBuffer.SetIndices(newIndices, EIndexBufferStride::AutoDetect);

	TArray<FStaticMeshBuildVertex> newVertexList;
	if (PositionVertexBuffer)
		const int32 VertexCount = PositionVertexBuffer->GetNumVertices();
		for (int32 Index = 0; Index < VertexCount; Index++)
			FStaticMeshBuildVertex tempVertex;
			tempVertex.Color = FColor::White;
			tempVertex.Position = vertices[Index];
			tempVertex.TangentX = VertexBuffer->VertexTangentX(Index);
			tempVertex.TangentY = VertexBuffer->VertexTangentY(Index);
			tempVertex.TangentZ = VertexBuffer->VertexTangentZ(Index);
			tempVertex.UVs[0] = VertexBuffer->GetVertexUV(Index, 0);
	RunAsyncTask(ENamedThreads::RenderThread, [this]()

Here’s the RunAsyncTask function (got it from

Header File:

static void RunAsyncTask(ENamedThreads::Type Where, TFunction<void()> What);

Cpp File:

void UModelCutting::RunAsyncTask(ENamedThreads::Type Where, TFunction<void()> What)
	struct FAsyncGraphTask : public FAsyncGraphTaskBase
		ENamedThreads::Type TargetThread;
		TFunction<void()> TheTask;

		FAsyncGraphTask(ENamedThreads::Type Thread, TFunction<void()>&& Task) : TargetThread(Thread), TheTask(MoveTemp(Task)) { }
		void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { TheTask(); }
		ENamedThreads::Type GetDesiredThread() { return(TargetThread); }

	TGraphTask<FAsyncGraphTask>::CreateTask().ConstructAndDispatchWhenReady(Where, MoveTemp(What));