ArtificialNiko
ArtificialNiko

Reputation: 1

ParticleSystem find neighbouring Particles with OnParticleTrigger()

Is it possible to call OnParticleTrigger() multiple times per frame?

I am working on a particle system where each particle counts it neighbour particles and acts accordingly to it. For this purpose i created a empty gameobject with Circle Collider 2D (Game is 2D) and iterate its position to each particle postion.

So that the OnParticleTrigger() function is called for each particle and counts neighbours in this particle position. Then jumps into the next position of the particle system. I would like to have up to 10 000 particles so thats why i don't want to create for each particle its one collider. Yet i am only succeeding in counting the neighbours at one partice per frame so far because the PhysicsEngine of Unity just gives me once per frame the trigger information.

Any Ideas how I can call it multiple times? Or if there is a simpler solution for counting neighbour particles in the Unity particle system i am also open :D

         //In update: iterating over all particle positions at each frame
         InitializeIfNeeded();
         numParticlesAlive = m_System.GetParticles(m_Particles);
         while (h < numParticlesAlive)
         {
             if (triggered)
             {
                 Colly.transform.position = m_Particles[h].position;

                 cp = m_Particles[h].position;
                 h++;
                 triggered = false;

             }

         }

In this way just for one collider position per frame the function void OnParticleTrigger() is called... so i can count the neighbours just of one particle per frame.

Thank you for your help!

Upvotes: 0

Views: 1082

Answers (1)

Programmer
Programmer

Reputation: 125315

Is it possible to call OnParticleTrigger() multiple times per frame?

No, even if it is possibly, you shouldn't be calling any Unity callback function.

You should look into Unity's ParticlePhysicsExtensions class which has the GetTriggerParticles function that can help do this.

This is tricky but can be done with the following steps:

Use Sphere GameObject with a Sphere Collider. This Sphere Collider you can use to determine which particles are closer to each other. Any particle that is inside the sphere is considered to be closer to other particles that are inside the Sphere.

1.Create a Sphere then plug in into the Colliders slot in the Triggers module in Particle System. Position it to where it should detect the particles then disable its Mesh Renderer.

2.On the Triggers Module, make sure that Inside, Outside, Enter and Exit are set to Callback.

enter image description here

3.Get the particles that just Entered inside the Sphere with

ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Enter, enter);

4.Loop through the particles that are inside the Sphere(Particles from #3):

In each loop:

A.Move the Sphere position to the current particle loop

B.Get the particles that are inside the Sphere with

ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Inside, neighbouringParticles);

These are considered to be the neighbouring particles. After this, just move the Sphere back to its default position.

Here is an example of what you should do:

public GameObject SphereParticleCollider;

List<ParticleSystem.Particle> enter = new List<ParticleSystem.Particle>();
List<ParticleSystem.Particle> neighbouringParticles = new List<ParticleSystem.Particle>();
ParticleSystem mainParticle;

private void Start()
{
    mainParticle = GetComponent<ParticleSystem>();
}

void OnParticleTrigger()
{
    //Get particles that entered 
    findEnteredParticles();

    //Get neighbouring particles 
    findNeighbouringParticles();
}

void findEnteredParticles()
{
    if (mainParticle == null)
    {
        mainParticle = GetComponent<ParticleSystem>();
    }
    ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Enter, enter);
}

void findNeighbouringParticles()
{
    //Get default Spehere Collider position
    Vector3 currentParticleCollider = SphereParticleCollider.transform.position;

    //Find particles that are Neighbour of each particle that entererd
    for (int i = 0; i < enter.Count; i++)
    {
        //Move Spehere Collider to the positon of each particle that enetered
        SphereParticleCollider.transform.position = enter[i].position;

        //Finally get all particles that are inside the Sphere. These are considered to be near the particle
        ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Inside, neighbouringParticles);

        //Loop through and do something with each neighbouring particles 
        for (int j = 0; j < neighbouringParticles.Count; j++)
        {
            ParticleSystem.Particle neighbourParticles = neighbouringParticles[j];
            //.....
            //......
            //.....
            Debug.Log("Found neighbouring particles!");
        }
    }

    //Reset the position of the Spehere Collider position
    SphereParticleCollider.transform.position = currentParticleCollider;
}

Upvotes: 0

Related Questions