Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

ParticleSystem.ColliderData.GetCollider(int particleIndesx, int colliderIndex) returns null.

Discussion in 'General Graphics' started by chriseck, Aug 8, 2021.

  1. chriseck

    chriseck

    Joined:
    Nov 6, 2020
    Posts:
    3
    I would like to find out why it returns null and more importantly how I get to the collider of the object I hit.

    My setup:



    (Attached to the shooting particle system)
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Gamekit3D;
    5. using System;
    6. using System.Linq;
    7.  
    8. [RequireComponent(typeof(ParticleSystem))]
    9. public class DamagingParticleTriggerListener : MonoBehaviour
    10. {
    11.     [SerializeProperty("DamageAmount")] float damageAmount;
    12.     public float DamageAmount { get; internal set; } = 1;
    13.     public Damageable owner;
    14.     private ParticleSystem myParticleSystem;
    15.     private List<ParticleCollisionEvent> collisionEvents;
    16.     protected VList<Damageable> hittables;
    17.  
    18.     void Start()
    19.     {
    20.         myParticleSystem = GetComponent<ParticleSystem>();
    21.         collisionEvents = new List<ParticleCollisionEvent>();
    22.         hittables = FindObjectsOfType<Damageable>().ToVList();
    23.         hittables -= hittables.Where((damageable) =>
    24.         {
    25.             if (damageable == null) Debug.LogWarning(String.Format("'{0}' found an object in the {4} Script with a {1} owned by '{2}' that is null. Que???", name, nameof(Damageable), damageable.name, typeof(DamagingParticleTriggerListener)));
    26.             else
    27.             {
    28.                 if (owner == null) Debug.LogWarning(String.Format("'{0}' found in the {1} Script that {2} is null. Que???", name, nameof(DamagingParticleTriggerListener), nameof(owner)));
    29.                 else return damageable.team == owner.team;
    30.             }
    31.             return false;
    32.         });
    33.  
    34.         ParticleSystem.TriggerModule particleSysTrigger = myParticleSystem.trigger;
    35.  
    36.         foreach (Component component in hittables) particleSysTrigger.AddCollider(component);
    37.     }
    38.  
    39.     void OnParticleTrigger()
    40.     {
    41.         // Get all of the systems particles entering one of the given triggers this frame
    42.         List<ParticleSystem.Particle> particlesTriggeredEntered = new List<ParticleSystem.Particle>();
    43.         int numEntered = myParticleSystem.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, particlesTriggeredEntered, out ParticleSystem.ColliderData insideData);
    44.  
    45.         // Iterate over these particles, send a damage message to all hit triggers and destroy the particle by setting its remaining lifetime to 0
    46.         for (int particleIndex = 0; particleIndex < numEntered; particleIndex++)
    47.         {
    48.             for (int colliderIndex = 0; colliderIndex < insideData.GetColliderCount(particleIndex); colliderIndex++)
    49.             {
    50.                 Component collider = insideData.GetCollider(particleIndex, colliderIndex);
    51.                 if (collider != null) SendDamageMessage(collider.gameObject);
    52.                 else Debug.LogWarning(string.Format("'{0}' hit something that doesn't exist.", name));
    53.  
    54.                 ParticleSystem.Particle particle = particlesTriggeredEntered[particleIndex];
    55.                 particle.remainingLifetime = 0;
    56.             }
    57.         }
    58.  
    59.         // Push the remainingLifetime = 0 particles into the system, replacing the old particles.
    60.         myParticleSystem.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, particlesTriggeredEntered);
    61.     }
    62.     void SendDamageMessage(GameObject other)
    63.     {
    64.         if (!other.TryGetComponent(out Damageable theHurtOne))
    65.         {
    66.             return;
    67.         }
    68.  
    69.         Damageable.HealthInteractionMessage message = new Damageable.HealthInteractionMessage()
    70.         {
    71.             difference = -DamageAmount,
    72.             damager = this,
    73.             direction = Vector3.up,
    74.             stopCamera = false,
    75.             AppliesToTeamsX = (Damageable.Teams)(!(owner is null) ? owner.team != 0 ? 4/*~(owner.team)*/ : 0 : 0)
    76.         };
    77.  
    78.         theHurtOne.ApplyHealthInteraction(message);
    79.     }
    80. }
    81.  
    Note: VList is a custom defined List<T> wrapper, inheriting from List<T> and overloading all bitwise operators, "-=" in this case amounts to
    Code (CSharp):
    1. public static VList<T> operator -(VList<T> a, IEnumerable<T> b)
    2.     {
    3.         return new VList<T>(a.Where((x) => !b.Contains(x)));
    4.     }
    5.  
    Results while Debugging:
    When I shoot someone of my team, the particle passes through the target. Yay!
    When I slow down the particles and walk through them, nothing happens. Yay!

    When I shoot someone of the opposing team it triggers the "hit something that doesn't exist."-warning, I set for when ParticleSystem.ColliderData.GetCollider(int particleIndesx, int colliderIndex) returns null. :(
    The particle moves through the opposing player. :(
    Nay...

    No other Logs are in the Debug Log.

    Thanks to everyone helping!
     
    Last edited: Aug 8, 2021
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
    Hmm this is interesting.. if we are saying you have interacted with a collider, it seems to me that it must be a bug if we then give you a null collider.

    Are you able to submit a bug report?
     
  3. chriseck

    chriseck

    Joined:
    Nov 6, 2020
    Posts:
    3
    Did so through the link below your reply: Case 1356510
     
    richardkettlewell likes this.
  4. chriseck

    chriseck

    Joined:
    Nov 6, 2020
    Posts:
    3
    What do you think, would be a workaround?