Getting the Collider in a Particle System Trigger event

Hello everyone.
So I have this game, and it includes a particle system with it’s trigger module enabled. I need this particle system to return trigger enter callbacks that include information on the colliders that the particles have entered.
However, OnParticleTrigger() provides no such information.

Is there anyway for me to get information on the colliders that the particles have entered?
If not, is there any other method that would substitute for a trigger module system on a particle system that would provide information on the colliders that the particles are entering?

3 Likes

Can’t you use OnParticleCollision?

It’s odd that the Trigger Module allows you to add to a list of possible colliders, but that there’s no simple way to return which of those colliders were triggered in OnParticleTrigger. So the particle system has to react the same way for ALL of the colliders vs. something unique to EACH collider (e.g., change to the color of the thing you’re colliding with).

The cool thing about OnParticleTrigger is that it allows you to Get and SetTriggerParticles so you can manipulate the particles themselves.

By contrast, with OnParticleCollision, you get access to CollisionEvents, not the particles themselves. So you know where they hit and how fast they were going, but you don’t have a reference to manipulate them.

1 Like

May someone send here a link to do it the “Hard” way, because my game isn’t working really great with OnParticleCollision. would be nice

I had run into a similar conundrum with the “relatively” new particle system.
It used to be that you could do something like this with the older iterations of Unity:

function OnTriggerEnter(hit:Collider){
    if (hit.gameObject.tag == "ground") {
        particle.emit=true;
        particle2.emit=true;
    }
}
function OnTriggerExit(hit:Collider){
    if (hit.gameObject.tag == "ground") {
        particle.emit=false;
        particle2.emit=false;
    }
}

( Code above is via this older forum post )
Which was super useful and easy to “cull out” things that you just didn’t want to trigger an “impact”.
However, the more recent particle system collision module uses “Layers” to define what is an what is not going to collide so you don’t have to write the code.

Anywho…here is what you need to do to “cull” out specific objects in your game/scene:


When you are editing your “parent” particle system’s collision module (i.e. the system “colliding”), you will notice the “Collides With” property under the “Collision Quality” property. At first, I wasn’t sure what this was for as a bunch of layer names I wasn’t familiar with popped up, but then I later realized that this was because during one of my “package imports” from the asset store (at some point) one of the packages evidently “over wrote” my project’s pre-defined layers…which was a bit frustrating.

Either case, above you will see that I have only selected the layer called “Terrain” and as well the Terrain in this example is assigned to the “Terrain” layer.
6051773--654614--upload_2020-7-3_8-7-24.png
In the example above the “BloodSpew” particles only collide with any GameObject that is assigned to the “Terrain” layer. When I tested it in a scene, sure enough any GameObject that didn’t have the “Terrain” Layer assigned to it the collision module ignored. You can create a huge number of layer names, and as such this just happens to be the name I used at the time I was writing this.

Either case, I think that the newer particle system’s OnParticleCollision method isn’t designed specifically to provide you with all collision data (that is already handled with the Layers stuff, which is simple enough), and that the “Collision Message” option is strictly to allow one the ability to adjust the behavior of the particles based on the, at first, seemingly limited collision information.

So…just in case someone else runs into this conundrum where you are expecting to have to “cull particle collisions” by hand/code, it would seem that culling is handled via Layers and “behavior” is handled via the message system (which makes sense because everything is heading more towards a “Data Oriented Technology Stack” design).
In the end, with this newer design you don’t have to do thousands of “slow string compares” (or the like) to determine if you should or should not allow a particle to collide with something. I am sure this approach greatly helps with over-all performance in the end.

However, if you have some form of “unique element” you are trying to accomplish (i.e. like changing the behavior of a particle collision based on the material type of the thing you are colliding with) then the older way of doing things becomes “more useful” again…but I am still finding the subtle nuances of the more recent Unity iteration and there might very well be a way to handle this as well. If not, then it might be something to come in a future version, but for most cases everything you need to get some pretty cool results is there…just the way you go about achieving the same thing is a little different (for those who were familiar with older iterations of Unity).

Anyway, thought posting this info might help someone new to Unity and/or familiar with the older iterations of Unity figure out how to better utilize the newer particle system Collision Module and how to “prevent and/or limit collision with certain GameObjects”.

Cheers,

Noel

1 Like

This is what I used to overcome this problem maybe it helps someone.
I was using it to make my player die when colliding with a certain particle.
I put this code in a script which is attached to the particle system and in the triggers module I dragged in the gameobject of my player prefab.
Component is the base class for all colliders so this works for any type of collider.

    private void OnParticleTrigger()
    {
        ParticleSystem ps = GetComponent<ParticleSystem>();
        Component component = ps.trigger.GetCollider(0);
        component.GetComponent<CollisionBase>().Dead = true;
    }
6 Likes

GENIUS! Been looking all over for this simple bit of code! THANK YOU

I got stucked on a case that is reversed to this problem. I have a player that casts spell using trigger particle that needs to damage enemies (that is spawned into the map). I cannot add all the colliders to the list beforehand. And I dont think it is wise to add and remove all the enemies that are spawned / despawned to this list of a single particle. Unity should provide these trigger data via callback function.

6 Likes

I am needing a solution to this problem, and Lestercodes’ solution doesn’t work because it just returns the first collider in the list, rather than actually detecting which is the one that is being collided with.

Since there doesn’t currently seem to be a solution, I’m going to try just instantiating GameObjects instead of using the Particle System, which would solve the problem (even if it sacrifices performance.)

If a solution is developed, I’d be very interested.