Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Essential · Jun 22, 2012 at 08:03 PM · particlesdestroyparticlesystemshurikenlifetime

How to destroy / hide a single particle?

I tried using ParticleSystem.SetParticles to change the lifetime of a particle, but it reset the other particles. Is there a way to simply destroy / hide / move one particle without resetting the system?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by Wolfram · Jun 22, 2012 at 08:26 PM

What exactly did you do? As with the old system, I would guess you first have to get all current particles with ParticleSystem.GetParticles, then remove the particle you want from that array somehow, and then reassign that new array back to the ParticleSystem (but read on).

In the old particle system (ParticleEmitter), instead of removing the particle physically from the array, it was enough to set its energy to 0. This way the ParticleEmitter will take care of the rest, recognize the particle als being dead/finished, and remove it itself from its internal particle array. I would assume you can do the same with Shuriken?

EDIT: I tested this now for myself. The Shuriken works the same as the old system, you can modify/remove/add individual particles. BUT the API call to get the existing particles is just plain weird and stupid, I have no idea why anyone would program it in such a way: Instead of simply returning the particles array, which you then can modify, you must provide your own array, which is passed to GetParticles(). After this call returns, your particles array has been filled with the information of the existing ParticleSystem. This is completely unintuitive, and would probably be frowned upon and discouraged in any programming guide, to call a function "GetXXX", but then have it modify an array you have to initialize and pass into it.

tl;dr: Try this example instead, it will work. Create a new ParticleSystem with default emission behaviour, and attach this script to it. (Note, when using the menu GameObject->CreateOther->ParticleSystem, the ParticleSystem will initially have an x=270 rotation, for whatever reason)

 using UnityEngine;
 using System.Collections;
 
 public class ParticleSystemTest : MonoBehaviour {
     
     private ParticleSystem ps;
     
     void Start () {
         ps=GetComponent<ParticleSystem>();
     }
     
     void Update () {
         // initialize an array the size of our current particle count
         ParticleSystem.Particle[] particles=new ParticleSystem.Particle[ps.particleCount];

         // *pass* this array to GetParticles...
         int num=ps.GetParticles(particles);
         Debug.Log("Found "+num+" active particles.");
         for(int i=0;i<num;i++){
             if(particles[i].position.z>5) // large local z: let particle drop down
                 particles[i].velocity-=Vector3.up*0.1f;
             if(particles[i].position.x>1) // positive x: make it red
                 particles[i].color=Color.red;
             if(particles[i].position.x<-1) // negative x: make it die
                 particles[i].lifetime=0;
         }
         // re-assign modified array
         ps.SetParticles(particles,num);
     }
 }

  
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Essential · Jun 22, 2012 at 08:35 PM 0
Share

This appears to do nothing...

 var particleTotal = 7;
 private var particles = new ParticleSystem.Particle[particleTotal];
 
 function Update ()
 {
     particlesLength = particleSystem.GetParticles(particles);
 
     particles[0].lifespan = 0;
     particles[1].color = Color.red;
     particles[2].position = Vector3.zero;
 
 }
avatar image Loius · Jun 22, 2012 at 08:42 PM 1
Share

You need to reassign the particle system.

particleSystem.SetParticles(particles,particles.length)

avatar image Essential · Jun 23, 2012 at 04:36 AM 0
Share

Yeah that's my problem Vicenti. When I do that, the particle system resets.

What I'm trying to achieve is a set of orbs that bounce out that the player can collect. They'll bounce out fine and will slowly disappear over the lifetime rate, and I can detect when a player has collected a particle. I just don't know how to make that individual particle disappear. Using SetParticles the particles all bounce out all over the place again and reset the lifespan.

avatar image Wolfram · Jun 25, 2012 at 03:47 PM 0
Share

Well, in the code fragment you posted you are creating an empty array of particles, so there won't be happening much. Usually, this array is initialized by the ParticleSystem. If you create your particles entirely by yourself, generate an empty array as you did, fill it with your desired values (without using GetParticles!), and then apply it with SetParticles, all this in some initialization routine such as Start().

Note that your code fragment shouldn't compile, since there is no property "lifespan", it is called "lifetime". Also note that in your code you set the first particle's lifetime to 0, so the ParticleSystem will automatically remove it before the next Update. This reduces the length of your particles array by one, and at a starting size of 7 you should be almost immediately run into an "array out of bounds" error.

avatar image JonathanBolten · Jan 26, 2014 at 03:46 AM 3
Share

There is nothing "weird and stupid" about filling an array passed to the particle system. That is how you avoid an expensive memory allocation every time you call GetParticles. No memory to allocate if you can reuse the same array.

Show more comments
avatar image
0

Answer by Essential · Jun 23, 2012 at 07:36 PM

So the more I research this, the more I'm beginning to believe that it's impossible to adjust the properties of a settled particle without the whole particle system starting the animation from scratch. If anyone could just confirm this that would be great. Then I can start investigating another option for my bouncing collectable coins...

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Wolfram · Jun 26, 2012 at 10:20 PM 0
Share

