GetVertexColorData() not working on packaged build?

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 shared by Rama ([wiki][2]), I have the following code:

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

...

TMap<FVector, FColor> VCMap;
SM->GetStaticMesh()->GetVertexColorData(VCMap);

for (int i = 0; i < VCMap.Num(); i++)
{
	FColor c = VCMap[VertexPositions[i]];
	VertexColors.Add(c);
}

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!

Hello CapitaineStar,

From looking up the GetVertexColorData function in StaticMesh.cpp, it looks like the entire body of the function, other than the first line which sets it to an empty value, is contained in “#if WITH_EDITOR” meaning that it will only execute in the editor.

From looking up alternatives, I came across this old archived post that may be able to provide some information. It looks like there are no plans to expose this information to blueprint but you may be able to access it in C++ by directly accessing a Static Mesh’s FColorVertexBuffer variable.

Hello Matthew,

This is exactly what I ended up doing!

Here’s the code for anyone that would need it:

#include "StaticMeshResources.h"

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

	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));
			VertexPositions.Add(WSLocation);

			const FColor Color = ColorBuffer->VertexColor(Index);
			VertexColors.Add(Color);
		}
	}

	return true;
}

The other really important thing here is to enable Allow CPUAccess on your Static Mesh settings.