Search Unity

VFX Graph - How can I dynamically stop specific events?

Discussion in 'General Graphics' started by turboturboturbo, Jan 22, 2020.

  1. turboturboturbo

    turboturboturbo

    Joined:
    Dec 2, 2018
    Posts:
    25
    I want to create X number of particle emissions.
    Each emission varies in color, and position.

    In my VFX Graph instance I create these emissions like so:

    Code (CSharp):
    1.     public void CreateEmission(Color color, Vector3 position)
    2.     {
    3.         VFXEventAttribute _attrib = vfx.CreateVFXEventAttribute();
    4.         _attrib.SetVector3("position", position);
    5.         _attrib.SetVector3("color", new Vector3(color.r, color.g, color.b));
    6.         vfx.SendEvent("OnManualSpawn", _attrib);
    7.     }
    8.  
    So let's say I call this 3 times, I now have 3 different emissions running.


    Now I want to dynamically stop emission #1. How can I do this?

    Currently I am instantiating and then destroying a new VFX Graph instance for every event! But this seems wrong. Is it possible to do this within a single VFX Graph instance??
     
    Last edited: Jan 23, 2020
    ggama likes this.
  2. ggama

    ggama

    Joined:
    Jun 4, 2021
    Posts:
    10
    Hey, so I've had a similar problem and solved it using the Set Alive Block on Update Particle. Since VFX Graph has not an array/list as a parameter I've also made a workaround using the bits of multiple Integer parameters, 1 particle is alive / 0 particle should die.
    Since my solution only required at maximum 88 particle's IDs I've used 3 Integers (since 32bits * 3 is enough).

    Explaining briefly:

    In my Graph's Blackboard I have 3 Integers "Matrix" which will store the alive state for each particle ID (0-31;32-61;62-88-...). And the Id of each particle invoked per event.
    upload_2022-1-30_21-29-27.png

    For storing the particle self ID (single per event) I set the Mesh Index Attribute to my NoteIndex parameter.

    upload_2022-1-30_21-32-4.png


    [continuing in the below comment due max photos limitation]
     

    Attached Files:

  3. ggama

    ggama

    Joined:
    Jun 4, 2021
    Posts:
    10
    [...]

    Breaking it down in a single segment (0 to 31 IDs). I apply a right shift based on the index stored as meshIndex and apply a bitwise AND. To this result I compare if it is equal to 1 (alive) or 0 (to die/to stop).
    upload_2022-1-30_21-35-16.png

    Applying this to all segments:
    upload_2022-1-30_21-39-24.png

    Lastly in the code I set the particle ID in the NoteIndex parameter and update the corresponding segment/matrix before raising the Event:

    Code (CSharp):
    1.  
    2. int notesMatrix1 = 0, notesMatrix2 = 0, notesMatrix3 = 0;
    3. int noteIndexId, pressEventId;
    4.  
    5.     private void Awake()
    6.     {
    7.         pressEventId = Shader.PropertyToID("Note");
    8.         noteIndexId = Shader.PropertyToID("NoteIndex");
    9.     }
    10.  
    11.  
    12.  
    13.     public void ToggleNote(bool toActive, int noteIndex)
    14.     {
    15.         noteIndex -= 21;
    16.  
    17.         if (toActive)
    18.             Debug.LogWarning($"Toggle Note {noteIndex}");
    19.  
    20.         if (noteIndex > 61)
    21.         {
    22.             SetMatrix(toActive, noteIndex, ref notesMatrix3);
    23.             visualEffect.SetInt("NotesMatrix3", notesMatrix3);
    24.         }
    25.         else if (noteIndex > 31)
    26.         {
    27.             SetMatrix(toActive, noteIndex, ref notesMatrix2);
    28.             visualEffect.SetInt("NotesMatrix2", notesMatrix2);
    29.         }
    30.         else
    31.         {
    32.             SetMatrix(toActive, noteIndex, ref notesMatrix1);
    33.             visualEffect.SetInt("NotesMatrix1", notesMatrix1);
    34.         }
    35.  
    36.         if (toActive)
    37.         {
    38.             visualEffect.SetInt(noteIndexId, noteIndex);
    39.             visualEffect.SendEvent(pressEventId, eventAttribute);
    40.         }
    41.     }
    42.  
    43.  
    44.     private void SetMatrix(bool noteActive, int index, ref int matrix)
    45.     {
    46.         if (!noteActive) matrix &= ~(1 << index); else matrix |= 1 << index;
    47.     }
    For killing the particle with the x ID, you simply set that bit to zero and update the corresponding matrix.