Some c++ code doesn't work on a packed game!

I’m using a custom node made by Rama, this is the code :

bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions)
{
	if(!Comp) return false;
	if(!Comp->IsValidLowLevel()) return false;
	
	//~~~~~~~~~~~~~~~~~~~~
	//				Vertex Buffer
	if(! Comp) 									return false;
	if(! Comp->StaticMesh) 					return false;
	if(! Comp->StaticMesh->RenderData) 	return false;
	if( Comp->StaticMesh->RenderData->LODResources.Num() < 1) return false;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	
	//~~~ End of Pointer Safety Checks ~~~
	
	//~~~~~~~~~~~~
	VertexPositions.Empty();
	//~~~~~~~~~~~~
	
	FPositionVertexBuffer* VertexBuffer = NULL;
	VertexBuffer = & Comp->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
	if(!VertexBuffer) return false;
	//~~~~~~~~~~~~~~~~
	
	int32 VertexCount = VertexBuffer->GetNumVertices();
	 
	FTransform RV_Transform = Comp->GetComponentTransform(); 
	for(int32 Itr = 0; Itr < VertexCount; Itr++)
	{
		VertexPositions.Add(
			Comp->GetComponentLocation() + RV_Transform.TransformVector(VertexBuffer->VertexPosition(Itr))
		);
	}
	
	return true;
}

It works great in the editor, and even on a standalone window, but when i pack it, it won’t work anymore.
I’v tried it as a plugin and also as a c++ class in the project, and it gave me the same results.

This is the blueprint:

This is in the editor:

And this is in a packed game:

While searching for something similar I found a wiki page below that explains how to do this -

It seems because of the way vertex data is packed in shipping builds you can’t access the them through the vertex buffer on render data.

Note that I wasn’t able to get the code in the wiki page to compile because of some Physx dependency issues but it’s worth trying out for sure (I probably got my build.cs or includes wrong)

Thanks! I will take a look on it.

I can confirm this issue, I’ve been experiencing it since 4.3

Summary of issue: vertex positions are often jumbled or just missing in packaged game when accessed using method posted in original post and also via code below in this comment

#Question For Epic

Epic is there a preferred way to access vertex data in a package game, that you recommend?

Here’s the code being used that works perfect in pre-packaged game and does not work in packaged game.

It seems that using the Render Data / LOD info in packaged game does not work some reason?

Comp->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer

Is there an after-packaging better way to get the vertex position info?

Please note the rotation/translation of each vertex is scaled by the FTransform to match actor scaling and rotation.

Comp->GetComponentLocation() + RV_Transform.TransformVector(VertexBuffer->VertexPosition(Itr))

#Solution Using PhysX

Dear Community,

I’ve updated my BP node in my Victory BP Library plugin to use PhysX to get the vertex positions (special thanks to Vebski for pointing out that we can get accurate vert positions using PhysX in packaged games(

BP Node For You

UE4 Forum Link

#C++ Code For You

Here’s my C++ code that you can use to get the transformed (rotated, translated, scaled) vertex positions of any static mesh component!

#Build CS

You need to include APEX and PhysX in your build.cs dependencies

//~~~ PhysX ~~~
#include "PhysXIncludes.h"
#include "PhysicsPublic.h"		//For the ptou conversions
//~~~~~~~~~~~

//Get Transformed Vertex positions of any static mesh! -Rama
     bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions)
{
	
	if(!Comp) 						
	{
		return false;
	}
	
	if(!Comp->IsValidLowLevel()) 
	{
		return false;
	}
	//~~~~~~~~~~~~~~~~~~~~~~~
	
	//Component Transform
	FTransform RV_Transform = Comp->GetComponentTransform(); 
	
	//Body Setup valid?
	UBodySetup* BodySetup = Comp->GetBodySetup();
	
	if(!BodySetup || !BodySetup->IsValidLowLevel())
	{
		return false;
	}  
	
	//Get the Px Mesh!
	PxTriangleMesh* TempTriMesh =BodySetup->TriMesh;
	 
	if(!TempTriMesh) 
	{
		return false;
	}
	//~~~~~~~~~~~~~~~~
	
	//Number of vertices
	PxU32 NbVerts 			= TempTriMesh->getNbVertices();
	
	//Vertex array
	const PxVec3* Vertices 	= TempTriMesh->getVertices();
	
	//For each vertex, transform the position to match the component Transform 
	for(PxU32 v = 0; v < NbVerts; v++)
	{ 
		VertexPositions.Add(RV_Transform.TransformPosition(P2UVector(Vertices[v])));
	}
	
	return true;
	
	/*
	//See this wiki for more info on getting triangles
	//		https://wiki.unrealengine.com/Accessing_mesh_triangles_and_vertex_positions_in_build
	*/
} 

#Enjoy!

#:heart:

Rama

Hi! more question…

How can i access index buffer in packed game?