Search Unity

OnParticleTrigger Always Triggering

Discussion in 'Scripting' started by Nigey, Aug 21, 2018.

  1. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Hi Guys,

    I have 'OnParticleTrigger' always triggering, but when I try GetTriggerParticles on any ParticleSystemTriggerEventType, they all return empty. Has anyone seen this before?

    This is my code:

    Code (CSharp):
    1.         private void OnParticleTrigger()
    2.         {
    3.             if(Initialised)
    4.             {
    5.                 // get the particles which matched the trigger conditions this frame
    6.                 if(particleSystem.GetTriggerParticles(ParticleSystemTriggerEventType.Inside, detectedParticles) > 0)
    7.                 {
    8.                     detectedPPM = detectedParticles.Count;
    9.                     float percentageThroughLife = 0f;
    10.  
    11.                     for (int i = 0; i < detectedParticles.Count; i++)
    12.                     {
    13.                         ParticleSystem.Particle p = detectedParticles[i];
    14.  
    15.                         if (p.remainingLifetime / p.startLifetime > percentageThroughLife)
    16.                         {
    17.                             percentageThroughLife = p.remainingLifetime / p.startLifetime;
    18.                         }
    19.                         detectedParticles[i] = p;
    20.                     }
    21.  
    22.                     detectedPPM = sourcePPM * falloffRate.Evaluate(percentageThroughLife);
    23.  
    24.                     // re-assign the modified particles back into the particle system
    25.                     particleSystem.SetTriggerParticles(ParticleSystemTriggerEventType.Inside, detectedParticles);
    26.  
    27.                     // Only when the PPM calculations are done do you notify listening gas detectors.
    28.                     DetectionUpdate?.Invoke();
    29.                 }
    30.             }
    31.         }
    I'm using the NVidia Flex plugin, which is modifying the particles, but I can't see exactly what is changing the OnParticleTrigger method.

    Code (CSharp):
    1.     [ExecuteInEditMode]
    2.     [DisallowMultipleComponent]
    3.     [RequireComponent(typeof(ParticleSystem))]
    4.     [AddComponentMenu("Flex/Flex Particle Controller")]
    5.     public class FlexParticleController : MonoBehaviour
    6.     {
    7.         private FlexActor m_actor;
    8.         private ParticleSystem m_particleSystem;
    9.         private ParticleSystem.Particle[] m_particles = new ParticleSystem.Particle[0];
    10.  
    11.         #region Messages
    12.  
    13.         void OnEnable()
    14.         {
    15.             m_actor = GetComponent<FlexActor>();
    16.             if (m_actor)
    17.             {
    18.                 m_actor.onFlexUpdate += OnFlexUpdate;
    19.                 m_particleSystem = GetComponent<ParticleSystem>();
    20.                 if (m_particleSystem)
    21.                 {
    22.                     m_particleSystem.Emit(m_actor.indexCount);
    23.                     m_particleSystem.Stop();
    24.                 }
    25.             }
    26.         }
    27.  
    28.         void OnDisable()
    29.         {
    30.             if (m_actor)
    31.             {
    32.                 m_actor.onFlexUpdate -= OnFlexUpdate;
    33.                 m_actor = null;
    34.             }
    35.         }
    36.  
    37.         void Update()
    38.         {
    39.             var main = m_particleSystem.main;
    40.             main.simulationSpace = ParticleSystemSimulationSpace.World;
    41.             main.playOnAwake = false;
    42.             main.maxParticles = (m_actor && m_actor.asset) ? m_actor.asset.maxParticles : 0;
    43.             var emission = m_particleSystem.emission;
    44.             emission.enabled = false;
    45.             var shape = m_particleSystem.shape;
    46.             shape.enabled = false;
    47.             //m_particleSystem.Stop();
    48.         }
    49.  
    50.         void LateUpdate()
    51.         {
    52.             m_particleSystem.SetParticles(m_particles, m_particles.Length);
    53.         }
    54.  
    55.         #endregion
    56.  
    57.         #region Private
    58.  
    59.         void OnFlexUpdate(FlexContainer.ParticleData _particleData)
    60.         {
    61.             FlexActor actor = GetComponent<FlexActor>();
    62.             if (actor is FlexSourceActor)
    63.             {
    64.                 FlexSourceActor sourceActor = actor as FlexSourceActor;
    65.                 var main = m_particleSystem.main;
    66.                 float time = Time.time - Time.fixedTime;
    67.                 int[] indices = sourceActor.indices;
    68.                 int indexCount = sourceActor.indexCount;
    69.                 float[] ages = sourceActor.ages;
    70.                 m_particleSystem.Clear();
    71.                 m_particleSystem.Emit(indices.Length);
    72.                 if (m_particles.Length != indexCount) m_particles = new ParticleSystem.Particle[indexCount];
    73.                 float startLifetime = main.startLifetime.Evaluate(0);
    74.                 Color32 startColor = main.startColor.Evaluate(0);
    75.                 float startSize = main.startSize.Evaluate(0);
    76.                 for (int i = 0; i < indexCount; ++i)
    77.                 {
    78.                     ParticleSystem.Particle p = m_particles[i];
    79.                     p.velocity = _particleData.GetVelocity(indices[i]); ;
    80.                     p.position = (Vector3)_particleData.GetParticle(indices[i]) + p.velocity * (time - Time.fixedDeltaTime);
    81.                     p.remainingLifetime = ages[i] - time;
    82.                     p.startLifetime = startLifetime;
    83.                     p.startColor = startColor;
    84.                     p.startSize = startSize;
    85.                     m_particles[i] = p;
    86.                 }
    87.             }
    88.             else if (actor)
    89.             {
    90.                 var main = m_particleSystem.main;
    91.                 float time = Time.time - Time.fixedTime;
    92.                 int[] indices = actor.indices;
    93.                 int indexCount = actor.indexCount;
    94.                 if (m_particles.Length != indexCount) m_particles = new ParticleSystem.Particle[indexCount];
    95.                 Color32 startColor = main.startColor.Evaluate(0);
    96.                 float startSize = main.startSize.Evaluate(0);
    97.                 for (int i = 0; i < indexCount; ++i)
    98.                 {
    99.                     ParticleSystem.Particle p = m_particles[i];
    100.                     p.velocity = _particleData.GetVelocity(indices[i]);
    101.                     p.position = (Vector3)_particleData.GetParticle(indices[i]) + p.velocity * (time - Time.fixedDeltaTime);
    102.                     p.remainingLifetime = m_particleSystem.main.startLifetime.Evaluate(0);
    103.                     p.startLifetime = p.remainingLifetime;
    104.                     p.startColor = startColor;
    105.                     p.startSize = startSize;
    106.                     m_particles[i] = p;
    107.                 }
    108.             }
    109.             m_particleSystem.SetParticles(m_particles, m_particles.Length);
    110.         }
    111.         #endregion
    112.     }
    Any thoughts guys?
     
    konsic likes this.
  2. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Shameless bump. Will work on myself and post anything I find in meantime.
     
  3. Crashhelmet

    Crashhelmet

    Joined:
    Mar 13, 2018
    Posts:
    5
    Hi Nigey, same issue here. I don't use any plugins for the particles.

    This code:
    Code (CSharp):
    1.     private void OnParticleTrigger()
    2.     {
    3.         Debug.Log("OnParticleTrigger");
    4.  
    5.         // particles
    6.         List<ParticleSystem.Particle> inside = new List<ParticleSystem.Particle>();
    7.         List<ParticleSystem.Particle> outside = new List<ParticleSystem.Particle>();
    8.         List<ParticleSystem.Particle> enter = new List<ParticleSystem.Particle>();
    9.         List<ParticleSystem.Particle> exit = new List<ParticleSystem.Particle>();
    10.  
    11.         // get
    12.         int numInside = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, inside);
    13.         int numOutside = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Exit, outside);
    14.         int numEnter = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, enter);
    15.         int numExit = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Exit, exit);
    16.  
    17.         Debug.LogFormat("inside ({0}) outside ({1}) enter ({2}) exit ({3})", numInside, numOutside, numEnter, numExit);
    18.     }
    Results in a lot of:
    "inside (0) outside (0) enter (0) exit (0)"

    ps.trigger settings:
    Inside > Ignore
    Outside > Ignore
    Enter > Callback
    Exit > Ignore

    edit: OnParticleTrigger also triggered when all set to Ignore
     
    Last edited: Nov 4, 2018
  4. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    @Crashhelmet that might be down to your configuration of the particles. Make sure that you have the collision module turned on in the particle system, and then make sure you've turned on world collision, and then dragged the collider you're intending the particles to hit into the particle system inspector where it shows an open space to do that. For me I had to make a workaround, but getting it to work with vanilla Unity is super easy.
     
  5. FuretUnity

    FuretUnity

    Joined:
    Mar 5, 2019
    Posts:
    1
    I've got the same issue :
    I want to detect a trigger collision between my particle system and a collider (who isTrigger).
    Everything seems well configured to me :
    - My particle system has a script attached with a method "void OnParticleTrigger()"
    - I use trigger.SetCollider to the box collider (which is IsTriger) I want to trigger to
    - My particle system trigger settings are all Ignore except Enter which is Callback
    But :
    - OnParticleTrigger() is called every frame (even if there is no trigger collision)
    - GetTriggerParticles() seems to always return 0 (even if there is trigger collision)
    And I can't find a workaround,
    Any idea to help ? Thank you in advance
     
  6. dotsquid

    dotsquid

    Joined:
    Aug 11, 2016
    Posts:
    224
    That's because your collider is a trigger.
    In previous versions of Unity (I used 2017.1) Trigger module was working with trigger colliders (how ironic), but not now.
    I've already reported about this backwards compatibility break.
     
    DaseinPhaos likes this.
  7. WildMaN

    WildMaN

    Joined:
    Jan 24, 2013
    Posts:
    128
    Same issue here, callback every frame even when all events set to Ignore. Any workarounds?
     
  8. chowness

    chowness

    Joined:
    Jan 2, 2020
    Posts:
    1
    Bump. Same issue here
     
  9. denholmspurr

    denholmspurr

    Joined:
    Apr 17, 2020
    Posts:
    42
  10. therobby3

    therobby3

    Joined:
    Jan 30, 2019
    Posts:
    131
    Also having the same issue here. The OnParticleTrigger is being called because the Enter callback is set, but when I check inside the OnParticleTrigger method how many particles triggered, I am getting 0. So the OnParticleTrigger method is being called even when the trigger wasn't tripped. Same problem as above.
     
  11. fran86

    fran86

    Joined:
    May 23, 2014
    Posts:
    1
    same issue here, OnParticleTrigger() is being called on every frame and getting 0 particles trigggered
     
  12. LazyEti

    LazyEti

    Joined:
    Sep 10, 2017
    Posts:
    7
    Exact same problem on my side (2019.3.14f1) this is clearly another broken feature.
    It's all the little things like this that makes unity so frustrating to work with : (
     
  13. RazNayr

    RazNayr

    Joined:
    Oct 17, 2019
    Posts:
    3
    Same here :D (2019.4.10f1)
     
  14. Tricc

    Tricc

    Joined:
    Feb 22, 2021
    Posts:
    1
    Same issue here, Version 2020.2.6f1
     
  15. NNSkelly

    NNSkelly

    Joined:
    Nov 16, 2015
    Posts:
    35
    New twist: one of my artists got a scene into a state where, early in run, particle collision/trigger works fine, but later in the run, particles are still rendering, I can see the colliders intersecting, OnParticleTrigger is being called, but the same GetTriggerParticles call that was previously returning particles is now returning 0/empty. He claims he "fixed" it by adjusting particle lifetime, but I'm mystified how particles which are still alive enough to render are not alive enough to trigger...

    Update: in my specific case, this looks like a bad interaction between the Timeline system and the Particle System. Once a Particle System on the Timeline with default settings (Timeline syncs the system's time to its own) hits its specified emitter Duration, things go a bit Screwy. If the Particle System is not set to Loop, then it looks like it keeps being driven to a time equal to its Duration, meaning triggers may occur but no time-dependent behavior of any sort is allowed to progress (presumably dt in all the internal sims becomes 0). If it IS set to Loop... at least in one run in my editor, everything starts to grind really hard. The devs obviously thought of this to some extent, since the tracks when selected have subtle ghosted HOLD or L2/L3/L4/... overlays, but... yeah this behavior is not ideal. Stopgap for some cases is to disable time synchronization in the Advanced breakout of the inspector and just let Timeline control whether the system is enabled or not.
     
    Last edited: Apr 6, 2021
  16. xqtr123

    xqtr123

    Joined:
    Jun 7, 2014
    Posts:
    20
  17. rebichini19

    rebichini19

    Joined:
    Aug 8, 2019
    Posts:
    2
    Same issue 2022.1.7. onParticleTrigger is always called. WHYYYYYY?????
    upload_2022-11-29_23-32-9.png
     
  18. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hi all, we had a bug where the callback would be called even if no events had passed the trigger conditions.
    It's fixed, and backports are in progress. You can follow it here: https://issuetracker.unity3d.com/is...nditions-are-set-to-ignore-or-any-other-value

    There is no backport planned for 2020.3 because no-one told us they need it in that version (yet). If you need it there, reply here and I will make the extra backport request.
     
  19. ujz

    ujz

    Joined:
    Feb 17, 2020
    Posts:
    29
    Using 2020.3.12f1 and got this issue. If I upgrade this bug will be fixed? Sorry not sure what backport means. Thank you.
     
  20. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,481