Collaborative Project: L-Systems

One of Xinyu’s earliest sprite submissions was the seaweed spritesheet – it contained long strands of curved seaweed, with bulbous ‘heads’.

I initially animated these with a simple cosine ‘tidal’ script, so they appeared to bob and sway in the water, but I was keen to try something more complex.

I asked Xinyu to chop the sprites up into smaller units. My idea was to use Unity’s 2D physics to create ‘chains’ of these units, anchored to the seabed; if the ‘head’ of the seaweed was to move, it would cause the rest of the organism to move in a cascading, ‘natural’ way.

This proved much harder to implement than I had expected, perhaps due to my still incomplete understanding of Unity physics and its Joint objects. Additionally, even if I had been able to get a single chain of seaweed functioning properly, the workflow of hinging together piece after piece was far too laborious.

Luckily, Zans had covered L-Systems with us the previous week, so I created a new ‘dev scene’ to experiment with making L-System seaweed formations.

Step 1 was creating a ‘root’ object – this would be a prefab that could be instantiated repeatedly. It contained a sprite – the piece of seaweed I wanted to render – and a transform – for the next instantiated object to use as its position.

Step 2 was defining an axiom – the rules by which the seaweed would know how to form itself. I created a short set of instructions, then instructed the script to iterate over them 2 or 3 times – I wasn’t keen on overwhelming formations with 4 or more iterations!

My initial experiments produced bush-like formations that looked much happier on land. This was due to the axiom randomising its angles – sunlight is all around plants on land, so leaves grow in various directions and angles in order to reach it. Seaweed naturally grows upward, as it is buoyed by salt water and seeks the sun, which is above, so its angular formations are much more uniform. I swapped in some new instructions: if the program came across a + or a -, it would set the angle of the next instantiated object to be between x and y (or -y and -x) degrees, with x and y being exposed floats I could tweak in the inspector.

This gave new formations a ‘natural’ logic, more akin to Prusinkiewicz and Lindenmayer’s sketches and axioms featured in The Algorithmic Beauty of Plants.

Prusinkiewicz, P and Lindenmayer, A, The Algorithmic Beauty of Plants, Springer-Verlag NY 1990, p25, viewed 18th February 2021, <http://algorithmicbotany.org/papers/abop/abop.pdf>

This setup allowed for a fast and productive workflow – I could generate seaweed and coral prefabs quickly, and made five prefabs in no time at all. Of course, I had forgotten to attach movement scripts to the sprites themselves, and had to add one to each sprite! Thankfully, Unity’s search function made this relatively painless. I updated the ‘branch’ prefab with the movement script, so that any future L-System prefabs would be pre-scripted.

Overall, I ended up with fifteen prefabs of different colours, sizes and textures. I was able to resize and rotate these in-scene to create more fibrous-looking seagrass, as well as using some placeholder rock sprites to create clumpier coral growths. 

Some of the prefabs implemented in-game – bump-mapping and a lighting system really brings them to life!

Were I to revisit L-Systems again, I would look at coding a randomiser that would alter the iteration recipe, so that on pressing space I would have a brand new formation, not just the same underlying structure with different angles. I would also fully create multiple branch prefabs first, then use a List to randomise which branch a new formation uses as its root. With those two simple additions, I would have a tool that could output hundreds of unique prefabs an hour, if not more. I hope not to need that many plants in the future, but you never know!