Visual Effect Graph - disable loop, add delay

Something that I can’t find in VFX Graph are these two options known from Particle System - Loop (bool) and Delay (float). I’m working on a spell effects and wanted to switch from PS to VFX Graph for better performance and visuals. Because spells are one time use, there should be almost no looping and some delay between stages while casting a spell. I know there is “Loop and delay” node but that delay works after first loop.
Anything helpful about this topic that doesn’t involve tons of events and coroutines?

1 Like

Hi, I was looking for the solution of a similar problem. I want to control the Constant spawn rate to endure a determined amount of time. But for your case, did you try using a “Single Burst” spawn block instead of a constant rate? you have in there a delay that you can control.

Not really what I’m aiming for. This is still burst, while I need delay before spawn / initialization and constant spawn for given duration, without looping.
Thank you for the suggestion tho.
If there is no other way than using scripts then I’ll do that.

ahh, then what you need is similar to what I need. I want a constant rate of particles, lets say 25.000 per sec, but not forever, I want that for a determined duration, like 3 seconds, and then die off.

Hey, I found out that you can “sort of” control the death of your “constant rate” spawn system by putting a Kill block at the end of the Update context, and control when to kill using a periodic time node of X number of seconds.
The system never stops looping but kills all particles smoothly and starts again. with this and some proper on/off coding to spawn and kill the system I think you should achieve your goal, right?

If I’m forced to use scripts then here is a simple Duration controller. Make sure to add new float parameter named “Rate”, make it exposed and attach to your Constant Spawn Rate.
Then attach this script to Visual Effect object, set duration, check if you want smooth spawn rate reduction or instant stop, check if you want to destroy that object when duration ends and that’s it.
This resolves Duration and Loop issue, only Delay left.

using UnityEngine;
using UnityEngine.Experimental.VFX;

[RequireComponent(typeof(VisualEffect))]
public class VFX_DurationProperty : MonoBehaviour
{
    public float duration = 5.0f;
    public bool smooth = false;
    public bool destroyOnEnd = false;

    private float rate;
    private float count;
    private VisualEffect visualEffect;

    private void Start()
    {
        visualEffect = GetComponent<VisualEffect>();

        if (!visualEffect.HasFloat("Rate"))
            throw new System.Exception("Visual Effect missing exposed parameter type float with name 'Rate'");

        rate = visualEffect.GetFloat("Rate");

        if (destroyOnEnd)
            Destroy(gameObject, duration);
    }

    private void Update()
    {
        if (visualEffect.HasFloat("Rate"))
        {
            count += Time.deltaTime;
            if (smooth)
            {
                if (count < duration)
                {
                    rate -= count;
                    visualEffect.SetFloat("Rate", rate);
                }
            }
            else
            {
                if (count >= duration)
                {
                    visualEffect.SetFloat("Rate", 0);
                }
            }
        }
    }
}

Hi All,

Indeed the Loop and Delay block was a temporary prototype solution before we switched to actual behavior in Spawn Contexts. As for 2019.3, all this functionality will move into the Spawn Context settings (Check the inspector when selecting a Context for more dropdown’s). We have implemented a delay before loop, and after loop, (and even both)

Right now internal sequencing is a bit bare metal and should be better next year.

In the meantime, if you need to create sync points between your systems you can use chained spawn contexts by having a master spawn that will connect to other spawn start inputs. Every time the master spawn will spawn 1, it will hit the other other spawn context’s start input, thus restarting them.

So if you put a periodic burst with constant count of 1 t and a random delay on the master spawn, all others will spawn based on the random delay of the master.

(And you can even also perform Set EventAttribute Random in the master spawn to compute global values that are transmitted to all systems, and that you can read using Get Attribute (Source Location) or Inherit Blocks)

2 Likes

Great! I’m glad that this won’t get unnoticed and future updates will be provided with these features.