Using Particle Effects and Vertex Animation to Simulate Large Groups of Animated Meshes

Now, 100,000 birds means 100,000 skeletal meshes right?
No! We can use an old-school trick called vertex animation.
It’s now easier than ever to make smart particles that interact with your environment.

Mesh and Material Setup

I started with a simple bird skeletal-mesh from the marketplace, which I converted into a static mesh and baked all its animations into a single vertex animation texture.
I am feeding in the animation frame from the emitter using a Dynamic Parameter.

Emitter Module Setup (Niagara)

We need to create a custom module that consists of the following:

  • A set of conditions for when to play each animation
  • If statement that specifies the Animation StartFrame, EndFrame and State (or Animation_ID)
  • (Optional) FinishCurrentAnimation before switching to the next Function
  • Play Animation Function

If-statements and Conditions

If-statements define the animation Start and End Frame.
In this case, it picks between flying or gliding based on the up velocity sign.
The animation info is then sent to FinishCurrentAnimation (optional), then PlayAnimation.

FinishCurrentAnimation Function

This Function Stores the Current State Properties and ignores all new states until the current one is complete.
I am outputting the same output twice as a reminder that you need to store the value, as functions don’t have persistent variables.

PlayAnimation Function

AnimationFrame = StartFrame + ElapsedFrames + (AnimationSpeed*DeltaTime) * FrameRate.
If the current animation’s EndFrame is reached, it will loop back to the StartFrame.
If the animation changes, it will reset to the new animation StartFrame.
The InitialState check is used to prevent resetting the ElapsedAnimationFrames. Useful if you want to randomize animations offsets, you can do so during the initial state.

The Particle System Setup (Niagara)

This part controls the bird movement. In this case, I am setting the velocity via a curve.
The Animation module we just created then decides which animation to play.
A debug Module changes the particle color based on the animation state.

Putting it all Together

This bird particle is switching between different animations based on velocity and position.
If you try to make a bird that does it all, you can end up with something large like this:

Best to create a custom module for each system with its own set of conditions.

This sums up how to setup Animated Particles to simulate large flocks in Unreal.
Below are a few systems that demonstrate different bird logics

Birds that Land on Tree

Birds are spawned in a grid, their orientation and their animation start-time are randomized.
The destination points are sampled from a StaticMesh tree, where the top surface of branches is filtered using MaterialID.
Lerp between the two positions.

Birds that Land on Tree (Breakdown)

Since we are controlling the movement with a lerp and knowing each animation duration, there is no need to guess when the bird is going to land.
We can map each animation’s start to the lerp position.

A Flock of Birds

Vortex Velocity Module is used with a randomized axis to make the birds fly inside a sphere.
The animation module is selecting Fly Up or Fly Down based on the velocity z-direction.
With a simple effect like this, I managed to have 100k birds on screen.

Make sure to follow my on Twitter @JosephRAzzam]( for more #UETip](, and check back in two weeks where I plan to cover how to add player interaction.

Thanks for sharing your knowledge! Great for noobs like me!

Holy cow, amazing work ! If I may ask, how are you baking anims to texture ?

PS Big thumbs up for the great breakdown :slight_smile:

Could you clarify this, “The destination points are sampled from a StaticMesh tree, where the top surface of branches is filtered using MaterialID.” I don’t really understand

Unreal has a script to do it in 3ds max…ool/index.html
Vertex Animation Tool…hes/index.html
Vertex Animation Tool - Timeline Meshes…hes/index.html

Also, check out this youtube talk by my colleague

Niagara has a module to sample a static mesh and get location points on the surface. You can see that module in the Bird Tree Niagara screenshot. If you want specific areas of a mesh you can sample a Material area. So I just selected the areas where I want the birds to land, and placed them in a different material.

Great Tutorial, but its not for N00bs. I tried to replicate parts of it but i can’t even get the “Play animation NFS” to run properly. The animation is way to fast and i cant figure out why.

Where can i get the NFS Play Animation function?
I don’t have one