Spline mesh collision missing from packaged build

I have been working on a procedurally generated infinite runner style game with a series of spline mesh tubes as the level. If the tunnel spline and spline mesh are generated at runtime the collision data will be missing, but only in the packaged build. It works fine with per poly collision in the editor. I have tested other collision types and primitives but I still get the same problem.

When generating the tunnel in the construction script the collision is fine in the packaged build but then we can’t exactly have a different tunnel each time the game runs; like I intended.

Is there a way to cook physics at runtime; or is this a bug?

(using v. 4.6 and packaging for Windows 64bit)

I am having the same issue using procedurally generated spline meshes. Works in editor, but not on exported .exe or deployed to Android.

These lines in SplineMeshComponent.cpp seem to be the culprit:

void USplineMeshComponent::MarkSplineParamsDirty()
{
	MarkRenderStateDirty();

#if WITH_EDITOR
	if (!GetWorld()->AreActorsInitialized())
	{
		RecreateCollision();
	}
#endif // WITH_EDITOR
}

Outside of the editor, the collision is not created when spline parameters are changed. Why is this editor only?

+1! I’m having the same issue at the moment, and working a blueprint only project. This would really help to get something resolved asap :smiley:

+1 Same problem, needs fix!

Came here from Implement Runtime Collision Detection for Procedural Generated Meshes - Feedback & Requests - Epic Developer Community Forums

Got bitten by this too (4.7.6).
If you are using a series of spline mesh components, you are probably turning collisions off for performance in the editor (recalcs every collision mesh on spline while dragging ouch) and turning them back on in BeginPlay().
It appears there is a bug / feature deep in the serialization code that fails to serialize collisions for meshes that don’t currently have collisions enabled (UStaticMesh::ContainsPhysicsTriMeshData).

My workaround was overriding UObject::PreSave() for my spline mesh component container class to temporally turn all collisions back on ( #if WITH_EDITOR). BeginPlay() and Tick() turn on sections of the mesh only around the player.

Remember that you will have to fix the code, launch the editor and rebake to reserialize the fix in game…

Thanks a lot for posting this, man!
Container class confirmed working!

I have been getting some PM requests to help with/clarify this solution, but really don’t have a lot of free time right now. Posts to forums tend to help multiple people in the future as well.

NOTE: This is just a quick, messy hack. I couldn’t see an easy/clean way to patch the engine (don’t know the code/possible side effects well enough).

You could just force collisions to be enabled directly in USplineMeshComponent::PreSave() if you really wanted to.
This means running a (re)building source and running custom version of the engine (applying the hack/fix everytime you update). You could also make a local game code wrapper for USplineMeshComponent and override PreSave() in that class.

In my case, I have a container class that holds a bunch of instanced spline meshes.

.h
UCLASS()
class ASomeContainerClass : public AActor
{
…
...
#if WITH_EDITOR
	virtual void PreSave() override;
#endif
}

.cpp
#if WITH_EDITOR
void ASomeContainerClass::PreSave()
{
	Super::PreSave();
	// psuedo code:
	// for each spline mesh contained by this class
	// SplineMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics)
}
#endif

When the editor is running this code, the next time the level is saved out the spline meshes will have collision data.

Extra credit:
Now if you happen to be using something similar to the container class solution above and happen to be dragging (road) spline meshes around to position them you have a problem. Everytime a spline mesh is saved during an editor session, the collisions are turned back on and dragging splines around becomes super slow.

With the exception of UObject::PostSaveRoot(bool bCleanupIsRequired) which is for asset packages, there don’t seem to be any build in methods that are automatically called after an object saves.
What I did was:

  • Turn collisions off in PostLoad() which means the first load into the editor is fine.
  • Have a ‘Refresh’ bool property on the container class, (amoung other things) turns collisions off in PostEditChangeProperty. Click this before dragging, or dragging is super slow.
  • Turn the collisions back on in BeginPlay()

psychogony -

In my case, I have a container class that holds a bunch of instanced spline meshes.

I’ve tried to implement your method and the word “instanced” makes me think that presave is just storing prebuilt sections of spline mesh.

If so, spline meshes are already saved if you set them up in the construction and would work fine, but I need random each time the game runs.

Answered why it can’t be called at runtime

Unfortunately RecreateCollision calls various functions on UBodySetup that on cooked platforms (i.e. non-editor) only support loading cooked physx collision data, not creating it on the fly. Sorry, but making USplineMeshComponent::RecreateCollision() able to be called during game would require this restriction to be lifted, and I don’t think that’s something Epic will want to do.

Another method would be to read all the vertices and create a proceduralMeshComponent which can deliver collision at runtime. I’ve tried this using Rama’s Victory plugin to build proceduralMeshComponent from staticmesh but have been unable figure out the correct ordering of the vertices to correctly build the mesh.

Looks like we were seeing the same end problem ‘Spline mesh collision missing from packaged build’ from different root causes…

makes me think that presave is just storing prebuilt sections of spline mesh
Yup - assets must be serialized. Link you provide confirms (unless something has changed since Mar 2014).

If so, spline meshes are already saved if you set them up in the construction and would work fine
Nope (well not always).

but I need random each time the game runs.
Endless runners typically use modular mesh components that can be fitted together in different ways to create variation.

[Disclaimer – have never tried this in UE4]
It sounds like want you want to do is line up various mesh tube assets end to end (these could be prebaked meshes and don’t necessarily need to be spline mesh components).
I assume that applying a Transform() to a movable mesh component at runtime to position it works fine (rather than calling SetStartPosition() and SetEndPosition() on a spline mesh and trying to rebake the collision while the game is running).

This isn’t what I am doing - I attach static mesh components to a spline component in the editor and bake them out to a level asset.

2018 and i just discovered this bug after releasing my game on itch.io… time to give it up again…

did you ever figure out a solution to this… i currently have procedurally generated spline tunnels , and they work fine in editor , but in a packaged build there is no collision at all, just like your problem, right?