After watching Avatar: The Last Airbender I wanted to experience bending the elements just like in the show. Of course actually doing this is impossible but could a game give that feeling?

It turns out that you can achieve a compelling water bendning effect using Unity! Here’s the end result.

## So how did I do this?

Before jumping into 3D lets consider the problem in just 2 dimensions. Corona Labs lets you make 2D cross-platform games and it comes with a realistic particle simulator.

It comes with this demo below, click below to try it!

This gives some interaction with particles but doesn’t create the smooth flows of water you see in the show.

It works by making all particles within the orange box match the box’s velocity. This is done by repeatedly running queryRegion which sets particle velocity in a given region. Notably this allows incrimenting particle velocity as well.

Lets picture the first GIF but with imagined forces on the water drawn as arrows.

Now to get a bending effect we can recreate the above GIF it with multiple queryRegion boxes.

Using the grid above, when a user taps the screen a ring of cells are updated with each pointing to the cursor. To ensure the cursor is always in the middle of a grid cell the whole grid is shifted as the cursor moves between cells.

For cell values I make the magnitude’s greater for further out cells as I found this better holds the particles together. To get long streams of water I gradually decrease old cell values.

Below I show the cell values with white arrows (longer for greator velocity incriments).

Try water bending below.

Then by making particles with different physical properties you get different materials. Ice is a solid group of particles, green acid mixes colour with the blue water, slime is a sticky group of particles while mud is viscous.

Checkout the 2D source here.

## 3D bending

Now that our 2D bending is pretty cool we’ve just got to extend it into 3D!

First we can use ObiFluids to simulate particles in 3D. Sadly it doesn’t come with a native queryRegion method but we can just make one by partitioning space into a 3D grid.

When running the code iterates over every particle to find its region & adjusts the velocity in the same way as before.

This could clearly make a compelling VR game, unfortunatley I am too invested in an ML project right now to do more work. If you would like any other implementation details feel free to reach out to me on Twitter.