Spawn Over Distance is causing GC spikes

I am getting continuous Garbage Collection spikes with the Spawn Over Distance node. Frame rate jumps down a lot when this happens. Any ideas on how to prevent this, am I doing something wrong to cause this? Thanks!

FYI - this still hasn’t been addressed in Unity 2022.1.16

Hello,
Sorry for the late answer, we missed the initial message.
The block SpawnOverDistance relies on VFXSpawnerCallbacks interface, within the VisualEffectGraph package, there are a few blocks implemented this way :

For performance, when possible, we recommend avoiding usage of these spawn blocks for two reasons:

  • This unexpected garbage (which is actually an issue, you can track the resolution here)
  • These blocks are forcing the VisualEffect component update to be processed on the main thread (with current implementation of VFXSpawnerCallbacks)

However, the behavior of spawn over distance can generally be emulated using graph:
8442167--1119038--_SpawnOverDistance.gif

We are aware this VFX looks like a convoluted workaround but, even if the unexpected garbage is solved, the resolution of the performance issue with SpawnOverDistance will probably internally produce the same kind of graph.

8442167–1119026–SpawnOverDistance.unitypackage (12.6 KB)

1 Like

Thanks for the quick response.

This is interesting use of spawn context! I had no idea I could even do that. Does spawn context runs every frame and checks it’s spawnCount to emit particles and this is all it does?

Yes, the spawn context is run for every frame update and the spawnCount attribute is accumulated, when it reaches a value greater than 1, then the following context (generally an Initialize Context) receive a hit.

There is one subtlety, the update is processed whatever the Loop State of the Spawn Context, the VFXSpawnerState.playing is actually equivalent with loopState == VFXSpawnerLoopState.Looping (this behavior was used in LoopAndDelay to stop or reenable playing)

To illustrate this point, here an exemple of block Constant Rate emulated within the graph, it can help to understand how it works behind the curtain:
8444162--1119434--_Emulate_Constant_Spawn_Rate.gif

8444162–1119413–Constant_Rate_Emulator.unitypackage (6.58 KB)

1 Like

I have a problem with this, my VFX is Instantiated and that seems to cause the

The above change however causes a few other issues:

  • spawning in a prefab with the VFX the on it causes an initial burst of all the particles at the spawn position.
  • doing this (pic below) no longer works as from what I can tell Get Attribute oldPosition (Source) now is always 0,0,0.
    8446046--1119950--upload_2022-9-17_9-52-40.png

8446046--1119953--upload_2022-9-17_10-0-59.png

The workaround I showed previously doesn’t take the initial state into account. You can mimic the behavior of SpawnOverDistance testing the SpawnState.newLoop value, it will initialize old position with current position:
8449247--1120727--SpawnOverDistance_With_Init_Smaller.gif

This approach probably enough for most usage but it doesn’t strictly emulate the behavior of SpawnOverDistance, I’ve quickly tried an equivalent graph of this implementation but it’s probably partially wrong because it doesn’t exactly fit the spawn rate of the custom callback (every red square are supposed to have a yellow triangle inside):
8449247--1120730--_advanced_emulation.gif
I don’t expect such a complexity needed for the general purpose.

About this, I’m not sure to understand the problem, it should be (0,0,0) only during the first frame, if you are using a really recent Unity version and enabled instancing, it could be related to this issue.

All in all, the problem with unexpected garbage creating spikes in GC has been identified, you can follow this issue.

8449247–1120733–SpawnOverDistance_Variants.unitypackage (34.6 KB)

3 Likes

thanks again, this has been the best support I’ve ever received from Unity.

3 Likes