GetVertexColorData() not working on packaged build?

Hello all!

I have posted this question on Answer Hub almost 2 days ago but sadly, I did not get any answers. I figured I should try my luck here. Here’s what I want to achieve: I have a flat mesh where I want to instanced a static mesh on each vertex. Additionally, I want to use the vertex color of this mesh to handle the rotation and scale of the instance.

All of this is working fine in the editor. Here’s what it looks like:

My problem is that I am not able to properly get the vertex color in a packaged build (or when launching it). I am using a C++ Blueprint library to do this. Extending from the function to get vertex positions shared by Rama (wiki), I have added the following code:

bool UMultivrsBPLibrary::GetStaticMeshVertexInfo(UStaticMeshComponent* SM, TArray<FVector>& VertexPositions, TArray<FColor>& VertexColors)
 TMap<FVector, FColor> VCMap;
 for (int i = 0; i < VCMap.Num(); i++)
     FColor c = VCMap[VertexPositions*];

Is the GetVertexColorData() function not working outside the editor? Is there an other/better way to get the vertex color in blueprint? By the way, the position is still correct but the vertex color is completely black. I have been able to confirm this by doing a Print.

I would appreciate any help on this!

See if this and this has anything to do with what you’re trying.

The information you’re trying to access might not exist in the packaged build in order to save memory, but I’m not sure. They discuss some other ways of accessing this kind information at the packaged build, might be helpful.

As said by nick_p:

“Additionally, in shipping builds we free the CPU accessible vertex and index buffers to save memory. If you need to access this data at runtime you will have to make a small code modification in FStaticMeshLODResources::Serialize to set bNeedsCPUAccess to always be true.”

Thank you MatheusRC!

That seems like a perfectly logical explanation and a very good lead. I’ll try this!

Quick follow up on this subject:

I ended up using the ColorVertexBuffer variable of the Static Mesh to accomplish this. Long story short, I realize I didn’t need to make this code modification if I was using the AllowCPUAccess setting of the Static Mesh. Here’s the code for anyone who might be interested:

#include "StaticMeshResources.h"

bool UMultivrsBPLibrary::GetStaticMeshVertexInfo(UStaticMeshComponent* SM, TArray<FVector>& VertexPositions, TArray<FColor>& VertexColors)

	if (!SM)
		return false;
	if (!SM->IsValidLowLevel())
		return false;

	FPositionVertexBuffer* VertexBuffer = &SM->GetStaticMesh()->RenderData->LODResources[0].PositionVertexBuffer;
	FColorVertexBuffer* ColorBuffer = &SM->GetStaticMesh()->RenderData->LODResources[0].ColorVertexBuffer;

	if (VertexBuffer)
		const int32 VertexCount = VertexBuffer->GetNumVertices();
		for (int32 Index = 0; Index < VertexCount; Index++)
			// Converts the UStaticMesh vertex into world actor space including Translation, Rotation, and Scaling
			const FVector WSLocation = SM->GetOwner()->GetTransform().TransformVector(VertexBuffer->VertexPosition(Index));

			const FColor Color = ColorBuffer->VertexColor(Index);

	return true;

Make sure you are setting Allow CPUAccess to true on you Static Mesh!


P.S. Big thanks to Rama for this solution he posted a while ago:

@CapitaineStar i am trying to get the Vertex Color Data as well on runtime but when i try to use the Color Buffer exactly like you do i can inconsistent result where the color array are all red.

If i call ColorBuffer->Init(VerexCount, true); afterwards then it is all red up until the last 100 vertices in the color array where they seem the colors are random and don’t match up with what has been painted.

Note that allow cpu access is true on the mesh, and i am on 4.21