Recursion
The VariaInstantiate component is a useful part of Varia. It causes an arbitrary prefab or other object to be instantiated when the original object is. You could randomly add a hat object to creatures in your game.
But if you start to play around with it, you'll notice it's a bit more subtle than some of the other components Varia offers. The instantiated object can itself have Varia components attached, which get run when it's created. If those components include another VariaInstantiate component, then it'll run and create a third thing. And that third thing might go on to do even more...
In fact, you might have a series of prefabs, each of which creates the next in the series, and the final one creates the first once, starting the cycle over and over forever. This is the essence of Recursion.
We can harness this sort of behaviour to create a whole class of generated objects with Varia that would otherwise be impossible. Obviously, creating objects forever is not really feasible, so we'll put in a depth limit that stops creation after a certain number of objects.
In this tutorial, we're going to recreate the Golden Spiral fractal found in the Fractals sample.
Initial setup
First, create a new sprite from the white_square asset in the Fractals sample. Call it golden_spiral
, and give it the VariaPrototype
component. Adding this component disables all other varia components on it. That means when we start the scene, it'll remain unchanged. That's important as we're going to copy golden_spiral
many times, and need it to start from a consistent position.
Instead of adding VariaPrototype
, you could just make it a prefab. However, it's handy to have the object in the scene itself so you can edit it without constantly changing scenes in the editor.
Next, we're going to set up a "Previewer". Previewers automatically instantiate a given object, so are very useful for viewing in the editor what would occur when an object is created. Create an empty, add the VariaPreviewer
component, check "Continuous Refresh" and "Refresh in Editor", and set the target to golden_spiral
. Now any changes you make to golden_spiral
will be instantly reflected in the previewer. So you should see two white squares - one for golden_spiral
, and one for the previewer.
Adding the recursion
Create an empty object as a child of golden_spiral
, and call it, sub
. Set the scale of it to 0.7, hen add a VariaInstantiate
component. Finally, set the Targets array of that component to reference golden_spiral
.
Now move sub
around a bit with Unity's Move Tool. You should immediately see that 9 additional squares are visible in the previewer, each smaller than the last. As you move sub, they react in an interesting way.
What is happening is that sub
is creating a fresh copy of golden_spiral
using sub
's transform information. So, as we scaled sub
0.7, the new copy of golden_spiral
is also scaled by 0.7. That new copy has it's own sub
, which is scaled by 0.7 twice, giving it a total size of 0.49, just under half the size of the original. It creates a golden_spiral
with that size, and so on.
The process stops after 10 copies have been created. That is because, by default, VariaInstantiate
has a limit of 10 repetitions:
Warning
Setting the depth filter to too high a value, or removing it, will cause Unity to create too many objects. That can crash the editor!
To recreate the shape of the golden spiral, sub
should have the following settings:
Position: (1.618034, 0, 0)
Rotation: (0, 0, 270)
Scale: (0.618034, 0.618034, 0.618034)
At these values, the rectangles all interlock in a tight spiral, as you can see from this wireframe view:
To finish things off, replace the use of white_square.png with golden_curve.png, which draws an appropriate arc for each sprite. You should be rewarded with the full spiral.
More complicated patterns can be done via careful use of what to instantiate. The fractals and tree samples demonstrate a few ideas.
For more information on recursion, see recursion. Sorry, a little programmer humour there...