Making Hearts Fly With Unity VFX Graph

Learn how to use Unity’s VFX Graph to make stunning visual effects, like a flock of flying butterflies! The VFX Graph uses simple, node-based visual logic. By JJ Richards.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

Creating a Control Script

Inside RW/Scripts, create a new C# script named HeartManager. Next, attach that script to the HeartOfHearts GameObject.

Open the HeartManager script in your code editor, then add this declaration to the script, above the class declaration:

using UnityEngine.VFX; //for VFX graph

This lets you access VisualEffect features.

Script References
Next, just inside the class declaration, add these variables:

//1
private VisualEffect visualEffect;
//2
private VFXEventAttribute eventAttribute;
//3
private bool heartsAreFlying;
//4
private int flyingBoolID;

Here’s what this code does. It:

  1. Creates a private reference to VisualEffect, which you can use throughout the script.
  2. Declares the attribute, VFXEventAttribute, to use in the script.
  3. Creates a private variable to change the state of the visual effect.
  4. Declares a private variable, flyingBoolID, that allows the script to access the exposed variable in the graph’s Blackboard.

Initializing the Script
Next, you’ll use Awake to set up the VisualEffect component:

void Awake()
{
    //1
    visualEffect = GetComponent<VisualEffect>();
    eventAttribute = visualEffect.CreateVFXEventAttribute();
    //2
    flyingBoolID = Shader.PropertyToID("Flying");
    //3
    heartsAreFlying = false;
    //4
    visualEffect.SetBool(flyingBoolID, false);
    //5
    visualEffect.Stop();
}

In this code, you:

  1. Cache the reference to the attached VisualEffect and the required VFXEventAttribute to access it.
  2. Configure flyingBoolID to the name you’ll assign, in a bit, to the matching variable in the Blackboard.
  3. Initialize the variable heartsAreFlying to false so the butterhearts are resting to start
  4. Initialize the matching variable flyingBoolID in the Blackboard to the same.
  5. Stop the visual effect from playing at the start of the scene.

Adding Action Functions
With initialization complete, create a function to trigger the visual effect:

private void SpawnHearts()
{
    visualEffect.Play();
}

Next, create a function to toggle the intensity of the visual effect:

private void ToggleHeartFlight()
{
    //1
    heartsAreFlying = !heartsAreFlying;
    //2
    visualEffect.SetBool(flyingBoolID, heartsAreFlying);
}

In this code, you:

  1. Reverse the private Boolean used to track the state of the visual effect.
  2. Apply the updated state to the matching variable in the graph’s Blackboard.

These are all the functions you need. Now, you just need a way to call the functions.

Tracking Input
For this tutorial, an easy way to call the functions is to track key inputs with Update:

void Update()
{
    //1
    if (Input.GetKeyDown(KeyCode.Space)) 
    {
        SpawnHearts();
    }
    //2
    if (Input.GetKeyDown(KeyCode.F)) 
    {
        ToggleHeartFlight();
    }
}

In this code, you listen for the user to:

  1. Press Space, then call SpawnHearts.
  2. Press F, then call ToggleHeartFlight.

You’ve now finished the script. Save it and return to the editor.

Now that you can track inputs when playing the scene, it’s time to use that input to control the VFX Graph.

Adding Controls to the VFX Graph

First, select HeartOfHearts in the Hierarchy and click Edit to open the HeartOfHearts graph in the inspector. Make the window full screen so you have plenty of room to work.

In the Initialize Particle Block, increase the Capacity to 10,000. So many butterhearts shouldn’t fly forever, so add a Set Lifetime Random Block with (A:3, B:10).

Then, for a graceful exit, add a Set Alpha over Life Block to the Output Particle Block for both wings and set the animation curve to your liking.

To control whether the butterheart is flying or resting, add a new Boolean variable to the Blackboard and call it Flying. This variable modifies both the Wing Animation Speed and the particle velocity, so drag it onto the graph twice, close to each node it will modify.

To modify Wing Animation Speed, Flying supplies a Branch Node to choose whether to use the full or modified version of the Wing Animation Speed.

Wing Speed Nodes

To modify the particle velocity in the Update Block, Flying supplies a Branch Node to choose whether to use the full or reduced velocity calculation. Because velocity is used elsewhere in the graph, avoid setting the velocity to zero to avoid division errors.

Particle Velocity Nodes

[TODO: Eric – when I ran through the tutorial using the Unity template in latest 2020, the sample graph at the above point was slightly different. Is the screenshot above enough for the reader to see the changes required, now that they’ve been introduced to all the elements. Or do we need to explain further?]

Save the graph and return to the Game view.

Select HeartOfHearts in the Hierarchy and set up its Properties in the inspector. Check each property to enable it. Set the Count to 500. Copy the gradient you used for BoxOfHearts.

Save the scene, click Play and test your new controls.

ButterHearts spawning in a sphere

Next, you’ll play with the shape your butterhearts use when they spawn.

Customizing Spawn Shapes

Spawning from a sphere works, but it would be more interesting to use a Point Cache to control where particles spawn. In this case, you’ll make them appear in the shape of a heart.

To create a Point Cache, navigate to Window ▸ Visual Effects ▸ Utilities ▸ Point Cache Bake Tool. Set the Bake Mode to Texture, then select butterheartfull from the RW/Sprites folder. Set the Threshold to 0.9. Then, save the new file to RW/PointCaches and name it butterheartfull.

Point Cache Bake Tool

Open the HeartOfHearts graph and add a Point Cache Node. Then, assign the butterheartfull asset from the PointCaches folder.

In the Initialize Particle Block, replace the Add Position (Sphere) Block with a Set Position from Map Block. Then, connect the Point Cache Node to the Attribute Map input and set the Value Scale to (X:2, Y:2, Z:1).

Note: Make sure the Set Position from Map block is at the top of the Initialize Particle block. Otherwise you may see a warning in the console, and no butterhearts on screen!

Using a Point Cache in the Initialize Block

Because the graph no longer uses Radius, remove it from the Blackboard.

In the Update Particle Block, also remove the Tile/Warp Positions Block.

Save the graph, then return to the Game view.

Make sure you’ve enabled the HeartLight and the BoxOfHearts.

Now, save the scene and the project.

Click Play and experiment with the input keys to trigger new flocks of butterhearts and toggle their active state. You’re now making hearts fly with Unity VFX Graph!

ButterHearts spawning in a heart shape