Search Unity

Building up scenes with all particles simulating

Discussion in 'General Graphics' started by FeastSC2, Aug 27, 2017.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    When creating my scenes I would like to be able to see my particles moving, basically simulating as if I was clicking on it in the hierarchy.

    Like in this video:


    During the creation, his props are moving through shaders ok but what about the Particle System like the sun shafts?
     
  2. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    There is no straightforward way to preview all particle systems automatically in the same scene during edit mode because you risk lagging the editor severely when more particle systems are present. The only way to preview a group of particle systems without manually selecting multiple objects is to nest all particle system objects to a same parent object and this parent needs a particle system component as well, just uncheck all modules, emission and renderer especially, then when you select and simulate either particle system, the rest in the same object tree will simulate altogether.
     
    theANMATOR2b likes this.
  3. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Ok thanks for the info ifurkend. Too bad it can't be done. Maybe I can use shaders to move the shafts and other various elements rather than using the particle systems. But it might take more time than it's worth.
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    FYI we have been working on a way to preview all systems in Edit Mode :)
     
    karl_jones and FeastSC2 like this.
  5. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    One option to achieve this is to write a script with the ExecuteInEditMode attribute on it. You can the call ParticleSystem.Simulate in that script.
     
  6. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Cool that's nice ;) I guess I'm doing something wrong in my script then.

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. [ExecuteInEditMode]
    7. public class SimulateAllPS : MonoBehaviour
    8. {
    9.     private readonly List<ParticleSystem> AllParticleSystems = new List<ParticleSystem>();
    10.     private float Timer;
    11.     public float RefreshPsTime = 10f;
    12.     public bool RefreshNow = true;
    13.  
    14.     void Start ()
    15.     {
    16.        Timer = 0f;
    17.        AllParticleSystems.AddRange(FindObjectsOfType<ParticleSystem>());
    18.  
    19.        Debug.Log("Start");
    20.  
    21.        foreach (var ps in AllParticleSystems)
    22.        {
    23.            //if (ps.isStopped || ps.isPaused)
    24.            ps.Simulate(0);
    25.  
    26.            Debug.Log("Simulating: " + ps);
    27.        }
    28.     }
    29.  
    30.     void Update ()
    31.     {
    32.         Debug.Log("Updating");
    33.  
    34.         if (RefreshNow)
    35.         {
    36.             AllParticleSystems.Clear();
    37.             AllParticleSystems.AddRange(FindObjectsOfType<ParticleSystem>());
    38.  
    39.             foreach (var ps in AllParticleSystems)
    40.             {
    41.                 if (ps.isStopped || ps.isPaused)
    42.                     ps.Simulate(0);
    43.  
    44.                 Debug.Log("Simulating: " + ps);
    45.             }
    46.         }
    47.  
    48.      
    49.  
    50.         //Timer += Time.deltaTime;
    51.         //if (Timer > RefreshPsTime)
    52.         //{
    53.         //    AllParticleSystems.Clear();
    54.           // AllParticleSystems.AddRange(FindObjectsOfType<ParticleSystem>());
    55.         //}
    56.     }
    57. }
    58.  
    I tried a bunch of different ways but my PS are not simulating.
     
  7. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Check the params you are passing to Simulate. One is a "restart" bool. Make sure it's false, and set the time param to Time.deltaTime.

    Your script looks almost good though.. I'm sure it's nearly working!
     
    theANMATOR2b, karl_jones and FeastSC2 like this.
  8. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Richard, are you sure this is supposed to work?
    The particle system seem to advance 1 frame and then stop. We would need to call it every frame, but ExecuteInEditMode only call update when there is a scene change and in this case it gets called only once.
    Anybody was able to make it work?
    It would be very useful to preview particles all at once in the editor without selecting each.
     
  9. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I'm pretty sure it works... I know other developers who are using the technique successfully. Admittedly, I'm not sure about the update frequency of [ExecuteInEditMode] scripts though. Googling suggests you're right about the update frequency, and some more googling suggests that this may work for you: https://answers.unity.com/questions/1006398/executeineditmode-than-runs-update-all-the-time.html

    If/when you upgrade to 2017.3, you'll notice a new option in the Scene View Overlay, called Simulate Layers. You can use this to get the preview behavior you want, without writing any custom scripts.
     
    karl_jones likes this.
  10. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Thank you very much! I am already on 2017.3 so I'll use the latter.
    I saw that option before but thought it was something for performance, some sort of particle culling.
    Works beautifully now.
     
    richardkettlewell likes this.
  11. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Hi Richard, going back to this as I am trying to control particles manually in gameplay.
    Is there any way to set the time of the particle emittter?
    The time property doesn't seem to work, it just continue to play.
    And the simulate method seem to play all the particles up to the time given, there is no start time.
    I am looking for something like Animator.StartPlayback.
    You can seek in editor by moving the time slider, so I guess you have some way.
     
  12. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Code (CSharp):
    1. ps.Simulate(startTime, true, true);
    ought to do it.

    That will restart the system and play it up to the point you want.

    If you want to be smarter for forwards scrubbing, you can detect that you're going forwards, and avoid the restart, (set param 3 to false) and simply simulate forwards by newTime - ps.time.
     
    00christian00 likes this.
  13. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Doesn't work. It seem to render few frames and rewind.
    I found some code that set the randomseed property before simulating. If I do that, the parent emitter behave correctly, the child emitter still play when they shouldn't.
    Is it a bug? Do I need to set the randomseed of all the child systems?
     
  14. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    I made a bug report(1010191).
    After further digging it seem to make it work you need to set the randomseed property of all the ParticleSystem involved, including children.
    I don't think that is the expected behavior.
     
    karl_jones likes this.
  15. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I think it’s probably “by design”. I can see why it’s not ideal for you here though. The auto seed mode changes the seed on each restart. I suspect changing this behavior would cause problems for other users, so I think it must stay as it is.

    As you have discovered, it’s simple to set a fixed seed to get the behavior you want (and you can always use a fresh seed in a situation where you do want it to trigger differently)
     
    00christian00 likes this.
  16. kepesh

    kepesh

    Joined:
    Dec 29, 2017
    Posts:
    92
    I can't find the Simulate Layers option, I'm on 2017.4.

    Where is this option exactly?

    Thanks
     
  17. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    In the scene view, when playing a particle system in edit mode, there is a little dialog in the lower right corner with play/pause etc buttons in it. It’s on there. We may have renamed it after feedback.. just to keep you guessing!!
     
  18. kepesh

    kepesh

    Joined:
    Dec 29, 2017
    Posts:
    92
    What have you renamed it to?
    Will this simulate all of my particles in the scene?
     
  19. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I checked, Simulate Layers is the final name, any renaming must have happened earlier during internal testing.

    All looping effects. And only if you set the layer mask to a value that encompasses all your particle systems.
     
  20. tgb-joel

    tgb-joel

    Joined:
    Nov 30, 2018
    Posts:
    1
    Hopping on here to continue the conversation.

    I've noticed this 'Simulate Layers' option, and it's useful -- but is there any way to set these layers through code?

    For context: Our team's toolset sidesteps default GameObject selection, so when using the tool, our artists are never actually selecting the Particle System. I'd like to set these Simulate Layers automatically when they open the tool.
     
  21. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    There are 2 ways but I think only one will work.. (I’m not in the the office so can’t give a precise answer right now)

    1. The value is set in the registry. So you could set it in the registry yourself. However, I doubt we re-fetch the current value from the registry each time, so I suspect this is the way that won’t work robustly.

    2. Call our internal API yourself. It’s called previewLayers and is declared here: https://github.com/Unity-Technologi...riptBindings/ParticleSystemEditor.bindings.cs

    There are various examples online of how to call internal methods from c# via reflection on google, if you’re not familiar with it. It comes with the obvious caveat that we might change it in the future.. but realistically I think that’s unlikely.
     
    jperry_oddgames likes this.
  22. jperry_oddgames

    jperry_oddgames

    Joined:
    Sep 18, 2017
    Posts:
    62
    I realize this is an old thread, but I've just found it and got all particles on a prefab simulating during prefab edit-time.

    For anyone struggling to get particles smoothly updating with the Simulate method, make sure you call the UnityEditor.SceneView.RepaintAll method each time you update
     
    Last edited: May 21, 2021
    mserkies and Lorrak like this.