Shootable Roaches
Posted on March 5, 2024 • 4 minutes • 817 words •
Table of contents
Shootable Roaches in Niagara
In this Niagara System I implemented basic roach behaviour using a state machine to lerp between behaviour parameters (idle / walk / run), player avoidance and, of course, I couldn’t resist the urge to make the bugs shootable with some over-the-top VAT splats!

Roach VAT prep
I used a free cockroach model made by SkyBeyondStorm from HERE!
First I had to transform the roach model to the origin, and position it such that its legs touched the ground and body faced in the correct direction (Houdini x-axis), ready for instancing on my Niagara particles.

After plugging the textures into a custom “VAT Particle Material” (utilizing the SideFX Labs VATSoftbodyDeformation
material function) and assigning it the mesh, we have a material that is now ready to be controlled from a Niagara particle system.

For the purposes of the roach particle sim, this material only needed to expose an AnimTime Dynamic Parameter to the particle simulation. This allowed the simulation to control the VAT mesh animation.
Idle / Walk / Run State Machine
During their normal behaviour, the roaches would randomly switch between idle
and walk
states, using the Time Based State Machine
module.

In the idle
state, the roach particle is simply forced to a halt. No forces or heading rotations are applied and the animation paused.
In their walk
state, the roaches are being affected by various forces (curl noise, boundary forces, drag). The particle state is used to modulate the noise strength in different states. For example, if the particle is in the walk
state, the EnableState(Walk)
dynamic input module (state filter) would return 1. If the particle is in a different state, the input module would return 0, and thus multiply the walk
-state curl noise down to zero. This approach is used to easily enable/disable the various forces for different states.

The boundary force is simply an “inward” force that gets applied when the roach particle moves outside the designated area to “gently” nudge it back in the desired zone.
The result of the various forces are then combined into a desired_heading
vector.
GPU Distance Field surface projection
The roach’s desired_heading
vector will be projected onto the GPU Distance Field surface (projected_heading
) to ensure that the particle’s desired movement direction always follows the surface normal to avoid any unnatural-looking slowdowns in its movement.

Custom Movement Update
In a custom movement update module (MoveToHeading
), the roach heading
is rotated (using a rotation speed) towards the projected_heading
after which the particle is displaced along heading
based on its current speed. This ensures that the roaches are always moving in the direction that their facing, instead of trying to rotate towards their velocity direction (which looks unnatural).
After the particle has been displaced along its heading
vector, the particle itself will also be projected onto the Distance Field surface to ensure that we don’t have floating roaches after the custom movement step.
Player Avoidance
Whenever the player comes withing a certain range of the roaches, they will go into a fleeing
state where they will frantically try to run away from the player for a short period of time.
The player’s current position is being fed into the Niagara system from Blueprints through user parameters. If the roaches are within a certain distance of the player’s position, they will switch to the fleeing
state and start running away until their fleeing_time
runs out.
Hit Trace Detection
Hit trace detection works very similar to the player avoidance mechanism. Whever a bullet’s line trace hits the Niagara box, line trace data is passed into the Niagara system via user parameters for one tick: HitDirection
(vector), ShotDirection
(vector), and ProcessHit
(bool).

If ProcessHit
is true, then all particles will check whether they are within a certain distance (particle radius) from the ray (defined by the user parameters). If they are close enough to the ray, the roaches are considered to be “hit”. The particles that have been “hit” will switch to a splat
state.
Splat VAT
The Splat VAT was generated in Houdini with a FLIP fluid sim and exported as Dynamic Remeshing (Fluid) VAT.

Once a particle enters a splat
state, it the particle will switch from the Roach MeshRenderer
to the Splat MeshRenderer
(using Niagara’s VisibilityTags) and proceed with playing a retimed version of the Splat VAT animation.

Final result
After some retiming tweaks of the VAT Splat animation, the (over-the-top) retimed VAT Splat felt satisfyingly punchy. And then finally, putting it all together in-game:
Working towards Part II
The biggest limitation in this setup was that the GPU emitter couldn’t generate Death Events. This would have been very useful for spawning decals and bug bits when the roaches explode. There are alternative approaches / workarounds for this limitation that I intend to explore and do a follow-up article. So keep an eye out for Part II where we add some decals and bug bits!