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

Particle Playground

Discussion in 'Assets and Asset Store' started by save, Dec 4, 2013.

  1. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Some interesting things about performance in the next update:

    Quite the bit optimizations in the making has proven simulations to be up to 1.5x faster and has reduced GC allocations up to 6x. Although this differs a bit depending on the scene setup, testing with 10 skinned meshes with separate simulated turbulence results in about 4,5x GC improvement and about 10 - 15 frames extra (using 4 CPUs). We can also see that 2 standard particle systems from previous version is about equally heavy as 10 in the new version. This looks promising to say the least, here's some overdone graphics to underline the results! :)



    We should be able to expect a lot better performance overall, more good news coming up later!
     
    overthere, MikeTon, hopeful and 2 others like this.
  2. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
  3. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392
    Hello

    Would you know how to destroy a specific particle when it is tapped?

    I am using Particle Playground's soap machine and I'm looking whether users can tap one of the soap bubbles and destroy it.

    Thanks
    German
     
  4. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi!
    You can use a Manipulator to track particles within a certain space, if you're looking to only kill one particle at a time you can single it out by comparing the distances of the contained particles within the Manipulator to its Transform. Here's an example script you can assign to the particle system:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using ParticlePlayground;
    5.  
    6. public class KillParticleOnClick : MonoBehaviour {
    7.  
    8.     PlaygroundParticlesC particles;
    9.     ManipulatorObjectC manipulator;
    10.     Transform manipulatorTransform;
    11.     Camera mainCamera;
    12.     Transform cameraTransform;
    13.  
    14.     void Start () {
    15.  
    16.         // Get the particle system component on this GameObject
    17.         particles = GetComponent<PlaygroundParticlesC>();
    18.  
    19.         // Create a new GameObject which will serve as the Manipulator's Transform
    20.         manipulatorTransform = new GameObject("Manipulator Transform").transform;
    21.  
    22.         // Create a new Local Manipulator on the particle system
    23.         manipulator = PlaygroundC.ManipulatorObject(manipulatorTransform, particles);
    24.  
    25.         // Setup the Manipulator
    26.         manipulator.trackParticles = true;
    27.         manipulator.type = MANIPULATORTYPEC.None;
    28.  
    29.         // We'll use the main camera to create a XY 'plane' on Z distance to the particle system and position the Manipulator's Transform
    30.         mainCamera = Camera.main;
    31.         cameraTransform = mainCamera.transform;
    32.     }
    33.    
    34.     void Update () {
    35.  
    36.         // Set the position of the Manipulator Transform
    37.         Vector3 inputPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, particles.particleSystemTransform.position.z-cameraTransform.position.z);
    38.         manipulatorTransform.position = mainCamera.ScreenToWorldPoint(inputPos);
    39.  
    40.         // Kill particle on interaction
    41.         if (Input.GetMouseButtonDown(0))
    42.             KillParticle();
    43.     }
    44.  
    45.     void KillParticle () {
    46.  
    47.         // Get particles in Manipulator
    48.         List<PlaygroundEventParticle> particlesInManipulator = manipulator.GetParticles();
    49.         int closestParticle = -1;
    50.         float closestDistance = 9999f;
    51.  
    52.         // Single out closest particle to the Manipulator's Transform
    53.         if (particlesInManipulator.Count > 1) {
    54.             for (int i = 0; i<particlesInManipulator.Count; i++) {
    55.                 float dist = (particlesInManipulator[i].position - manipulatorTransform.position).sqrMagnitude;
    56.                 if (dist < closestDistance) {
    57.                     closestDistance = dist;
    58.                     closestParticle = particlesInManipulator[i].particleId;
    59.                 }
    60.             }
    61.         } else if (particlesInManipulator.Count == 1)
    62.             closestParticle = particlesInManipulator[0].particleId;
    63.  
    64.         // Kill the closest particle found
    65.         if (closestParticle>-1) {
    66.             particles.Kill (closestParticle);
    67.         }
    68.     }
    69. }
    70.  


    You may need to edit the size of the Manipulator (manipulator.size) and how the inputPosition is done depending on your camera setup.

    You'll also find a more advanced example in the Examples/Example Scenes/Interactive/ folder called Manipulator Events where an Event is called on each particle kill.
     
  5. smou1328

    smou1328

    Joined:
    Jul 28, 2015
    Posts:
    11
    Hey there,
    first of all, thanks for the great work you put into this great plug-in! =)
    I wanted to aks if there is something like a hotfix out there for the texture sheet animation problem.
    I have a texture with 2 sprites on it (x=1, y=2) but no matter what settings i use in the texture sheet tab i end up with either one sprite or the other. And i tried "show shuriken" and editing it there, but with the same result unfortunately. If i set up the same thing as a standart shuriken system it works just fine (randomly choosing between the two).
    Whould gladly appreciate your help on this, because i really need this to work =)

    Thanks in advance,
    Flo

    PS.: Is it possible to simulate a particleplayground system at a certain time? like the simulate function with shuriken?
     
    Last edited: Jul 28, 2015
  6. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hey and thanks!
    Are you using version 2.26? This setup should work:

    Gives this (non-animated) result:


    You can prewarm a particle system which will simulate to a normalized lifetime, you'll find it in Advanced > On Enable > Prewarm. The Lifetime Cycles determine where in the cycle it should scrub to (for example 1.5 would be a full and a half lifetime cycle). The Cycles (Resolution) determines how many calculation cycles it should go through, which will be a resolution for how the particles have moved during prewarming. For a particle system with advanced forces you may need to amp this value up a bit to get a close end result.
     
  7. smou1328

    smou1328

    Joined:
    Jul 28, 2015
    Posts:
    11
    Thanks for the quick reply.
    ...It does work now, not only with your specific setting. My PC crashed before so i had to restart Unity, this must have fixed it ^^' Sorry for bothering you because of that.
    Ah, ok good to know! Because in my current case the Particle Systems have to be save and loadable at any given time. I will evaluate this in the next days.
     
  8. ArthurClark

    ArthurClark

    Joined:
    May 12, 2013
    Posts:
    15
    Hey!
    Is there a way to auto scale particles relatively to a whole system? I have a particle system that adds a trail to a model. The thing is this model is scaleable and scales pretty often and in large degree relatively to its initial size. In my current test situation I have a model that is scaled up to 5 times and the trail of particles is almost invisible because particles is too small. Can I make the particle system scale particles automatically? Also I emphasize that I know how to scale particle system. I need the way to scale particles themselves. Thank you!
     
  9. DominikAbe

    DominikAbe

    Joined:
    Mar 20, 2015
    Posts:
    5
    Hi,

    I wonder which is the easiest and most memory efficient solution for „saving/loading“ the state of a particle system.

    • I think with your system it would be possible to make a real state save? Which I would try to avoid because of the data size it would create.
    • Another solution would be using prewarming I guess? But I didn’t find the current lifecycle of a particle system yet. Where can I find it?
    • Or do you have any other solution/recommendation for saving/loading a system? I wouldn’t need a 100% correct solution.
    Thank you!
     
  10. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392

    Thanks a bunch for this! I really love Particle Playgrounds.

    If I need to add a second or third set of particles, say stars, etc, do I need to attach this script to each particle set? Would this be an efficient way to do it?

    Thanks again
     
  11. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392

    If you don't mind my asking, how can I improve the accuracy of the click? In my setup (using your script) bubbles are killed when clicking near or around the bubbles.

    Also, when I attached the script to, in my case three particle systems, a click could kill one than one bubble. Ideally, only one should be killed.

    Thanks
     
    Last edited: Jul 30, 2015
  12. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi!
    You could use a Manipulator around your model which scales only the birthing particles:

    Type: Property
    Property Type: Size
    Lifetime Filter: Enabled (0 - low value)

    By setting the Lifetime Filter you can ensure that your resizing only happens on newly birthed particles, if you for example can turn the other direction and intersect with previous particles which no longer should be affected.

    To set the Particle Size value of the Manipulator you can do this:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class ManipulatorParticleSize : MonoBehaviour {
    6.  
    7.     public PlaygroundParticlesC particles;
    8.     private ManipulatorObjectC _manipulator;
    9.  
    10.     void Start ()
    11.     {
    12.         // Cache the Manipulator reference at index
    13.         _manipulator = PlaygroundC.GetManipulator(0, particles);
    14.     }
    15.  
    16.     /// <summary>
    17.     /// Call this whenever you want to change the size of your particles within the Manipulator.
    18.     /// </summary>
    19.     public void SetParticleSize (float size)
    20.     {
    21.         _manipulator.property.size = size;
    22.     }
    23. }
    24.  
    For reference; If you need to scale all particles at once you can instead use particles.scale without any need for a Manipulator.

    Hi,
    You can try the implemented Save() and Load(int), this will store the current state of a particle system. This method is used for creating and loading Snapshots, where you also have the possibility to transition between states.
    The method is cloning the particle system and its cache, so it can be heavy in data size if you have a lot of particles in simulation, although quite fast as it saves and loads on separate threads.

    Prewarming can only be done when a particle system enables, where it will calculate the setup prewarmCycles on beforehand to the set prewarmTime which is a normalized value for a particle system's life cycle. I'm not sure if you could have use for that.

    There's a third possible solution in the making which has a much more efficient way of serializing particles. This is mainly used for recording / playback but could be used for single frame states as well. I will most likely implement compression, but it's still a bit early to tell if this will be in the first release. :)

    Generally if you want to affect particles from several particle systems you can instead use a Global Manipulator. However in this scenario I'm seeing some unexpected behavior with tracking particles globally and using the Kill() method, I'll dig into that to see what could be the issue. For now you can use separate Local Manipulators on each particle system but use the same Transform to control them.
    For better accuracy you could test the input position spherically from the particle using its position and size. Here's an updated example script you could try:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using ParticlePlayground;
    5.  
    6. public class KillParticleOnClick : MonoBehaviour {
    7.    
    8.     public PlaygroundParticlesC[] particles;        // Assign the particle systems in Inspector
    9.     ManipulatorObjectC[] manipulators;
    10.     Transform manipulatorTransform;
    11.     Camera mainCamera;
    12.     Transform cameraTransform;
    13.    
    14.     void Start () {
    15.  
    16.         // Create a new GameObject which will serve as the Manipulator's Transform
    17.         manipulatorTransform = new GameObject("Manipulator Transform").transform;
    18.  
    19.         manipulators = new ManipulatorObjectC[particles.Length];
    20.  
    21.         // Create and setup new Local Manipulators on the particle systems, they will all share the same Manipulator Transform
    22.         for (int i = 0; i<particles.Length; i++) {
    23.             manipulators[i] = PlaygroundC.ManipulatorObject(manipulatorTransform, particles[i]);
    24.             manipulators[i].trackParticles = true;
    25.             manipulators[i].type = MANIPULATORTYPEC.None;
    26.         }
    27.  
    28.         // We'll use the main camera to create a XY 'plane'
    29.         mainCamera = Camera.main;
    30.         cameraTransform = mainCamera.transform;
    31.     }
    32.    
    33.     void Update () {
    34.        
    35.         // Set the position of the Manipulator Transform
    36.         Vector3 inputPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, -cameraTransform.position.z);
    37.         manipulatorTransform.position = mainCamera.ScreenToWorldPoint(inputPos);
    38.        
    39.         // Kill particle on interaction
    40.         if (Input.GetMouseButtonDown(0))
    41.             KillParticle();
    42.     }
    43.    
    44.     void KillParticle () {
    45.  
    46.         for (int i = 0; i<manipulators.Length; i++) {
    47.  
    48.             // Get particles in the Manipulator
    49.             List<PlaygroundEventParticle> particlesInManipulator = manipulators[i].GetParticles();
    50.             int closestParticle = -1;
    51.             int particleSystemId = -1;
    52.             float closestDistance = 9999f;
    53.            
    54.             // Single out closest particle to the Manipulator's Transform
    55.             if (particlesInManipulator.Count > 0) {
    56.                 for (int x = 0; x<particlesInManipulator.Count; x++) {
    57.                     float dist = Vector3.Distance(particlesInManipulator[x].position, manipulatorTransform.position) *2f;
    58.  
    59.                     // Check that the particle is within range
    60.                     if (dist < closestDistance && dist <= particlesInManipulator[x].size) {
    61.                         closestDistance = dist;
    62.                         closestParticle = particlesInManipulator[x].particleId;
    63.                         particleSystemId = particlesInManipulator[x].particleSystemId;
    64.                     }
    65.                 }
    66.             }
    67.            
    68.             // Kill the closest particle found
    69.             if (closestParticle>-1) {
    70.                 manipulators[i].RemoveParticle (particleSystemId, closestParticle);
    71.                 particles[i].Kill (closestParticle);
    72.             }
    73.         }
    74.     }
    75. }
     
  13. cAyouMontreal

    cAyouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    315
    Hey there !
    Is there any way to run particles with TimeScale set to 0? I've already checked on documentation, on advanced settings, and on the web. Thanks !
     
  14. Ellenack

    Ellenack

    Joined:
    Feb 16, 2014
    Posts:
    41
    Hi ! Just dropping by for a suggestion. When using a mesh emitter, I had a hard time finding out why my particles where emitted from a small area compared to the mesh size in the scene. In the end, the problem was that even if set in world space, you are using the local scale of the object, and not the lossy scale. I think it might be useful to let users decide what they need here. :)
     
  15. neroziros

    neroziros

    Joined:
    Aug 25, 2012
    Posts:
    129
    Hi all, I was wondering if anyone could help me with this odd error.

    For some reason, if I enable-disable an object with a particle playground effect on it, the particle system eventually stops working (Sometimes even after the first enable-disable loop). Here you can see a short video of this error:

    http://screencast-o-matic.com/watch/cojeDefxKS

    PS: Console doesn't display any error message
     
  16. cAyouMontreal

    cAyouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    315
    The only thing I see here that could help is to clear the cache. I'm sure there is a way to call it by script.
     
  17. AlphaNerd_DE

    AlphaNerd_DE

    Joined:
    Jan 2, 2013
    Posts:
    10
    Hey, I bought this asset some time ago and finally had time to try it out.
    I know there is some sort of script support. But is there a way to directly manipulate basic properties like transparency, size, etc. for single particles?
    I know that it's possible to manipulate the position, but what about all that other stuff? The Script Reference couldn't really help me there.
     
  18. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hey!
    Not yet without rewriting a small part of the Playground Manager, there's an option in next version to let particle systems progress individually only affected by their own time scale. Here's what you need to change in PlaygroundC.cs (line 1322):
    Code (CSharp):
    1. /// <summary>
    2.                 /// Updates the global time.
    3.                 /// </summary>
    4.                 public static void SetTime () {
    5.                      
    6.                         // Set time
    7.                         globalTime += (Time.realtimeSinceStartup-lastTimeUpdated)*globalTimescale;
    8.                         // Set delta time
    9.                         globalDeltaTime = globalTime-lastTimeUpdated;
    10.                      
    11.                         // Set interval stamp
    12.                         lastTimeUpdated = globalTime;
    13.                 }
    Very nice suggestion, will be implemented as an option in upcoming version.

    That is odd, could you possibly send the particle system in a UnityPackage to support@polyfied.com so I can have a look at its settings?

    If you're looking to flicker a particle system (enable/disable it rapidly) the most optimal route would be to use the Particle Mask. Here's an example component which you could enable when you want to issue a flicker:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class Flicker : MonoBehaviour {
    6.  
    7.     [Range(.01f, 1f)]
    8.     public float flickerInterval = .1f;
    9.     PlaygroundParticlesC particles;
    10.  
    11.     float _lastUpdate;
    12.  
    13.     void OnEnable ()
    14.     {
    15.         if (particles == null)
    16.             particles = GetComponent<PlaygroundParticlesC>();
    17.  
    18.         particles.particleMask = particles.particleCount;
    19.     }
    20.  
    21.     void OnDisable ()
    22.     {
    23.         particles.applyParticleMask = false;
    24.     }
    25.    
    26.     void Update ()
    27.     {
    28.         if (Time.time >= _lastUpdate + flickerInterval)
    29.         {
    30.             particles.applyParticleMask = !particles.applyParticleMask;
    31.             _lastUpdate = Time.time;
    32.         }
    33.     }
    34. }
    35.  
    Yes you could either use a Manipulator which can change particle properties like position, velocity, color and scale in different manors. If you're looking to do this through script (by singling out specific particles in the array) you can edit that trough the Playground Cache and the particleCache (when it comes to color). The trick is to first set the particle to behave like it was changed by a Manipulator, such as:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class ChangeParticleProperty : MonoBehaviour {
    6.  
    7.     public float size = 1f;
    8.     public Color32 color = Color.red;
    9.  
    10.     PlaygroundParticlesC particles;
    11.     int[] particlesToChange = {0,10,20,30,40,50,60,70,80,90};
    12.  
    13.     void Start ()
    14.     {
    15.         particles = GetComponent<PlaygroundParticlesC>();
    16.     }
    17.  
    18.     void Update ()
    19.     {
    20.         if (particles.IsReady ())
    21.         {
    22.             for (int i = 0; i<particlesToChange.Length; i++)
    23.             {
    24.                 if (particlesToChange[i] > particles.particleCount-1)
    25.                     continue;
    26.  
    27.                 // Set size
    28.                 particles.playgroundCache.changedByPropertySize[particlesToChange[i]] = true;
    29.                 particles.playgroundCache.size[particlesToChange[i]] = size;
    30.  
    31.                 // Set color
    32.                 particles.playgroundCache.changedByPropertyColor[particlesToChange[i]] = true;
    33.                 particles.particleCache[particlesToChange[i]].color = color;
    34.             }
    35.         }
    36.     }
    37. }
    38.  
     
    cAyouMontreal likes this.
  19. AlphaNerd_DE

    AlphaNerd_DE

    Joined:
    Jan 2, 2013
    Posts:
    10
    Ah, okay, I get it. This feels a bit like a workaround, but I can see why this is how it is.
    Instantly made this plugin so much better. Thank you for developing it and for this excellent support.
    10/10 would buy again :)
     
  20. DominikAbe

    DominikAbe

    Joined:
    Mar 20, 2015
    Posts:
    5
    Thank you for the answers! Any timing on this? :) Half a Yera? A year? Less?
     
  21. cAyouMontreal

    cAyouMontreal

    Joined:
    Jun 30, 2011
    Posts:
    315
    Thanks ! I guess this will change it for all my particles I'm using in the game, but that's correct for now.
     
  22. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392
    If my already configured orthographic camera has a FoV of 190, how can I resize the soap machine in a way that looks like like in your default example.

    Thanks
     
  23. AlphaNerd_DE

    AlphaNerd_DE

    Joined:
    Jan 2, 2013
    Posts:
    10
    Okay, I ran into another problem that I haven't encountered with the standard particle system. Do particles actually need longer than 1 frame to redraw? Or in other words, if I manually alter a particles position in Update, can I be sure that they're actually drawn at that position the next time Update runs? Because it really doesn't look like it.
     
  24. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Try setting Particle Settings > Size: 4 - 10, Particle Scale: 10 and Velocity > Constant Force > Velocity Scale: 100. If you need more you can amp the Inspector constraints in Window > Particle Playground > Settings > Editor Limits.

    This is due to multithreading where you can never know when code will execute. It may have executed this, the next or n frames ahead depending on the calculation complexity / processor power. There is an option to sync particles in Advanced > Misc > Sync Particles To Main-Thread, this will set all particle positions in MonoBehaviour's LateUpdate each frame, otherwise particle positioning will happen asynchronously on another thread.

    You may also need to force a particle to update while setting its position by doing this:
    Code (CSharp):
    1. playgroundCache.isCalculatedThisFrame [p] = true;
    this is an optimization which skips setting non-finished calculated particles back into Shuriken and mends visual tearing on heavier particle systems.

    I'll look over this part to make it more streamlined so you could use common functions instead, it would be better if we had ParticlePosition(int, Vector3), ParticleColor(int, Color32) etc. and not have to worry about the internal PP stuff. :)
     
    Last edited: Aug 5, 2015
    hopeful likes this.
  25. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Less! :)
     
  26. AlphaNerd_DE

    AlphaNerd_DE

    Joined:
    Jan 2, 2013
    Posts:
    10
    At first I felt stupid for not concluding myself that this could have to do with multithreading. But sadly, your solution doesn't work.
    I set this at the top of my code (as it doesn't stay ticked in the editor if I don't):
    Code (CSharp):
    1. particles.syncPositionsOnMainThread = true;
    and continue with this further down in my code:
    Code (CSharp):
    1. particles.playgroundCache.isCalculatedThisFrame[i] = true;
    2. particles.playgroundCache.position[i] = offset[i] + transform.position;
    I also tried this with a new project that does nothing else.
    I frequently have to bring my player back to the origin (to avoid floating point issues) and want to take my particles with me.

    This is how it currently looks in an otherwise empty project and huge particles for better visibility:
    Last frame before teleporting back to origin:


    First Frame after Teleporting back:


    Second Frame after teleporting back:



    These should in theory all look the same, but as you can see, the particle system is one frame behind. I checked multiple times that all my code is executed in the right order and I also don't have that problem with the normal shuriken particle system.

    I know that this probably isn't what Particle Playground is normally used for, but it'd still be neat to have a solution for this.
     
  27. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Thanks for thorough description! I'm testing it out with this code which seems to work as expected during frame stepping (setting particleCache position and issuing an update of Shuriken as well):
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class RelocateTest : MonoBehaviour {
    6.  
    7.     public Transform someObj;
    8.     public PlaygroundParticlesC particles;
    9.     System.Random random = new System.Random();
    10.  
    11.     void Start ()
    12.     {
    13.         InvokeRepeating("Relocate", .1f, 1f);
    14.     }
    15.  
    16.     void Relocate ()
    17.     {
    18.         Vector3 offset = PlaygroundParticlesC.RandomVector3(random, new Vector3(-1f, -1f), new Vector3(1f, 1f));
    19.  
    20.         someObj.position += offset;
    21.  
    22.         for (int i = 0; i<particles.particleCount; i++) {
    23.             particles.playgroundCache.position[i] += offset;
    24.             particles.particleCache[i].position = particles.playgroundCache.position[i];
    25.             particles.playgroundCache.isCalculatedThisFrame[i] = true;
    26.         }
    27.  
    28.         particles.UpdateShuriken();
    29.     }
    30. }
    31.  
    If you'd like you could also instead add this (at the time being somewhat experimental) code to PlaygroundParticlesC:
    Code (CSharp):
    1.  
    2.         /// <summary>
    3.         /// Positions the specified particle.
    4.         /// </summary>
    5.         /// <param name="p">Particle index.</param>
    6.         /// <param name="position">Position.</param>
    7.         public void ParticlePosition (int p, Vector3 position) {
    8.             playgroundCache.position[p] = position;
    9.             particleCache[p].position = position;
    10.             playgroundCache.previousParticlePosition[p] = position;
    11.             playgroundCache.isCalculatedThisFrame[p] = true;
    12.         }
    Then simply use yourParticleSystem.ParticlePosition (index, position). The function will end up in the next version.

    The issue that the toggle gets reset sounds like it loads its prefab value, could that be it?

    Edit: Try using particles.UpdateShuriken() after your relocation.
     
    Last edited: Aug 6, 2015
  28. AlphaNerd_DE

    AlphaNerd_DE

    Joined:
    Jan 2, 2013
    Posts:
    10
    Edit: Nevermind all the S*** I wrote, it was wrong.
    I'll come back after more testing.

    Edit 2:
    I don't know what's happening anymore, but the only explanation I have left is, that this isn't real and I'm just dreaming all of this.
    I got it to work in an otherwise empty project, fine. But it doesn't work with the exact same particle system and the exact same script (I literally copied them) in another project. So, I cannot replicate this error in an empty project anymore. And at this point I also doubt that this is all on ParticlePlayground, although I don't experience this with the standard shuriken particle system.

    So I'm just gonna use shuriken until I want to try fixing this error again, but I currently lack the patience (and most importantly, the time).
    And although I'm going back to shuriken, I still think that this is an excellent plugin and anyone who hasn't should go and buy it :)
     
    Last edited: Aug 7, 2015
  29. BortStudios

    BortStudios

    Joined:
    May 1, 2012
    Posts:
    48
    I have a few questions about how collisions work in the particle system.

    I'm using stretched billboards right now for fast bullets. First off, I found that if I start the velocity high, there is some cap to it. Ie it actually gets faster if I take the velocity from 0 to 100, but at 20,000, 50,000, or 100,000, they're all the same. I have to up the velocity scale to get them moving faster. Is this intentional?

    Second of all, when they move too fast and are going to hit something, they do not actually render until impact. I assume that this is because the particles are looking ahead to see if they collide. As a result, they will disappear when they are halfway to the target. Is there any way around this, or a parameter I can change so that they do not detect collisions so far away?

    Thanks
     
  30. SpaceRay

    SpaceRay

    Joined:
    Feb 26, 2014
    Posts:
    455
    Sorry for the maybe basic question, and that maybe I have missed it

    Can Particle Playground emit 3D mesh particles?

    I mean that if I have 3D models (for example small 3D cubes and spheres) I could use them as particles and behave in the same way as the particles, and be able to do the same things

    I mean that all the examples I have seen, seems to be based on 2D particles, or at least this is what I think and of course I may be wrong.

    Thanks for your help and best wishes for the next update that will be waiting to see what it brings
     
  31. ShinKazuo

    ShinKazuo

    Joined:
    Oct 28, 2014
    Posts:
    12
    Hey save, I'm back with another question!

    I instantiate most of the particles through code and almost all of them are the burst type. In the inspector, they all have their "emit" status as false (as well as not having loop).

    Some of them run perfectly when I tell them to emit via code after spawning them, but some of them just refuse to work. If I activate loop, then they start working after a few seconds waiting, usually 2 or 3, which makes it even weirder. This is what I have in code. Can you help me out?

    float angle = transform.eulerAngles.z;
    Vector2 direction = GameManager.Instance.ToVect(angle);
    PlaygroundParticlesC bambooSpread = PlaygroundC.InstantiatePreset("BambooSpread");
    Vector3 bambooSpreadPos = campfireCol.gameObject.transform.position;
    bambooSpreadPos.z = 10f;
    bambooSpread.transform.position = bambooSpreadPos;
    bambooSpread.transform.eulerAngles = new Vector3(0, 0, angle);
    bambooSpread.Emit(true);

    The idea is to create the bamboo spread particles (it starts disabled), I rotate it to the right direction the particles should go, change its position and then activate the emitter.
     
  32. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392
    After working on my PP prototype I decided it was time to migrate the scene to my main project.

    Problem was I wasn't seeing any of my particles and when I clicked on Playground Wizard I was getting this error:
    The particle playground assets couldn't be found in the specified path. please edit the paths to match your current project.

    So I imported PP into the main project and I can access PP full menu and options. Phew.

    But I still can't see the particles at all.

    I did a bit of work on a Playground Manager with a few particles so I'd hate to re-do everything all over.

    Are there any issues exporting a scene with PP and importing back into a different project?


    Thanks again
    German
     
  33. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Haha alright. :) It is interesting though if you'd be able to replicate it, let me know if you do later on!

    I'm not entirely sure if this is connected to the issue of the velocity cap in the settings as you may emit from script, but you can set the max velocity Inspector value cap in Window > Particle Playground > Settings > Editor Limits.

    The collision foreseeing range is unfortunately not something you can tweak yet, but I'm hoping to soon improve collisions further and while I'm at it add more flexible parameters. If you'd like to tweak this yourself you could have a go at it in the PlaygroundParticlesC.Collisions function where this is determined within the Raycast.

    Are there any more collision functionality you would like to see being added?

    No worries, and yes! You can set the Rendering > Render Mode to Mesh. It has the very same render output as Shuriken.

    Hey!
    It sounds like this could be a caching issue where you may call Emit in the middle of when the particle cache is constructed. As this is done asynchronously on another thread you may experience different outcomes. Try to wait for the particle system to become ready before calling Emit(true), it could be done like this:
    Code (CSharp):
    1. IEnumerator Start () {
    2.  
    3.         while (!particles.IsReady())
    4.             yield return null;
    5.  
    6.         particles.Emit (true);
    7.     }
    If this doesn't help we could investigate it further, hit me up at support@polyfied.com with some more details if you'd like!

    Try to put all the particle systems in one or separate prefabs then export that as a UnityPackage and import to your other project. There might be some issue with serialization and dependencies, but it's difficult to say what the exact cause is.
    You can have Particle Playground living anywhere in your project folder, just edit Playground Wizard > Settings > Paths > Playground Path.
    Let me know if it helps!
     
  34. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392
    I chose to add the particle systems and then noticed that the ones imported as package were missing the Source > Transforms > Transform.

    It was so weird.

    Problem 1: The soap texture particle-object-bubble.psd changed from RGBA Compressed DXT4 85.4 KB to RGBA Compressed PVRTC 4 bits 42.8 KB and this change is making the bubble look pixelated.

    UPDATE: This was due to PVRTC compression on iOS. I exported a png and it looks a little better. Kind of a WIP for now

    Problem 2: When I do this:
    Code (CSharp):
    1. particles[i].Emit(true);
    particles kind of burst out at the same time. Is there a way to make them appear one by one instead of all of them at the same time?


    Thanks again!
     
    Last edited: Aug 14, 2015
  35. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    I see! It sounds like you could make use of Source: Script to emit particles when calling Emit(position, velocity, color) instead (or any of the other overloads which suits the scenario best). Then you could use an array of transforms to iterate over them. There's an example script you could start off from called EmitFromTransformsC.cs in the Simple Scripts folder.
     
  36. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392

    Humm... I really like that way particles emit continuously and would rather use an overload that allows continuous emission.

    The problem is when I turn on any particle system
    Code (CSharp):
    1. particles[i].Emit(true);
    I get the 20 or so particles (on particle count) spawned at the same time, instead of they way it does it normally, which is again a continuous Lifetime Sorting of type scrambled linear.

    See screenshot

    Thanks
     

    Attached Files:

  37. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    That is unfortunately a shortcoming of how particle time is set which will queue up emissions up till the entire loop has passed the simulation time. Let me see if I can do something about that in the upcoming version, till then the only correct behavior would be to call each emission through script. Here's an example of what you could do with an array of particle systems which is behaving in a similar fashion to a linear lifetime emission routine (and uses your entire particle system setup except the birth position is set to its own transform):

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class ArrayEmitFullCycle : MonoBehaviour {
    6.  
    7.     public EmitWrapper[] particleSystems;
    8.     void Start ()
    9.     {
    10.         // Setup emission routine for all particle systems
    11.         for (int i = 0; i<particleSystems.Length; i++)
    12.             particleSystems[i].Setup();
    13.     }
    14.  
    15.     void Update ()
    16.     {
    17.         // Iterate over particle systems emission routine
    18.         for (int i = 0; i<particleSystems.Length; i++)
    19.             particleSystems[i].EmissionUpdate();
    20.     }
    21. }
    22.  
    23. [System.Serializable]
    24. public class EmitWrapper {
    25.     public PlaygroundParticlesC particles;
    26.     public bool emit = true;
    27.     private float _lastEmission = 0;
    28.     private float _emissionDelta;
    29.  
    30.     public void Setup ()
    31.     {
    32.         particles.source = SOURCEC.Script;
    33.  
    34.         // Emit with delta depending on particle count and maximum lifetime
    35.         _emissionDelta = particles.lifetime / (particles.particleCount*1f);
    36.     }
    37.  
    38.     public void EmissionUpdate ()
    39.     {
    40.         if (emit && Time.time >= _lastEmission+_emissionDelta)
    41.         {
    42.             particles.Emit (particles.particleSystemTransform.position, RandomVector3(particles.initialLocalVelocityMin, particles.initialLocalVelocityMax));
    43.             _lastEmission = Time.time;
    44.         }
    45.     }
    46.  
    47.     Vector3 RandomVector3 (Vector3 min, Vector3 max)
    48.     {
    49.         return new Vector3 (
    50.             Random.Range(min.x, max.x),
    51.             Random.Range(min.y, max.y),
    52.             Random.Range(min.z, max.z)
    53.         );
    54.     }
    55. }
    When you want to pause/continue emission on one particle system you could toggle particleSystems[index].emit and no excessive particles will be emitted on continuation. Hope it helps!
     
  38. Exbleative

    Exbleative

    Joined:
    Jan 26, 2014
    Posts:
    216
    Hi, loving Particle Playground, thanks! However have run into a problem. Somehow I have two Playground Managers in a scene, and if I click one of them, the hierarchy 'goes grey' and I can't click anything inside it. I get two errors:

    NullReferenceException: Object reference not set to an instance of an object
    PlaygroundHierarchyIcon.DrawHierarchyIcon (Int32 instanceID, Rect instanceRect) (at Assets/Particle Playground/Scripts/Editor/PlaygroundInspectorC.cs:998)
    UnityEditor.SceneHierarchyWindow.OnGUIAssetCallback (Int32 instanceID, Rect rect) (at C:/buildslave/unity/build/Editor/Mono/SceneHierarchyWindow.cs:246)
    UnityEditor.TreeView.OnGUI (Rect rect, Int32 keyboardControlID) (at C:/buildslave/unity/build/Editor/Mono/GUI/TreeView/TreeView.cs:430)
    UnityEditor.SceneHierarchyWindow.DoTreeView (Single searchPathHeight) (at C:/buildslave/unity/build/Editor/Mono/SceneHierarchyWindow.cs:347)
    UnityEditor.SceneHierarchyWindow.OnGUI () (at C:/buildslave/unity/build/Editor/Mono/SceneHierarchyWindow.cs:195)
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)

    NullReferenceException: Object reference not set to an instance of an object
    PlaygroundInspectorC.RenderPlaygroundSettings () (at Assets/Particle Playground/Scripts/Editor/PlaygroundInspectorC.cs:275)
    PlaygroundInspectorC.OnInspectorGUI () (at Assets/Particle Playground/Scripts/Editor/PlaygroundInspectorC.cs:97)
    UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean forceDirty, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect, Boolean eyeDropperDirty) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1150)
    UnityEditor.DockArea:OnGUI()

    I need to shutdown Unity and restart to fix it.

    One of the managers is turned off, the other is on. If I delete the one that is on, and then go to select the off one, same problem happens as usual. So I don't know how to delete them, if it is a problem of having two in the scene at once?

    Please let me know, thanks!
    Regards,
    Jay
     
  39. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    Hi,
    Sorry if this has been answered but I could not find it.
    Is there a way to set the system to a specific point in the simulation? I need to bake the systems down into a sprite sheet for LODs.

    Hopeing for something like this:
    float ratio = (float)currentFrame / (float)(frames-1);
    float time=ratio;
    time *= ((target as ParticleSystem).duration + 0.5f);
    (target as ParticleSystem).Simulate (time);

    Thanks!
     
  40. Situacao

    Situacao

    Joined:
    Dec 4, 2013
    Posts:
    21
    Hey save,

    I'm thinking about buying Particle Playground and I'd like to ask you if PP has any support for lit particle effects, as in particle that emit light by themselves?

    Thanks in advance!
     
  41. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    433
    Hi, I'm trying to make a hand-shaped, just like the Playground Burning Robot example, but it's hard to adjust particle size. I want fingers particles smaller than others. Is there any way to approach that? Can particle mask do this? Thanks.
     

    Attached Files:

  42. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi Jay, sorry about the late reply. I've sent you an email which hopefully should clear things up, otherwise let me know and we'll investigate further. For reference:

    Hi,
    You could use a small hack created for these type of situations, even with a fancy Inspector. :)
    Code (CSharp):
    1. Synced Simulate will let you time-step a Particle Playground system in predetermined intervals. This is a rough workaround and will alter the global time of Particle Playground within the scene due to access level of members which otherwise are controlled internally within a Playground system.
    2.  
    3. Find the package here: http://polyfied.com/development/unity/playground/Playground_SyncedSimulate.unitypackage
    4.  
    5.  
    6. /////////////////////////////////////////////////////////////////////////////////////////////////
    7. // Playground Synced Simulate/SyncedSimulate.cs
    8. /////////////////////////////////////////////////////////////////////////////////////////////////
    9.  
    10. using UnityEngine;
    11. using System.Collections;
    12. using ParticlePlayground;
    13.  
    14. /// <summary>
    15. /// Synced Simulate is a rough hack to make a Particle Playground system be able to step forward in time intervals. It uses PlaygroundC.globalTime to reconfigure the current time, so it will affect other particle systems in your scene.
    16. /// </summary>
    17. [ExecuteInEditMode()]
    18. public class SyncedSimulate : MonoBehaviour
    19. {
    20.     public bool pauseOnStart = false;            // Should the simulation be paused in the beginning?
    21.     public bool pauseOnSimulation = false;        // Should the simulation pause upon calling Simulate()?
    22.     public float stepTime = 1f;                    // The time to step forward each Simulate() call
    23.     public int stepResolution = 100;            // The resolution to calculate forces, the more the heavier on CPU
    24.     PlaygroundParticlesC _particles;            // Cached particle system reference
    25.  
    26.     void OnEnable ()
    27.     {
    28.         _particles = GetComponent<PlaygroundParticlesC>();
    29.         _particles.applyDeltaOnRebirth = true;
    30.  
    31.         if (pauseOnStart)
    32.             _particles.particleTimescale = 0;
    33.     }
    34.  
    35.     /// <summary>
    36.     /// Simulate on main-thread to the specified time. Resolution determines how exact the final result should be in terms of forces.
    37.     /// </summary>
    38.     /// <param name="time">Time of simulation.</param>
    39.     /// <param name="resolution">The amount of calculated steps.</param>
    40.     public void Simulate (float time, int resolution)
    41.     {
    42.         _particles.particleTimescale = 1f;
    43.  
    44.         if (resolution < 1)
    45.             resolution = 1;
    46.  
    47.         float currentTime = PlaygroundC.globalTime;
    48.  
    49.         for (int i = 0; i<resolution; i++)
    50.         {
    51.             PlaygroundC.globalTime = currentTime+(time*((i*1f)/(resolution*1f)));
    52.             PlaygroundParticlesC.ThreadedCalculations(_particles);
    53.         }
    54.  
    55.         if (pauseOnSimulation)
    56.             _particles.particleTimescale = 0;
    57.     }
    58. }
    59.  
    60.  
    61. /////////////////////////////////////////////////////////////////////////////////////////////////
    62. // Playground Synced Simulate/Editor/SyncedSimulateInspector.cs
    63. /////////////////////////////////////////////////////////////////////////////////////////////////
    64.  
    65. using UnityEngine;
    66. using UnityEditor;
    67. using System.Collections;
    68.  
    69. /// <summary>
    70. /// This is the inspector of SyncedSimulate.cs, make sure this is in a folder called 'Editor'.
    71. /// </summary>
    72. [CustomEditor(typeof(SyncedSimulate))]
    73. class SyncedSimulateInspector : Editor
    74. {
    75.     SyncedSimulate _sSimulate;
    76.  
    77.     public void OnEnable ()
    78.     {
    79.         _sSimulate = (SyncedSimulate)target;
    80.     }
    81.  
    82.     public override void OnInspectorGUI ()
    83.     {
    84.         _sSimulate.pauseOnStart = EditorGUILayout.Toggle ("Pause On Start", _sSimulate.pauseOnStart);
    85.         _sSimulate.pauseOnSimulation = EditorGUILayout.Toggle ("Pause On Simulation", _sSimulate.pauseOnSimulation);
    86.         _sSimulate.stepTime = EditorGUILayout.FloatField("Step Time", _sSimulate.stepTime);
    87.         _sSimulate.stepResolution = EditorGUILayout.IntField("Step Resolution", _sSimulate.stepResolution);
    88.         if (GUILayout.Button ("Step"))
    89.             _sSimulate.Simulate(_sSimulate.stepTime, _sSimulate.stepResolution);
    90.     }
    91. }
    Hey,
    There's support for having any type of followers (through a script extension found in the package), so for example having GameObjects with a light component following your particles is supported.

    Hi,
    You could try setting the Particle Settings > Size > Array Size Animation Curve to match the vertex order. Otherwise you may need to use a Manipulator (Size Property).
    In cases like this, a source setting for more custom editing would have been nice, let me see what can be done in future versions. :)
     
    overthere and zhuchun like this.
  43. QFGlenn

    QFGlenn

    Joined:
    Feb 21, 2013
    Posts:
    39
    What's the status of the Playmaker actions addon? Curiously awaiting the arrival :)
     
    RecursiveRuby likes this.
  44. tobln

    tobln

    Joined:
    Jul 5, 2013
    Posts:
    5
    Hey, whats the best practice to in PPG to archive something like the Burst Sequences in the Unity Particle System?
     

    Attached Files:

  45. RecursiveRuby

    RecursiveRuby

    Joined:
    Jun 5, 2013
    Posts:
    163
    Hey I'm having an issue which I think relates to saving particle playground components in prefabs I'm not too sure. Basically I create a new particle system and drag it onto a gameobject which I then save as a prefab. This object is like a spell so multiple can be cast at a time. It works fine when one is cast and finishes it's effect and then another but if two prefabs are active with the particle playground system at any one time it gives me an error and any subsequent systems won't work. I'm sorry if it sounds confusing. This is the error if you are interested. Any ideas?

     
  46. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    Hi,
    Thanks so much for the hack to jump to specific points of the simulation. Going to try it this week.
     
  47. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    I had purchased Particle Playground a little while ago and am just now starting to get into it - what an awesome addon!!! I have one question, though: Is there a way to make particles move along a spline? I've found a way to create particles along a spline, which is already quite helpful - but I also need to be able to move the particles along predefined paths ... so ... is that even possible?
     
  48. RecursiveRuby

    RecursiveRuby

    Joined:
    Jun 5, 2013
    Posts:
    163
    I'm not sure if they can actually move or not along a path but have you tried setting your lifetime sorting to Linear. This means they will emit in sequence rather than appearing randomly. As long as you have a high enough particle count and the size of each particle is large enough to meet it's neighbour it will give the illusion of something in motion. I've used this in my game. I imagine it'd be what you are looking for.
     
    jashan likes this.
  49. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Currently there's focus on rolling out the next big update, still a shortage on Playmaker actions, sorry! You can still use Playmaker with Playground though, by dragging a particle system component from Inspector into the FSM. All members will be exposed so it could require some jumps into the script reference.

    In Playground this part becomes a bit less intuitive unfortunately due to the current particle pool structure. What you can do is setup a custom Lifetime Sorting. From the manual:
    There's an example of such preset here which has irregular emission throughout a lifetime cycle. But you can't control exact bursts unless going into Source: Script mode.

    Hey! That's not good (and a first), could you possibly send the prefab in a UnityPackage to support@polyfied.com? It would help trying to figure out why the system becomes null at the random rotation function.

    Happy you like it! There are a two general ways to make particles travel along a spline, depending on which type of outcome you'd like.

    Using a method in Forces > Force Annihilation together with either the particle system's Source > Time Offset (PlaygroundParticlesC.splineTimeOffset) or the individual Playground Spline's Time Offset (PlaygroundSpline.timeOffset, for offsetting each spline differently) you'll see a confined result like this:


    For more natural flows you can use a Spline Target Manipulator, which will require some fine-tuning to act the way you want. Could look something like this:


    You can also use Target Method: Particle Time and Transition: None to make the particles move automatically along the spline target (similar to first example), but you will then have an overhead of particles being containment checked from the Manipulator. This will be required if you only want some particles moving along the spline within a certain space.

    You can find two example scenes using these methods in Examples/Example Scenes/Splines/ (02 & Spline Targets)
     
    Last edited: Sep 15, 2015
    jashan and overthere like this.
  50. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Cool, thanks! I appreciate the quick and extensive reply!

    I'll try it with the Spline Target Manipulator which I believe should give me the desired results.

    Thanks also @Barabicus - I had considered using the approach from Playground Spline Example 01 and would fall back to that if I can't get what I want with Spline Target Manipulator. But the actual movement of the individual particles is pretty important to me (I'll even have particles moving in both directions of the spline simultaneously, probably be creating two systems). They should primarily be moving along the spine but also with a little bit of "noise", in other words some randomness that takes them away from the exact position of the spline (which at first looks like it may be hard with the first solution that Lars-Erik suggested).