0
\$\begingroup\$

I wrote a script to manage my Particle System emission. The starting lifespan is set to infinite so that the particle never dies until it reaches a specific collider. I didn't find any method to destroy a specific particle in the Unity Manual.

How can I do this?

Here's the code (updated to show the partial fix)

using UnityEngine;
using System.Collections.Generic;

public class PlayerDamage : MonoBehaviour
{
    private ParticleSystem ps;
    public List<ParticleCollisionEvent> collisionEvents;
    public int attackValue = 1;

    //
    [Range(0.0f, 100f)]
    public int maxParticles;
    public float particleLife;
    public bool neverDies;
    public float particleSpeed = 8.0F;


    void Start()
    {
        ps = GetComponent<ParticleSystem>();
        collisionEvents = new List<ParticleCollisionEvent>();
        //
        var collision = ps.collision;
        collision.enabled = true;
        collision.type = ParticleSystemCollisionType.World;
        collision.mode = ParticleSystemCollisionMode.Collision3D;
    }

    void OnParticleCollision(GameObject other)
    {
        int numCollisionEvents = ps.GetCollisionEvents(other, collisionEvents);

        Rigidbody rb = other.GetComponent<Rigidbody>();
        int i = 0;

        while (i < numCollisionEvents)
        {
            if (rb.CompareTag("Enemy"))
            {
                BaseHealth baseHealth = other.GetComponent<BaseHealth>();

                if (baseHealth != null)
                {
                    Vector3 pos = collisionEvents[i].intersection;
                    Vector3 force = collisionEvents[i].velocity;// * 10;
                    rb.AddForce(force);
                    baseHealth.TakeDamage(attackValue);
                }
            }
            i++;
        }
    }

    void Update()
    {
        var collision = ps.collision;
        collision.maxKillSpeed = particleSpeed;

        Debug.Log("Particles Alive Count: " + GetAliveParticles());

        ps.Emit(maxParticles);
        var main = ps.main;
        main.maxParticles = Mathf.RoundToInt(maxParticles);
        main.startLifetime = particleLife;

        if (neverDies)
        {
            particleLife = float.PositiveInfinity;
        }
        else
        {
            particleLife = 5f;
        }
    }



    int GetAliveParticles()
    {
        ParticleSystem.Particle[] particles = new ParticleSystem.Particle[ps.particleCount];
        return ps.GetParticles(particles);
    }
}
New contributor
bibrosko is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
  • \$\begingroup\$ Taking a look at the API, it doesn't look like there's an efficient way to do this. You'd need to iterate over the whole list of particles, comparing their positions to find the ones that struck this particular object. Can you tell us more about the effect you're trying to achieve? There might be simpler ways to accomplish the same outcome. \$\endgroup\$ – DMGregory Jan 12 at 20:37
  • \$\begingroup\$ i want to simulate dripping water. it starts dripping from a water source lowering the water source capacity, then it slides on the terrain and finally it reaches a lake gameObject. At this point the particle dies and raises the water amount int in the target. \$\endgroup\$ – bibrosko Jan 12 at 20:59
  • \$\begingroup\$ this solved partially the problem, but now i don't know how to access the collided object to modify its values (water amount) docs.unity3d.com/ScriptReference/… \$\endgroup\$ – bibrosko Jan 12 at 21:02
  • \$\begingroup\$ please guys, can i have an update on this? The particles collisions are not detected. Could it be because void OnParticleCollision is in conflict with the main module var main = ps.main;? Maybe i should write another question to show the complete code? \$\endgroup\$ – bibrosko Jan 14 at 17:24
  • \$\begingroup\$ Sounds like you can edit this question to show us how to reproduce the problem you're having. \$\endgroup\$ – DMGregory Jan 14 at 17:25
0
\$\begingroup\$

I solved the problem.

  1. The ps was missing a render material. Apparently this prevents the collisions to be detected.
  2. I activated Send Collision Messages in the Collision Module, without that it won't work.

Thanks all.

New contributor
bibrosko is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

Your Answer

bibrosko is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.