Bizarre 4.27 issue with HISM in packaged builds / Standalone

Hi everyone,

I have a really strange issue with my hierarchical static instanced meshes in 4.27 when I package my game up for distribution.

My game uses a HISM component to render soldiers in a company. A company is basically an invisible character which navigates around and the soldiers use that as a reference to understand where they should be stood at any given moment. A soldier is just a UObject containing an FTransform and a bunch of data related to which animation it should be playing (I’m using vertex animations baked into a texture).

I separately run logic in the company’s Tick function to update the positions of soldiers, and then my HISM component runs through the lists of soldiers and updates their rendering info on that tick, like so:

for (int32 i = 0; i < NumSoldiers; i++) {

			InstanceTransforms.Add(pair.Value.Soldiers[i]->GetSoldierTransform());

			pair.Value.HISM->UpdateInstanceTransform(i, pair.Value.Soldiers[i]->GetSoldierTransform(), true);
			pair.Value.HISM->SetCustomData(i, pair.Value.Soldiers[i]->CustomData);
			
}

So every tick, my HISM is looping through every soldier and calling UpdateInstanceTransform, and SetCustomData.

The issue I have is that this works great in the editor using PIE running under a single process like so:

But if I play in a packages build, or launch a standalone session under a separate process, the HISM is now broken completely. It only updates once every 5-10 seconds, like the world’s slowest slideshow. Note that I know the game is correctly updating the soldiers because I can collide with them, it is ONLY the rendering which isn’t working:

Notice how you can see the little sphere representing the invisible company character moving smoothly, and then the soldiers are just frozen and then suddenly teleport.

To make things even weirder, losing focus on the window by bringing up the start menu fixes the issue. It only happens if the game window has focus.

Anyone have any idea what on Earth is going on here? Is it a bug? Have I messed something up?

Thanks!

What tick group is assigned to the actor?

Hey! Thanks for responding :slight_smile:

There are two actors involved. The company actor is responsible for determining where the soldiers are at any point and the custom data (which governs animations), and a separate “Soldier Renderer” actor contains the HISM components which lifts the transforms and custom data for each soldier and updates the HISM component each tick.

Both actors have the Actor default “Pre Physics” tick group assigned.

First thing that comes to mind is that perhaps the HISM transform itself is fine, and what’s wonky is the vertex animation. I had some problems where the loading of texture MIP levels was inconsistent between editor and packaged build. If your vertex animation texture got mipped, or otherwise compressed, it could cause this. I would double check mip maps and compression settings are disabled for the vertex animation texture.

Other than that, IDK if your game contains any multiplayer code, but if it does, it could be related to some replication relevance.

Also, I’d recommend looking into BatchUpdateInstanceTransforms() function in HISM. It should be a bit more efficient when updating large amount of instances often. The way you’d do that is that you’d first generate array of transforms for every soldier sorted in the same order as the soldier instance, and then you feed that whole array into the function.

Given that you are drawing quite a few soldiers and updating them every frame, you could get some nice performance boost :slight_smile: Anyway, my main point is that replacing the loop with a single call of BatchUpdateInstanceTransforms() could perhaps miraculously solve the issue, as it often happens in programming :smiley:

Thanks for the suggestion! I actually was doing batch updates previously (you’ll see in my code I’m adding to a FTransform array which does nothing), but I started this project in 4.26 and I think there was an issue with batch updates.

From what I remember, there wasn’t a feature to batch update custom data, or it was bugged, so I had to update custom data individually, and the transform had to be done before the custom data or it caused further issues. I’ll give batching a try again now I’m in 4.27 :slight_smile:

I think I may have resolved the issue thanks to you guys. I did two things:

  • Made the soldier renderer actor’s tick group to TG_PostUpdateWork
  • I noticed I didn’t seem to be marking the render state as dirty in that function. This is normally the 4th parameter in UpdateInstanceTransform and by default it’s false, so after the loop I added a call to MarkRenderStateDirty()

Problem seems to have gone away now in packaged builds. Will update this if I turn out to be wrong.

1 Like