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. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    - I'm not sure what I did, but I seemed to fix the hierarchy exploding with objects, I must have done something wrong but it's not happening anymore.. :)

    - It doesn't seem to happen in Play mode, which is the most important thing I suppose. It seems to be happening the most when I change the selection of the hierarchy in edit mode. E.g. I have two particle systems with trails. System A is selected to so it autoplays in the editor. I select System B and things go stringy like in the image. Not a huge problem upon inspecting it further though, because it doesn't seem to happen in play mode.

    One more question; Any way to disable trails casting shadows?
     
  2. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    If it comes back let me know! It should be a fairly simple fix as well. :)
    Will have a closer look into the Editor throwing end-points to start location, it's great if we can keep it somewhat true to runtime when editing.

    Shadow settings etc. is coming up very soon, right now that part needs to be handled in the shader for the material you're using. Hang in there!
     
    DMeville likes this.
  3. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    Cool cool. I didn't think it's shader related, using a custom shader on my trails anyways.
    Maybe let us assign a mesh renderer to the trail component, and copy the values from that per trail?

    Adding this in PlaygroundTrails.cs - line 470 is a quick fix.
    Code (CSharp):
    1. newTrail.trailRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
    2.  
     
  4. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    And of course you could hack the code for an even quicker fix. :) Will give you proper Inspector values soon though!
     
    hopeful and DMeville like this.
  5. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    42
    The problem with this:
     

    Attached Files:

  6. Simie

    Simie

    Joined:
    Oct 26, 2012
    Posts:
    456
    Hey @save, I'm considering using Particle Playground for my project (I already bought it back when v2 was released because of your excellent demo videos!).

    In my game I have particles that are affected by the air-velocity of the tile they occur on (example video: link). Is it possible in PP to have a custom affector that can lookup this velocity data based on the particle position?
     
  7. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hey Georgy, I sent you an email with the solution. The problem is that you're using a Playground Spline as a Source and not a Manipulator to move the particles. There are two general ways of moving particle like this, one is through a Manipulator using the Particle Time as Target Method and one is using it as a Source without a Manipulator and offsetting the Spline Time.

    Hey, happy to hear that!
    Indeed there is, you could try use Manipulators with shape as a box in case there isn't crazy many different in the grid. If there is I would suggest the alternative of using a lookup table of rects and access the particles cached array to insert your velocity through script. It should be fairly quick to implement. What you then would be using is the PlaygroundCache to edit the particle data.

    I will have better suggestions later down the road when implementing vector fields though. :)
     
  8. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
  9. BabyDinoHerd

    BabyDinoHerd

    Joined:
    Mar 27, 2014
    Posts:
    21
    Hi,

    I'm mostly enjoying my time with PP so far, but I have a seemingly simple thing I want to do and I can't figure out how to do it.

    I would like a fractional, evenly-spaced emission rate. The "emission rate" seems to just emit for the first fraction, then nothing for the rest of the loop, no matter what the lifetime sorting is. I am not sure what "lifetime emission" does, but it's not what I want it to do.

    Any thoughts?

    The goal is to have a mesh-based state with, say 1024 particles, lifetime 1, but emit one particle only once every 0.1s, for instance.
     
  10. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    I have a feature request, that may or may not be outside the scope of the project.. :)

    I see that you have a SplineMesh component, that renders a quad strip along the spline, what about something similar, but instead renders a tube around the spline.

    I made something similar, although sloppy, that makes a tube and follows along when the spline is deformed - although it's not super performant it adds some cool looks to some effects!
     
  11. DangerFro

    DangerFro

    Joined:
    Oct 18, 2012
    Posts:
    2
    Hello!

    I've been exploring different fx packages for Unity since Shuriken doesn't have the functionality that the company I work for is looking for. For the most part we've been making use of popcornfx most recently, but we're interested in the possibilities that particle playground presents.

    My main curiosity at this time is if particle playground has a functionality similar to what popcornfx presents here:

    http://wiki.popcornfx.com/index.php/CParticleEvolver_Projection

    In short it allows a particle system to move across the surface of a mesh regardless of UV's or normal direction, with eventual hopes of developing it to apply to skinned meshes as well. The closest function that generates similar results that I've been able to find within PP is the Source Scatter coupled with Lifetime Sorting.

    Even if this isn't currently possible to replicate, I'm sure it'd make for an excellent feature in the future.
     
  12. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    It came back. Every time I hit play a new trail object is created, and on cancel it's not destroyed. :(
     
  13. ian_facepunch

    ian_facepunch

    Joined:
    Mar 16, 2015
    Posts:
    22
    I've got the same issue with the trails. I've had a quick look at the code and it seems that they get destroyed when the application calls OnDestroy from play mode but then created again in OnEnable inside the editor. This new object doesn't get removed when switching back again from the editor to play mode.

    Any way to get a quick fix for this?
     
    DMeville likes this.
  14. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi,
    Currently that is unfortunately not possible due to the lifetime sorting and particle time structure. It is something I really want to address but will take time as there's so many nested features depending on this structure.
    There is a more advanced scripted emission coming soon which enables iteration over another Source, which I believe would be a perfect approach in your type of scenario. This means you will be able to call emission on a specific source point created by a State for example with a custom lifetime setting on your particles.

    Sounds like a fun side project, if I make one I'll make sure to post it. :) Otherwise feel free to dissect and improve PlaygroundSplineMesh.cs!

    Hi! You can for example use the Source: Projection, but that requires colliders which raycasts from a texture can bounce on. Otherwise masking for meshes and skinned meshes is on the roadmap, which would potentially produce something very similar, but it would require to still birth at vertices (or scattered positions from them). Indeed a good feature for the future!

    Quick fix is coming up very soon, hopefully tonight together with a fix for an issue found with creating Snapshots.
     
  15. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Quick fixes are up!

    Let me know how it works. The Playground Trails issue I was never able to reproduce, however the alternative approach should work better as it has a verification on its necessity to exist.
     
  16. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    I got a question recently how to play audio on particle collisions. This is something I haven't addressed yet with the example scenes or the script library but is something you many times want to do. One really easy way of approaching this is by adding or modifying this script: :)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class PlayAudioOnParticleCollision : MonoBehaviour {
    6.  
    7.     public PlaygroundParticlesC particles;
    8.     public GameObject audioSourceReference;
    9.     public int audioSourcePoolCount = 10;
    10.     public float randomPitch = .1f;
    11.  
    12.     private AudioSource[] _audioSourcePool;
    13.     private int _audioSourceIndex = 0;
    14.     private PlaygroundEventC _collisionEvent;
    15.  
    16.     void OnEnable ()
    17.     {
    18.         // Create the audio pool based on the audio source reference
    19.         AudioSource sourceRef = audioSourceReference.GetComponent<AudioSource>();
    20.         sourceRef.playOnAwake = false;
    21.         _audioSourcePool = new AudioSource[audioSourcePoolCount];
    22.         for (int i = 0; i<_audioSourcePool.Length; i++)
    23.         {
    24.             GameObject go = (GameObject)Instantiate (audioSourceReference);
    25.             go.transform.parent = transform;
    26.             _audioSourcePool[i] = go.GetComponent<AudioSource>();
    27.         }
    28.  
    29.         // Try to get the particle system on the GameObject this script is attached to
    30.         if (particles == null)
    31.             particles = GetComponent<PlaygroundParticlesC>();
    32.  
    33.         // Set event reference if collision event already exists
    34.         foreach (PlaygroundEventC e in particles.events)
    35.         {
    36.             if (e.eventType == EVENTTYPEC.Collision && (e.broadcastType == EVENTBROADCASTC.EventListeners || e.broadcastType == EVENTBROADCASTC.Both))
    37.             {
    38.                 _collisionEvent = e;
    39.                 break;
    40.             }
    41.         }
    42.  
    43.         // Otherwise create the event
    44.         if (_collisionEvent == null)
    45.         {
    46.             _collisionEvent = PlaygroundC.CreateEvent(particles);
    47.             _collisionEvent.eventType = EVENTTYPEC.Collision;
    48.             _collisionEvent.broadcastType = EVENTBROADCASTC.EventListeners;
    49.         }
    50.  
    51.         // Start listening to the event
    52.         _collisionEvent.particleEvent += OnParticleCollisionEvent;
    53.     }
    54.  
    55.     void OnDisable ()
    56.     {
    57.         // Remove the event whenever disabling this component
    58.         if (_collisionEvent != null)
    59.             _collisionEvent.particleEvent -= OnParticleCollisionEvent;
    60.     }
    61.    
    62.     void OnParticleCollisionEvent (PlaygroundEventParticle eventParticle)
    63.     {
    64.         // Position the audio source
    65.         _audioSourcePool[_audioSourceIndex].transform.position = eventParticle.collisionParticlePosition;
    66.  
    67.         // Randomize the pitch
    68.         _audioSourcePool[_audioSourceIndex].pitch = Random.Range (1f-randomPitch, 1f+randomPitch);
    69.  
    70.         // Play the audio
    71.         _audioSourcePool[_audioSourceIndex].Play();
    72.  
    73.         // Increment index
    74.         _audioSourceIndex = (_audioSourceIndex + 1) % _audioSourcePool.Length;
    75.  
    76.         // Remember that the eventParticle has more info about the particle, for example:
    77.         //
    78.         // eventParticle.size
    79.         // eventParticle.position
    80.         // eventParticle.velocity
    81.         // eventParticle.collisionCollider
    82.         //
    83.         // and so on!
    84.     }
    85. }
    86.  
     
    hopeful likes this.
  17. Image3d

    Image3d

    Joined:
    Jun 20, 2008
    Posts:
    155
    Hi,

    How do I start the play of a recorded particle at Runtime ?
     
  18. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi,
    In short you could use recorder.Play(). To give some better understanding of how it works;
    The Playground Recorder Data object (a Scriptable Object) store information about the particles in a per-recorded-frame structure whenever assigned and recording. It is not necessary to assign one if both recording and playback happens during runtime in the same session (for example instant replay).
    To replay between sessions you must have assigned a Playground Recorder Data object to the Playground Recorder. Any Particle Playground system will be able to replay a recording, even if the recording didn't originate from it.
    Loading of the data happens during OnEnable of the Playground Recorder and is an asynchronous procedure if you have enabled Playground Recorder > Advanced > Multithreading.

    There's quite some things supported in the recorder, here's a cheat sheet for the most common operations:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class RecorderExamples : MonoBehaviour {
    6.  
    7.     /// <summary>
    8.     /// The reference to the Playground Recorder.
    9.     /// </summary>
    10.     public PlaygroundRecorder recorder;
    11.  
    12.  
    13.     /***********************************************************************************
    14.         Playback control
    15.     ***********************************************************************************/
    16.  
    17.     /// <summary>
    18.     /// Starts the playback of this Playground Recorder.
    19.     /// </summary>
    20.     public void Play ()
    21.     {
    22.         recorder.Play ();
    23.     }
    24.  
    25.     /// <summary>
    26.     /// Starts the playback of this Playground Recorder with specified playback speed.
    27.     /// </summary>
    28.     /// <param name="speed">The speed of the playback.</param>
    29.     public void Play (float speed)
    30.     {
    31.         recorder.Play (speed);
    32.     }
    33.  
    34.     /// <summary>
    35.     /// Starts the playback of this Playground Recorder with specified starting point, playback speed and if looping should occur.
    36.     /// </summary>
    37.     /// <param name="fromNormalizedTime">From normalized time in recording.</param>
    38.     /// <param name="speed">The speed of the playback.</param>
    39.     /// <param name="repeat">If set to <c>true</c> then enable looping.</param>
    40.     public void Play (float fromNormalizedTime, float speed, bool repeat)
    41.     {
    42.         recorder.Play (fromNormalizedTime, speed, repeat);
    43.     }
    44.  
    45.     /// <summary>
    46.     /// Pauses the playback of this Playground Recorder.
    47.     /// </summary>
    48.     public void Pause ()
    49.     {
    50.         recorder.Pause ();
    51.     }
    52.  
    53.     /// <summary>
    54.     /// Stops the playback and recording of this Playground Recorder.
    55.     /// </summary>
    56.     public void Stop ()
    57.     {
    58.         recorder.Stop ();
    59.     }
    60.  
    61.     /// <summary>
    62.     /// Scrub to specified time in particle recording. This will linearly interpolate between the closest recorded frames of the passed in time (normalized between 0f - 1f).
    63.     /// </summary>
    64.     /// <param name="normalizedTime">The normalized time (0f to 1f).</param>
    65.     public void Scrub (float normalizedTime)
    66.     {
    67.         recorder.Scrub (normalizedTime);
    68.     }
    69.  
    70.     /// <summary>
    71.     /// Sets the speed of the playback. Set this to a negative value to make the playback go backwards.
    72.     /// </summary>
    73.     public void SetPlaybackSpeed (float speed)
    74.     {
    75.         recorder.playbackSpeed = speed;
    76.     }
    77.  
    78.     /// <summary>
    79.     /// Determines if the playback should loop when reaching the end of the recording.
    80.     /// </summary>
    81.     public void SetPlaybackLoop (bool loop)
    82.     {
    83.         recorder.loopPlayback = loop;
    84.     }
    85.  
    86.  
    87.     /***********************************************************************************
    88.         Record control
    89.     ***********************************************************************************/
    90.  
    91.     /// <summary>
    92.     /// Starts a recording until StopRecording() is called. This overload will by default use the previously set keyframe interval during recording.
    93.     /// </summary>
    94.     public void StartRecording ()
    95.     {
    96.         recorder.StartRecording ();
    97.     }
    98.  
    99.     /// <summary>
    100.     /// Starts a recording until StopRecording() is called. This overload takes a keyframe interval as parameter.
    101.     /// </summary>
    102.     /// <param name="keyframeInterval">The Keyframe Interval determines the rate of created keyframes (measured in seconds where 1f is 1 second).</param>
    103.     public void StartRecording (float keyframeInterval)
    104.     {
    105.         recorder.StartRecording (keyframeInterval);
    106.     }
    107.  
    108.     /// <summary>
    109.     /// Starts a recording with specified length or until StopRecording() is called. This overload takes a recording length and keyframe interval as parameter.
    110.     /// </summary>
    111.     /// <param name="recordingLength">The amount of seconds the recording should be.</param>
    112.     /// <param name="keyframeInterval">The Keyframe Interval determines the rate of created keyframes (measured in seconds where 1f is 1 second).</param>
    113.     public void StartRecording (float recordingLength, float keyframeInterval)
    114.     {
    115.         recorder.StartRecording (recordingLength, keyframeInterval);
    116.     }
    117.  
    118.     /// <summary>
    119.     /// Records one frame. This can be useful if you want exact control of when keyframes should be created.
    120.     /// </summary>
    121.     public void RecordOneFrame ()
    122.     {
    123.         recorder.RecordOneFrame ();
    124.     }
    125.  
    126.     /// <summary>
    127.     /// Inserts a recorded frame into the specified frame index. This can be useful if you want to add frames into the recording that shouldn't be placed last. Use FrameCount() to determine how many frames you currently have.
    128.     /// </summary>
    129.     /// <param name="frame">The index of where the frame should be inserted.</param>
    130.     /// <param name="frameType">The type of the inserted frame (by default FrameType.Middle).</param>
    131.     public void InsertOneFrame (int frame, FrameType frameType = FrameType.Middle)
    132.     {
    133.         recorder.InsertOneFrame (frame, frameType);
    134.     }
    135.  
    136.     /// <summary>
    137.     /// Stops the ongoing recording.
    138.     /// </summary>
    139.     public void StopRecording ()
    140.     {
    141.         recorder.StopRecording ();
    142.     }
    143.  
    144.     /// <summary>
    145.     /// Clears out the current recorded frames.
    146.     /// </summary>
    147.     public void ClearRecording ()
    148.     {
    149.         recorder.ClearRecording ();
    150.     }
    151.  
    152.  
    153.     /***********************************************************************************
    154.         Set live particle system as playback
    155.     ***********************************************************************************/
    156.  
    157.     /// <summary>
    158.     /// Sets the particle system's live particles at the current position in playback (using the playhead) of this Playground Recorder. If multithreading is enabled this operation will run asynchronously.
    159.     /// </summary>
    160.     public void SetParticleSystemAsCurrentPlayback ()
    161.     {
    162.         recorder.SetParticleSystemAsCurrentPlayback ();
    163.     }
    164.  
    165.     /// <summary>
    166.     /// Sets the particle system's live particles at normalized time of the recorded frames. If multithreading is enabled this operation will run asynchronously.
    167.     /// </summary>
    168.     public void SetParticleSystemAsRecording (float normalizedTime)
    169.     {
    170.         recorder.SetParticleSystemAsRecording (normalizedTime);
    171.     }
    172.  
    173.  
    174.     /***********************************************************************************
    175.         Saving/Loading
    176.     ***********************************************************************************/
    177.  
    178.     /// <summary>
    179.     /// Stops the playback and recording of this Playground Recorder and serializes data into Recorder Data. If multithreading is enabled then the serialization will be asynchronous.
    180.     /// </summary>
    181.     public void StopAndSerialize ()
    182.     {
    183.         recorder.StopAndSerialize ();
    184.     }
    185.  
    186.     /// <summary>
    187.     /// Serializes the current recorded frames into the Recorder Data. If multithreading is enabled then the serialization will be asynchronous.
    188.     /// </summary>
    189.     public void Serialize ()
    190.     {
    191.         recorder.Serialize ();
    192.     }
    193.  
    194.     /// <summary>
    195.     /// Loads frames from the Recorder Data. This or LoadAsync happens automatically if recorderData is assigned.
    196.     /// </summary>
    197.     public void Load ()
    198.     {
    199.         recorder.Load ();
    200.     }
    201.  
    202.     /// <summary>
    203.     /// Loads frames from the Recorder Data asynchronously. This or Load happens automatically if recorderData is assigned.
    204.     /// </summary>
    205.     public void LoadAsync ()
    206.     {
    207.         recorder.LoadAsync ();
    208.     }
    209.  
    210.  
    211.     /***********************************************************************************
    212.         Frame trimming
    213.     ***********************************************************************************/
    214.  
    215.     /// <summary>
    216.     /// Trims (remove) the specified frames outside of normalized leftTime to rightTime. Returns true if trimming occurred.
    217.     /// </summary>
    218.     /// <param name="leftTime">The normalized left time (0 - 1).</param>
    219.     /// <param name="rightTime">The normalized right time (0 - 1).</param>
    220.     public bool Trim (float leftTime, float rightTime)
    221.     {
    222.         return recorder.Trim (leftTime, rightTime);
    223.     }
    224.  
    225.     /// <summary>
    226.     /// Trims (removes) the specified frames inside of normalized leftTime to rightTime.
    227.     /// </summary>
    228.     /// <param name="leftTime">The normalized left time (0 - 1).</param>
    229.     /// <param name="rightTime">The normalized right time (0 - 1).</param>
    230.     public void TrimInner (float leftTime, float rightTime)
    231.     {
    232.         recorder.TrimInner (leftTime, rightTime);
    233.     }
    234. }
    235.  
    More members can be found in the script reference.

    You can also have a look in the example scenes Recording One System and Recording Multiple Systems. The latter using the Playground Multi Recorder component which basically is a list of recorders controlled from single function calls.
     
    Last edited: Dec 25, 2015
  19. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    I believe I've just found a really nasty issue in Particle Playground (current version from the Asset Store, 3.02):

    For several weeks, I had sporadic hiccups in Unity when entering Play mode and also after compilation completed. What happened was that Unity simply stopped doing anything for about 100 seconds very much looking as if Unity crashed while it actually didn't crash. With some patience (waiting about 100 seconds), Unity would continue going into Play mode or return from the compilation hiccup.

    Joachim Ante from UT said the issue probably had to do Unity waiting for some Threads that domain reload has to wait for. So I tried figuring it out with the Visual Studio debugger (after going down a few long roads that didn't lead anywhere) ... and that finally revealed the (almost certain) cause of this issue:

    Code (csharp):
    1. stream = client.OpenRead(playgroundSettings.versionUrl);
    in PlaygroundParticleWindowC.CheckForInternetConnection().

    After replacing that method with return false; the issue did not occur for a few hours of developing / testing. After restoring the original implementation, it just took a few attempts to run into it again, and once again, the debugger showed one Thread getting stuck on that line, so I'm fairly certain that this is what's causing the issue.

    You might want to replace OpenRead with OpenReadAsync to prevent this from happening.
     
  20. manny003

    manny003

    Joined:
    Mar 18, 2014
    Posts:
    69
    I'm in somewhat of a pickle here. I just installed PP3 for the first time with the intention of using it in a project that's nearly complete -- and was written in Javascript (UnityScript).

    I'm having trouble getting references to PP3 objects at run time to perform simple things like enable/disable emitters, manipulators, change colors, etc. Nothing I've tried work.

    I've looked at Unity's guide for script compilation order at http://docs.unity3d.com/Manual/ScriptCompileOrderFolders.html and even moved the entire ParticlePlayground folder into "Plugins".

    Nothing has worked.

    I cannot find any Simple Script Javascript starter as eluded in Version History. Nor does the Playground Wizard has any option to select coding language as mentioned in the Version History document for version 1.18.

    Can someone please provide step-by step instructions, examples, tutorials on how to leverage PP3 in a Javascript dominated project?

    Thanks,
    Manny
     
  21. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Thank you that helps immensely! This will be fixed in the next update.
     
    jashan and hopeful like this.
  22. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    To make Particle Playground work with UnityScript:

    1) Create a folder called Plugins in the Project View then drag and drop Particle Playground into the Plugins folder using the Project View.

    2) Open the Playground Wizard (Window > Particle Playground) and press Find Playground Settings and the very top. This is needed in order for you to store your settings. The location is then stored in a file found in YourProject/PlaygroundCache/PlaygroundSettingsLocation so Playground won't have to search for its settings file again.

    3)
    In the Playground Wizard go to Settings > Paths and set the Playground Path to the Plugins folder. For example: Plugins/Particle Playground/. This is needed in order to load all Presets and other assets connected to Particle Playground.

    4) When referencing any Particle Playground components you will need to import ParticlePlayground into your UnityScript. For example:
    Code (JavaScript):
    1. #pragma strict
    2. import ParticlePlayground;
    3.  
    4. var particles : PlaygroundParticlesC;
     
  23. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    You're welcome! Great to hear it will be fixed in the next update - so I can update / overwrite my changes without worries. Thank you! :)
     
  24. manny003

    manny003

    Joined:
    Mar 18, 2014
    Posts:
    69

    Just what I needed! Thanks.
     
  25. Obsurveyor

    Obsurveyor

    Joined:
    Nov 22, 2012
    Posts:
    277
    Is the Interactive/Manipulator Events scene script broken? It doesn't seem to do anything when you hit Play except some flashing in the Hierarchy about "Manipulator Events (not loaded)". I'm currently digging into it but any help would be appreciated.

    edit: Figured it out, it doesn't like the Playground Next Scene With Enter script. Disabling that script makes it work.
     
    Last edited: Jan 2, 2016
  26. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Fixing this in the next update!
     
    Last edited: Jan 4, 2016
  27. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Would love some feedback in this thread if you're still on Unity 4, I'm looking into streamlining the development and adding features for PP!
     
  28. Disastercake

    Disastercake

    Joined:
    Apr 7, 2012
    Posts:
    317
    Hey save, I picked up the FT particle package that uses Particle Playground, but I can no longer attach the particles to a prefabed game object (like a missile). Are there detailed instructions on how to get playground particles to work in prefabbed objects?

    Here is the error I get:
    Code (csharp):
    1.  
    2. NullReferenceException: Object reference not set to an instance of an object
    3. FTME01_ParticleController.Update () (at Assets/_Assets/Particles/FT_MagicEffects_volume01/Script/FTME01_ParticleController.cs:124)
    4.  
     
    Last edited: Jan 3, 2016
  29. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    The only thing I can think of is that a Particle Playground system need its dependency references inside the prefab or be hooked up at Awake/Start. For example your Source's or Manipulator Transform(s) needs to be parented to the prefab. Which object is not assigned on line 124?

    In general I can't give my best support on the plugins as they are third-party, in case you need a more detailed answer you could check with the publisher @frontakk.
     
  30. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Update 3.0.3 is available, it's a smaller one taking care of the recent found bugs, adding Playground Trails shadow casting/receiving settings and Universal 10 build support (experimental/beta implementation).

    Features
    1. Playground Trails shadow casting & receiving
      Playground Trails can now be set to cast and receive shadows. Note that the shader for the trail material needs to support this to have any effect.
    2. Windows Universal 10 build support
      Particle Playground projects should now be able to build towards Universal 10 apps. The implementation is still experimental where additional updates to the multithreading architecture could be needed in further releases.
    Fixes
    1. Example scene issues
      Some example scenes got broken in the Unity 5.3 compatibility update due to a miss in PlaygroundNextScene.cs.
    2. Occasional Editor freezes when having the Playground Wizard open and hitting Play
      Due to the Playground Wizard checking the online version using a non-asynchronous method the Unity Editor could freeze before the returning timeout.
    3. Playground Trails having inconsistent length upon calculation cycle frame skips
      The Playground Trails was relying on a global delta time to update all trail points. This made each trail point inconsistent in their length as time would be updated slower when skipping calculation cycles. This was mostly noticeable on particle systems generating a higher amount of trails (~200+). Each trail point is now relying on their own delta time which results in a consistent behavior no matter the time between calculation cycles.
     
    Last edited: Jan 5, 2016
    ian_facepunch, hopeful and DMeville like this.
  31. s_guy

    s_guy

    Joined:
    Feb 27, 2013
    Posts:
    102
    Hi @save ,

    In updating from v2 to v3.0.3, we're encountering a Unity hard crash "Fatal error in gc; too many threads" when a scene with various Particle Playground emitters is loaded. Sometimes it happens from simply loading it in the editor, but it occurs more reliably upon scene load during play. Saving the problem scene with all "t: PlaygroundParticlesC" objects disabled reliably avoids the crash (reverting the project to v2 of particle playground also removes this issue).

    I probably can't share the project, but I can try to get a reduced case. I just wondered if there was any known issue or solution to this before starting the hunt for specific problem assets.

    Also, could you please confirm (or advise) that the following are reasonable and appropriate steps for updating a project from v2 to v3:
    1. Delete v2 install
    2. Import v3 with Unity's download manager
    3. Update custom path in the Particle Playground settings (we put 3rd party stuff under a tools folder)
    Is a step 4 expected, where pre-existing particle emitters need to be rebuilt under v3? We haven't taken this step.

    Thanks.

    EDIT: Some additional info.
    • This occurs on both an i5 with 8GB and i7 with 32GB.
    • The thread settings for Particle Playground are the default (auto, 128).
    • The crasher does not seem to be related to any single emitter, but having too many emitters enabled in the scene. There are about 50 total in the scene; about half of them are on characters and don't emit anything until a script calls it.
     
    Last edited: Jan 6, 2016
    xDavidLeon likes this.
  32. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi!
    This was not a known issue, but let's see if we can track it down.
    - Which version of Unity are you using?
    - How is the Playground Manager > Advanced > Multithreading settings setup (default or custom)?
    - How many particle systems are you trying to load at scene start?

    I'm trying to reproduce this with jumping between scenes having 10, 100 and 1000 particle systems loading at the same time but I can't seem to replicate it using multithreaded startup for the particle systems and then having all calculations running inside the Thread Pool Method: Playground Pool.

    What you could try is disable Advanced > Misc > Multithreaded Startup on your particle systems. I suspect there could be an issue with having a lot of particle systems loading at the same time on certain hardware. Another approach you could try is to batch instantiate particle systems in a sequence after the scene was loaded.

    When updating you should not need to delete the previous version as PP3 is backwards compatible (your old particle systems will still work).
    When putting the Particle Playground folder into another location you should be presented with a dialogue which enables you to automatically find the Playground Settings at the very top in the Playground Wizard (at least after the next Unity start). Then in the Playground Wizard go to Settings > Paths and set the Playground Path to the new location.
     
  33. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Thanks for additional info!
    Ok, 50 systems should not be the issue.
    When using Thread Pool Methoid: Playground Pool you should try to keep Max Threads as low as possible (default 8), this has an affect on how many threads will be generated to reuse. From the Playground Performance page:
    Try use Thread Pool Method: Playground Pool and lower Max Threads to 8 to see if it helps.

    I'm trying to reproduce this using 128 threads for the pool but still no issues (Unity 4.3.4 / 5.0 / 5.3 on an i7). Looking at the CPU resources Unity is overall using around 180 threads when doing this (apart from around 60 threads when Max Threads is set to 8).

    In case you keep having issues it would be great if you could send a stripped down project scenario for debugging to support@polyfied.com.
     
    Last edited: Jan 6, 2016
  34. s_guy

    s_guy

    Joined:
    Feb 27, 2013
    Posts:
    102
    Thanks a lot for the super fast reply!

    I'm on Unity 5.3.0f4.
    The Playground Manager > Advanced > Multithreading settings are all default. ("Playground Pool", "Automatic", "Inside Particle Calculation", "One per System", 128)
    Currently, all Particle Playground systems at scene start are on pre-placed scene objects. Some are instantiated on actor spawn / re-spawn, but I'm fairly certain that doesn't occur at scene start. I'll confirm this asap.

    Sorry, I can't seem to find the Multithreaded Startup option. I don't see a "Misc" section under "Playground Manager > Advanced". I'll give the script suggestion a try after I can find this option.

    I'll try this now and report my results. I'm not sure how the default threads are decided, but that setting was at 128 to start with. How are you seeing the count of threads in use?

    EDIT: Setting Max Threads to 8 seems to resolve the issue! I'll need to profile this but I'm guessing that I'm just providing a hint to the Playground Manager about limitations it already has to deal with. Is that correct? Should I expect a performance hit from this constraint? With a quick check, things seem to be performant still. Max Threads seems to be a setting that is saved per scene, when perhaps it is a project-wide concern?

    Thanks again for the great support. It makes use of this fun package all the more enjoyable.
     
    Last edited: Jan 6, 2016
  35. DMeville

    DMeville

    Joined:
    May 5, 2013
    Posts:
    418
    Hey @save

    Playground trails are quickly becoming my favorite thing ever.
    Just wondering if there would be any plans to have a "smooth trails" version? Using some sort of catmul-rom spline interpolation or something to smooth out jagged edges on fast moving particles.

    Keep up the awesome work!
     

    Attached Files:

  36. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    The Multithreaded Startup option is done per particle system and can be set through their Inspector. It is although preferred whenever possible to do this operation asynchronously as you'll have faster loading times (especially on scenes with a higher amount of particle systems).

    When a new Playground Manager instantiates it will default to 8 (the recommended value in most hardware setups). If you install over a previous version the previous value will be serialized within the scene, this is why you had the old value of 128.

    Max Threads is clamping the generated threads before calculations start to bundle into the same thread calls, if you have less CPUs than Max Threads the processor count will be used instead. The Playground Pool will although generate the specified Max Threads within the pool and iterate through them, which is why you encountered problems as you had too many threads generated from Unity (what that exact number is I'm not sure yet and is not consistent due to Unity versions, projects and hardware).

    You can do this with the built in Resource Monitor on Windows or Activity Monitor on Mac OS.

    You will need to set the Max Threads for each scene as this is a public serialized member on the Playground Manager. This can also be done from script by calling:
    Code (CSharp):
    1. PlaygroundC.SetMaxThreads(int);
    (Reference)
    You can use this to have an overall control over how particle calculations bundle at runtime, perhaps most interesting when working with limited hardware where you want to distribute calculation differently depending on how the scene works and how heavy particle systems you have in it. This can also be controlled by an override on a per particle system basis if you want to bundle certain particle systems together or have a separate thread for a particular one (page 63 in the manual).

    The lower the Max Threads value the better, you will have less threads to iterate through in the Playground Pool and should see a noticeable CPU time difference in the profiler for the PlaygroundC component.

    Awesome to hear, thank you! :)
     
  37. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Great to hear! :)
    Oh yes, this is on the roadmap for version 3.1.
     
    DMeville likes this.
  38. 8r3nd4n

    8r3nd4n

    Joined:
    Sep 10, 2011
    Posts:
    30
    Hi @save

    I have been using script to change the texture state of particles with success using the following:

    Code (CSharp):
    1. public void StartNewParticles(string s, Texture2D t)
    2.     {
    3.         particles.lifetimeColor = CM.StringToGradient(s);
    4.         particles.states[0].stateTexture = t;
    5.         particles.states[0].Initialize();
    6.         particles.emit = true;
    7.     }
    The issue that I am having is that each time the texture gets swapped, it is of different sizes and the particle count does not change according to the new texture. Well, it does in the particle state but not in the particle count section under particle settings. What I am trying to do is set the particle count to be double what the texture sets it at but cant find how to access the particle states particle count variable. If I have this, I would use:

    Code (CSharp):
    1. particles.particleCount = particles.states[0].particleCount * 2; // does not find the particle states count
    How can I set the particle setting count to that of the states?

    Cheers
     
  39. hierro__

    hierro__

    Joined:
    Sep 22, 2014
    Posts:
    59
    Hi all, im trying to generate kind of fire from a skinned mesh renderer, is there any hint about this kind of effect ? Thank you very much in advance
     
  40. Pyroka

    Pyroka

    Joined:
    Oct 22, 2012
    Posts:
    3
    Hey,

    We recently updated from PP 2 to PP 3 and it seems some behaviour has changed regarding rotation (and in particular, rotation of child VFX).

    We have a few VFX prefabs that represent a muzzle-flash, something like this (simplified):
    + Flash
    +---- Fire

    Where Flash is a GameObject with one particle system, and Fire is a child game-object with another one.

    When the player fires a gun we spawn one of these at the end of the barrel and rotate the top-level GameObject so that it points in the correct direction. In PP 2 this worked fine, but in PP 3 the 'Fire' vfx is not being rotated when the parent is. This seems to be tied up to the Rotation part of the Particle Settings, in that if Rotation is 'Off' then the sprite always has no rotation regardless of the parent rotation and if it's on it will use that rotation instead of any rotation on the transforms.

    Is there any-way to re-enable the old behaviour?
     
  41. topsekret

    topsekret

    Joined:
    Apr 18, 2013
    Posts:
    69
    Hello,

    We are currently using Particle Playground 2 (we are hesitant to risk upgrading to 3 since we are within weeks of shipping our game) and we seem to have found an issue with the snapshot feature.

    We have a particle system that has two snapshots that we blend between at runtime. Each snapshot has a world object as its source.

    Originally, we only needed one instance of this particle system. But now we need to have multiple instances, with the only difference between instances being the world object used as the source and the particle count.

    To achieve this, I tried to make the original particle system a prefab. Obviously, the prefab itself lost the references to the game objects in the scene used as sources in the snapshot, but that is fine since it maintained all the other settings. After dragging an instance of the prefab into the scene, I tried setting a new game object as the the source in the two snapshots.

    Everything looked fine until I tried blending between the snapshots (using the "Load" button with a transition time of 2 and "Ease In"). For snapshot 1, I could see particles coming from the new mesh. For snapshot 2 I could see particles from for the new mesh. But as I blended between them , the particles transitioned from the new mesh to the old mesh, then warped to the new mesh again at the end of the transition.

    This same behavior happened even if I just duplicated the particle system in the scene instead of making a prefab first.

    It seems that the particle system is serializing a reference to the old mesh somewhere for the snapshot transition feature and is not correctly reassigning this when I reassign the source world object.

    Any idea on how to fix this? Am I using the tool wrong, or is this a bug?
     
  42. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi!
    Sorry about the late reply. A state has a variable called positionLength which is the amount of positions generated by the texture or mesh. Here's an example:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class SetParticleCountToState : MonoBehaviour {
    6.  
    7.     public PlaygroundParticlesC particles;
    8.  
    9.     void Update () {
    10.         if (particles.particleCount != particles.states[particles.activeState].positionLength * 2)
    11.             particles.particleCount = particles.states[particles.activeState].positionLength * 2;
    12.     }
    13. }
    14.  
     
    Last edited: Jan 18, 2016
  43. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    You can try the Fire - Burning Robot example found in Window > Particle Playground > Presets > Fire. (example)
     
  44. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi! There is no specific changes regarding rotations in version 3 opposed to version 2. I believe that this is based on how Shuriken is functioning since Unity 5.3. What you could do though is set the initialRotationMin and initialRotationMax to the angle you'd prefer (for example based on the z-axis of the parent). Would that work? Otherwise I could have a deeper look into making something flexible for the next update, which will have more options regarding rotations.
     
  45. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Hi,

    If I understand correctly you would need to create a new Snapshot from the duplicated particle system as you have changed the information of where the Source positions are located due to the new World Object.

    If this becomes a world space issue you can then use the script SnapshotToLocalPosition found in the Simple Scripts folder to be able to reposition your snapshots within a local space.

    If you're looking for more flexibility when transitioning between particle systems you could use a (Skinned / Mesh) Target Manipulator and enable whenever transitions should occur. This requires more fine-tuning work though, but will give good control in how particles behave. You can top that with any other Manipulators, such as size and color.

    I am looking into more flexibility for Snapshots in future updates, if you have any suggestions in what's missing feel free to shoot them at me! I can recommend to upgrade to PP3 at a good point in your development cycle to gain performance (CPU time, stack- and heap memory). PP3 is backwards compatible with your PP2 systems.
     
  46. Hilbert

    Hilbert

    Joined:
    Dec 3, 2014
    Posts:
    9
    Is it possible to get the trails working in local space?
    I want my particles to move in a circle around an object which itself moves, and I would like to have trails that only follow this local circular motion, and not the global motion which also depends on the movement of the object that is being circled.

    [And while I'm talking about circles: what is the recommended way to get particles moving in a circle? I'm currently "faking" a circle with a spline. It works, but I'm not entirely happy with it because the "seam" where the beginning and end of the spline meet is somewhat visible.]
     
  47. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Trails are calculated in local space (using a TRS matrix set by the particle system's Transform) when the particle system is set to Advanced > Simulation Space > Local. So by moving the particle system your entire trails should follow accordingly.

    There are some different ways to get particles to move in a circle:
    • Use Force > Force Annihilation > Only Source Positions and rotate the source by its Transform.

    • Force > Force Annihilation > Lifetime Positioning (examples of particle system setups in Example Scenes/Interactive/Lifetime Positioning and Example Scenes/Lifetime Positioning - Manipulators).

    • Use Spline Target Property Manipulator (handmade circle) with Target Method: Particle Time, Transition: Linear, Shape: Infinite and Distance Effect: 0.

    • Use Combined Manipulator, two Math Manipulators setting either Particle Property: Position or Velocity:
      • Type: Sin
      • Type: Cos

    What method to choose is up to what you're looking to do in the end, for example using a Force Annihilation method means that you can't combine the effect with any type of forces. Using any Manipulator Targets you can combine with forces to some extent. Based on your description I would try either Only Source Positions and rotating the Transform or Lifetime Positioning using the Vector3 Animation Curves.
     
  48. Hilbert

    Hilbert

    Joined:
    Dec 3, 2014
    Posts:
    9
    Indeed they do. I was accidentally moving the spline manipulator instead of the particle system, now everything is fine. :)

    (A note for anyone else who might try these: When using the spline manipulator method, it appears that Smoothing should also be set to 0.)

    Thanks a lot. I almost feel guilty for having bought PP during a sale and thus having paid so little for such a great asset.

    EDIT: Now I'm confused again. I played around with the math manipulators, but I haven't managed to understand what it really is that they are supposed to do. I looked at the source code and apparently the Math/Position Sin/Cos manipulators add the value of a (possibly scaled) sin/cos evaluated at the current time onto the current value... this puzzles me, because in essence this leads to the resulting position behaving roughly like an integral of sin/cos, but how close they are the actual integral depends on how evenly spaced the evaluated time indices were. And even worse: while this can be used to approximate some circle, it makes it pretty much impossible to center that circle properly, because we are looking at approximated integrals of the form Int(sin(x), t0, t) that only equal the desired function cos(t) up to an additive constant that depends on the initial time t0 when the particle spawned.
    TL;DR: Sin/Cos math manipulators provide me with something roughly circle-shaped, but as far as I can see they cannot be reliably used to make particles orbit a specific center point.
     
    Last edited: Jan 24, 2016
  49. mcmorry

    mcmorry

    Joined:
    Dec 2, 2012
    Posts:
    580
    @save I have an issue with the Trails. I can't set the layer where they should be created. I could tweak the code for but would be nice to have a better solution. Please let me know if you have any suggestion.
    Thanks
     
  50. save

    save

    Joined:
    Nov 21, 2008
    Posts:
    744
    Ah that makes sense. :)

    Regarding the Math Manipulator and the Particle Property: Position; the structure is because of its necessity of remaining additive and foremost compatible with the other translation and velocity features. If particles were to be set only to the returned sin/cos value then it would have been a really specific scenario removing or interfering any other position and velocity settings, but perhaps I'm looking at it from the wrong angle in this answer - feel free to suggest improvements of course if I'm missing something! Math Manipulator is not a good way of making 'perfect' circles, but rather moving particles in circular motion through translation or velocity.

    The most effective way would be to use local simulation space, emit particles in a circle through script and then rotate the particle system transform, example:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class MoveParticlesInCircle : MonoBehaviour {
    6.    
    7.     public float rotationSpeed = 10f;
    8.     public float radius = 1f;
    9.     public Color32 color;
    10.     public PlaygroundParticlesC particles;
    11.  
    12.     IEnumerator Start ()
    13.     {
    14.         while (!particles.IsReady())
    15.             yield return null;
    16.  
    17.         particles.shurikenParticleSystem.simulationSpace = ParticleSystemSimulationSpace.Local;
    18.  
    19.         for (int i = 0; i<particles.particleCount; i++)
    20.         {
    21.             float angle = ((i*1f) / particles.particleCount) * Mathf.PI * 2;
    22.             particles.Emit(
    23.                 new Vector3(Mathf.Sin(angle) * radius, Mathf.Cos(angle) * radius),
    24.                 Vector3.zero,
    25.                 color
    26.             );
    27.  
    28.         }
    29.     }
    30.  
    31.     void Update ()
    32.     {
    33.         // Rotate the particle system transform
    34.         particles.particleSystemTransform.Rotate(Vector3.forward * Time.deltaTime * rotationSpeed);
    35.     }
    36. }
    Another way is using the Sticky feature (which will make particles stick onto a transform just as if they were parented to it, similar to how local space would behave but in global space and actively responding to scaling). Here's a Sticky example:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using ParticlePlayground;
    4.  
    5. public class MoveParticlesInCircle : MonoBehaviour {
    6.  
    7.     public Transform centreTransform;
    8.     public float rotationSpeed = 10f;
    9.     public float radius = 1f;
    10.     public Color32 color;
    11.     public PlaygroundParticlesC particles;
    12.  
    13.     IEnumerator Start ()
    14.     {
    15.         while (!particles.IsReady())
    16.             yield return null;
    17.  
    18.         particles.stickyCollisions = true;
    19.  
    20.         Vector3 centrePos = centreTransform.position;
    21.  
    22.         for (int i = 0; i<particles.particleCount; i++)
    23.         {
    24.             float angle = ((i*1f) / particles.particleCount) * Mathf.PI * 2;
    25.             Vector3 pos = centrePos + new Vector3(Mathf.Sin(angle) * radius, Mathf.Cos(angle) * radius);
    26.             particles.Emit(
    27.                 pos,
    28.                 Vector3.zero,
    29.                 color
    30.             );
    31.  
    32.             particles.SetSticky (i, pos, Vector3.forward, 0, centreTransform);
    33.         }
    34.     }
    35.  
    36.     void Update ()
    37.     {
    38.         // Update the sticky positions
    39.         for (int i = 0; i<particles.particleCount; i++)
    40.             particles.UpdateSticky(i);
    41.  
    42.         // Rotate the transform
    43.         centreTransform.Rotate(Vector3.forward * Time.deltaTime * rotationSpeed);
    44.     }
    45. }
    46.  
     
    Last edited: Jan 25, 2016