UE4.27.2 Moving (Hierarchical) Instanced Static Meshes with Custom Data render black in Game but fine when paused

Hi,

I am building a custom projectile pool with hierarchical instanced static meshes. For each projectile, I want to be able to set custom material data. For testing, I just assign three random floats to the RGB channels of an emissive color for my projectiles.

So, I set everything up and when I hit play and tested, all projectiles I shot were rendered black. It took me a while to find out that my setup was actually correct because, when I paused the game, I saw that the projectiles actually had a random color. I made a little showcase video here:

I tried to switch from HierarchicalInstancedStaticMeshComponent to InstancedStaticMeshComponent but that didn’t change anything.

I also noticed that, the less projectiles I shoot, the less rendering issues I have but they never go away completely.

Removing this line in my projectile movement logic makes the projectiles render correctly:

HISMProjectiles->UpdateInstanceTransform(ProjectileIndex, NewProjectileTransform, true, true);

However, obviously that doesn’t help since they then stop moving.

Any ideas how I can make this work?

Thanks!
Nico

Tested in UE 5.5, the fix is to use BuildTreeIfOutdated(false, true) on each frame tick after the gameplay/projectile positions update. Use after making changes to the (H)ISMC:
HISMC->BuildTreeIfOutdated(false, true);
(bool Async, bool ForceUpdate)
As the function says it will force rebuild the entire tree.

Projectile pools with a medium/large number of actors is a tricky case since collision can completely tank the frame rate, and async/gpu systems can be a pain to sync with. Niagara systems are great for cosmetics-only effects such as a spinning particle cone, but for anything involving collisions and movement on the particle level and actual callbacks - like a swarm of missiles with distance LODs - it’s understandable to consider HISMC or a large amount of AActors w/ mesh.

Not sure what the go-to should be for a projectile pool of say 300 homing projectiles. There’s the occasional selective dynamic collision or query traces, and a choice of pooled AActor, HISMC, and even Niagara.