Download

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.

https://youtube.com/watch?v=2XSQnfd7Xi8

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.

https://lh6.googleusercontent.com/M7GVF4qYApLLjsiFNAzgGH-7v-FsitQfuaEN_nF-mh_ossrZfXjBdYkAhBumnnRa1WZQZjf06daySF6xpsd-OOfnyk5IlzRbHuEBWsf0G8OHDMX6V0x8FxWmafP2ueqL2JP5Cg01

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

https://lh6.googleusercontent.com/Z3fCgLjB9-2vj1xLIYJkhgRussjFL_GR-KrwX5K6eSbIOAivilv8WMRgiQt--D3_KL9OdUerHI2Sb3zlGMLpM5HBgGyeopcfu1zUuMrB348RDRE1Mz-gUNDkFbGZtGat5cefS0g-

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.

https://lh5.googleusercontent.com/eYUxTMNjjqlaQ-MV0JXb7OItzbgHEgWaR1f6hJOSnAM74fRPGAtprTNTVXWxw32s4Ri6oxZNklFxR7Mnoa_Gpf4_48b88jZ9BokL2gv91BuZyBYcGsFiIaWhuz-Dx9qvgHfrb6Hr

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.

https://lh4.googleusercontent.com/aiWS2bu6lhpY2RFJ6E4_uYYREhY1RUjFWhYKKh8lQewnNmr3VOtuA-TTQiTR5tRUjQgprrmetlBvroC9741aR7TAcf6MoJ1v0QkW_5QA9B5sID-Psf_h_hw4I2tGP-TAzHmjj93n

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.

https://lh5.googleusercontent.com/tmI3eTj2xOaVANqd5fgagnxDZHwHn-fDqTBFbUQMcpLeKsw48vfFemvpbXzys8sQVrdFyqZ7EQIw83LRC1kdxzcc_XOquYGAvJHGBdHzSQwAJef0G08Q-Nz2qcPK7CL3UxeDHHdE

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.

https://lh6.googleusercontent.com/qQb-pxdPl8E7HlxpvV_Ulr15DR3Hbv9d8dyCXNUOasTWfsjlo8cwHotoiPyki1FEODHVfR-HJvijLICatWWTHs32VKqpBN00aLxHZZnxCxzSAYxoKg4hmYCgCIeJaNs6oM4YeWEd

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:

https://lh3.googleusercontent.com/Pu43HkszOBQJQPbwBAe0bpdqgrRjMM2WdWjomK2N0X4vZgG_hVty7desIljQnFDGt3bbdGLQgNFp7nAmnlXu56pEnicULcwynFZDdshr_AlBm-TwH-tnZkoa9uLQNH1yigGMOW2r

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

https://youtube.com/watch?v=4cNJNz3N1zw

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.

https://lh5.googleusercontent.com/7Z4mW098xOBAAl1Y6Zw-tlg34oSS1Kw9aLXKoh025cg0QoXjYNwnn5KS9fWjxqey8-d0ZEfeMcZDr9U8QyVIXYyG4eaCmRiPY7KENMG9S0ZyVe-xukdoo7w6Y06-wq4m1sBu5x5X

https://lh3.googleusercontent.com/y7iBA4p-zXeMs6V6tgBLLcRgW1VRJipvZwIueYYrCDSesI4FvjiKPE20G6yLlFd3jIe3dlpP712iu-g-A55wZcUf08UYoRWubDrE9KkhQLUgF3a7uoIL8_4oapJmCSIgZU4wT_Ua

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.

https://lh3.googleusercontent.com/6Uk0c3D_KY0jGDzuu6p4dKI7EF4ymi716UPcN1kshBF-zk6nOIEuX9EuEnNJNitMuQmChCW5BQSWUIhwskjGw6Pbp9YK7yy6q81RErTNPeou1HgXmihidl33g2vN4FDbM1n-jWjy

https://lh6.googleusercontent.com/UofDPM450RkfjA-YAvsiMBAuLx4Uw7SgrbCGpdhExSDnvJn2XFGDje2Ma14O4b6i10lSr0zE8JGokF2XqHUyLFd4HYnq_BYGofC3GIaHM2y05znhKqZKi7ef1tKwX2Hu_Bd7Uijw

https://lh6.googleusercontent.com/ZvtUBZqRWf29ST3QX0aEwJs4ghhTm50P4AgQPn4qbZb2n1EMp70wP9B8aFsYo08zCe47vmC6Bhf5bAYvGj8gyAwElnnLw9AdlXKHTLILAI8rrUZxNPldC1JiYFGgmhe-Iu8DeYxA

Make sure to follow my on Twitter @JosephRAzzam](https://twitter.com/JosephRAzzam) for more #UETip](https://twitter.com/search?q=%23UETip), 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

https://docs.unrealengine.com/en-US/…ool/index.html
Vertex Animation Tool

https://docs.unrealengine.com/en-US/…hes/index.html
Vertex Animation Tool - Timeline Meshes

https://docs.unrealengine.com/en-US/…hes/index.html

Also, check out this youtube talk by my colleaguehttps://youtube.com/watch?v=EUTE1SoOGrk

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