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:
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.
Hey, necroing this again. Thanks for the reply. I think I had resolved it in a different way. I believe I had to call the set custom material function each frame.
Otherwise I used TArrays for projectiles and my own custom projectile tracing logic only using HISMs for display and updating the instances based on trajectory calculations.
However, I will probably switch to Niagara, keeping my projectile logic with transforms and passing that data to Niagara.