see my edited answer

avatar image coding_crow · Oct 04, 2014 at 01:40 PM 0
Share

I believe this ties into my question (http://answers.unity3d.com/questions/802603/can-i-force-shuriken-to-recalculate-its-bounds-pro.html). I too would like to call SetParticles() without the particleSystem resetting/stopping. I mention this because if you get it to work you might run into the next problem which is culling with scripted shuriken systems. $$anonymous$$aybe have a look.

avatar image
0

Answer by brilliancenp · Feb 27, 2014 at 03:41 AM

If what you are trying to do is make a particle dissapear on collision with a player object, or any object for that matter it can be done. It seems like it would be inefficient to do it this way but I have seen no slowdown and I have done this with systems with many particles.

The difference here is that I am using a monobehavior, below I will call it MyParticleSystem, to copy the particle array into its own array every update. So every update I am using the behaviors ParticleSystem.Particle[] to Get and set the particles. This way I can expose the array and have access to modify it between updates without having to worry about doing a particleSystem.SetParticles() at an odd time risking some unwanted behavior.

If you get the collision event using OnParticleCollision on the Player character.

 void OnParticleCollision(GameObject other)
     {
         ParticleSystem particleSystem = other.GetComponent<ParticleSystem>();
         MyParticleSystem mySystem = other.GetComponent<MyParticleSystem>();
         if(null != mySystem)
         {
                     //here we will get the particle list from the attached MyParticleSystem
             ParticleSystem.Particle[] points = mySystem.GetParticleList();
 
             ParticleSystem.CollisionEvent[] collisions = new ParticleSystem.CollisionEvent[particleSystem.safeCollisionEventSize];
             int numberOfCollisions = particleSystem.GetCollisionEvents(this.gameObject, collisions);
             int j = 0;    
             
             while(j < numberOfCollisions)
             {
                     //find the particle closest to the collision
                     Vector3 collisionLocation = collisions[j].intersection;
                     float closestDistanceToIntersect = float.MaxValue;
                         int closestParticleNumber = -1;
                         for(int i = 0; i < this.points.Length; i++)
                         {
                                 ParticleSystem.Particle p = points[i];
                             float distanceFromIntersect = Vector3.Distance(p.position, collisionLocation);
                             if(distanceFromIntersect < closestDistanceToIntersect)
                             {
                                 closestDistanceToIntersect = distanceFromIntersect;
                                 closestParticleNumber = i;
                             }            
                         }
                     //I am pretty sure lifetime has to be set to less than 0.0f to get rid of it
                     
                     points[closestParticleNumber].lifetime = -1;
                     
             }
             //assign the list back to the object
             mySystem.SetParticleList(points);
      }
    }

This works nicely for me. This is a much condensed version of what I use however. I am not saying it will work for systems with 2000+ particles I have tested with the upwards of 800-900 with no slowdown in a test environment. I found that if you dont use the behavior to keep track of the particle list then the OnParticleCollision script will have to use the particleSystem.GetParticles(particleArray[]) and particleSystem.SetParticles(particleArray[], arraylength). SetParticles will remove any particles with a lifetime < than 0 so if the collision script runs it can cause unwanted behavior sometimes.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Krutor · Oct 22, 2014 at 11:06 PM 0
Share

Looks like to be a smart solution, but I can not do it. Could you please describe a little wider the process?

avatar image jason706 · Aug 18, 2015 at 11:08 AM 0
Share

Apologies for the dumb question, im kinda new to this. whats the difference between: ParticleSystem particleSystem = other.GetComponent(); $$anonymous$$yParticleSystem mySystem = other.GetComponent<$$anonymous$$yParticleSystem>(); And what does each represent? Sorry, if this has already been answered.

avatar image jason706 · Aug 20, 2015 at 08:07 PM 0
Share

I keep trying to find GetParticleList(); but there's no documentation. How did you get this to work? Or is GetParticleList a substitute for something? I've tried several different methods of getting a particle list, but I keep getting steered towards particleCount, and the compiler rejects that every time. Same Issue trying to find SetParticleList. Was this ran on Shuriken, or Legacy? I'm using Unity 4.6.1p2.

Or If someone has a better way of accessing particles on a individual collision level from a game object. I am all ears.

Thanks everyone!!

avatar image Wolfram · Aug 20, 2015 at 09:20 PM 0
Share

$$anonymous$$yParticleSystem is a helper class @brilliancenp wrote, he did not post the code for it. Get/SetParticleList are methods defined in this class, so they are not Unity methods, or part of the Unity class ParticleSystem.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to destroy live particle in Shuriken 1 Answer

Shuriken particle System - change velocity by trigger 0 Answers

Particle System lifetime not affecting particles 0 Answers

Changing startRotation from ParticleSystem on script does not work 1 Answer

How to make particles react to movement of particle system 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges