Search Unity

Shuriken: Make Particle System Completely Scale

Discussion in 'General Graphics' started by QFSW, Sep 24, 2017.

  1. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Hi all, I've got a bit of an issue.
    In my game I need my entire map to be able to scale up or down, this means the particle systems do too. Some are local and some are world space. Is there any way to make it so that the same system scaled 10x as big would look exactly the same as the original but 10x the size? this means the velocities, gravity, dampening etc would also scale
     
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
  3. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Hierarchy seems to be the best, but from my tests it doesnt affect the physics (e.g gravity scale). Is this intentional or a bug, and how can I work around it?
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I think this has been asked before but I can't recall what we decided. I think there was some argument for both scenarios: I.e some use cases want it to scale and others don't.

    But maybe I'm misremembering..!
     
  5. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Hmm I see. Do you know if it's possible to have it adjust with physics et all without having to multiply all the physics parameters on size change? This would be hugely useful!
     
  6. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Could you attach a script that reads the lossyScale of the transform and multiplies the gravity scale by it?
     
  7. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    The thing is, there's also the limit velocity, start velocity, force etc. So sure I could, but it seems kinda tedious so a native solution would be better. Is this the only way, and does it impact performance?
     
  8. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Those don't work?

    Gravity is kinda special because it's describing an effect that is external to the system (i.e. Is the world also 10x bigger, or just the emitter?)

    Other properties that are purely internal to the particle simulation should scale as you expect.
     
  9. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    So you're saying that gravity scale is the only thing would need changing? if so, I'll give it a test and report back
     
  10. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Scale = 0.1x
    Gravity = -0.01x
    upload_2017-9-24_21-32-19.png

    Scale = 10x
    Gravity = -1x
    upload_2017-9-24_21-33-4.png

    Doesn't seem like its scaling right? Or maybe im doing something wrong?
     
  11. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    It also seems like it's not just the physics, but the particles arent as big / growing as big. This seems odd given I'm using hierarchy. It's as if I make the parent smaller, the particle systems get smaller at a quicker rate?
     
  12. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    Does the particle system have sub emitter and inherit size?

    IIRC Noise module does not scale automatically either.

    Edit: Don't scale the particle system and even the map, move your camera instead.
     
    Last edited: Sep 25, 2017
  13. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    So is it not possible to scale the system?
     
  14. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    It's just some very basic scripting with ParticleSystem classes. The trickiest part would be figuring out which particle parameter is scaled automatically or not. Also mostly you would modify "~Multiplier" (which uses float value) instead to avoid the minMaxCurve valuetype (e.g. gravityModifierMultiplier instead of gravityModifier). Again, moving your camera removes all these scaling hassles.
     
  15. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    The thing is even If I don't scale the map, there are other times where I will need to do this particle system scaling anyway

    EDIT: Ignore stuff about sizes overshooting, I didn't change max size in renderer to compensate, sorry! Maybe this should be automatic though, idk
     

    Attached Files:

  16. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Sorry, didn't see your first q btw. No sub emitters or inherit size, however I would like a solution that doesn't stop me from adding some in the future
     
  17. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    hmm, this is strange. Tests are showing that different things need scaling depending on the simulation space. For example, noise and limit velocity seem to behave as normal on local space, but go completely out of whack on world space. @richardkettlewell, do you know if this is the case?
     
  18. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    In no way I'm blaming Ric and Karl for inconsistent design, but the scaling of particle system is still undergoing changes because the use cases vary from user to user. (I was able to convince them to scale the emission rate over distance conversely to transform.scale, but I always have a fear that other users might find this change detrimental.) That's why inheriting transform.scale from an object parent for a particle prefab is the least thing I would recommend doing. If you're scaling a particle fx (e.g. an individual buff magic spell) for different body sizes of characters which rarely scaled beyond 1.5x to 0.5x, then scaling by transform is the way to go. But your goal to zoom in/out the whole map along with the particle effects within is better to be dealt with camera, not transform.scale. Not to forget that fiddling the particle system with script has the potential to prevent draw call batching.

    And yes, there is still the scaling inconsistency involving simulation space which I can't tell if that's intentional or not.
     
    Last edited: Sep 25, 2017
  19. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Seems to be mostly working with the paramaters I've set up, will need to add more as I need them, but this should serve as a starting point for anyone facing the same issue.
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class ParticleSystemScaler : MonoBehaviour
    7. {
    8.     private ParticleSystem ThisSystem;
    9.     private ParticleSystem.MainModule ThisMain;
    10.     private ParticleSystem.NoiseModule ThisNoise;
    11.     private ParticleSystem.LimitVelocityOverLifetimeModule ThisLimitVelocity;
    12.  
    13.     private float CurrentScale;
    14.  
    15.     private float InitialGravity;
    16.     private float InitialNoiseStrength;
    17.     private float InitialNoiseFrequency;
    18.     private float InitialMaxVelocity;
    19.  
    20.     private void Start()
    21.     {
    22.         Initialise();
    23.         ResizeSystem(transform.lossyScale.x);
    24.     }
    25.  
    26.     private void Initialise()
    27.     {
    28.         ThisSystem = GetComponent<ParticleSystem>();
    29.  
    30.         if (ThisSystem)
    31.         {
    32.             ThisMain = ThisSystem.main;
    33.             ThisNoise = ThisSystem.noise;
    34.             ThisLimitVelocity = ThisSystem.limitVelocityOverLifetime;
    35.  
    36.             InitialGravity = ThisMain.gravityModifierMultiplier;
    37.             InitialNoiseStrength = ThisNoise.strengthMultiplier;
    38.             InitialNoiseFrequency = ThisNoise.frequency;
    39.             InitialMaxVelocity = ThisLimitVelocity.limitMultiplier;
    40.         }
    41.     }
    42.  
    43.     private void ResizeSystem(float NewScale)
    44.     {
    45.         CurrentScale = NewScale;
    46.  
    47.         if (ThisSystem)
    48.         {
    49.             ThisMain.gravityModifierMultiplier = InitialGravity * NewScale;
    50.             if (ThisMain.simulationSpace == ParticleSystemSimulationSpace.World)
    51.             {
    52.                 ThisNoise.strengthMultiplier = InitialNoiseStrength * NewScale;
    53.                 ThisNoise.frequency = InitialNoiseFrequency / NewScale;
    54.                 ThisLimitVelocity.limitMultiplier = InitialMaxVelocity * NewScale;
    55.             }
    56.         }
    57.     }
    58.  
    59.     private void Update()
    60.     {
    61.         if (transform.lossyScale.x != CurrentScale) { ResizeSystem(transform.lossyScale.x); }
    62.     }
    63. }
    64.  
    65.  
     
    Last edited: Sep 25, 2017
    DenDunno, Alic and xthewhitel like this.
  20. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Differences between world/local simulation space are almost certainly bugs, if you could report them with a sample project I'd appreciate it.

    Max render size is by design - that is for controlling performance by limiting pixel coverage.

    With so many options that need scaling, it's likely you've found a few properties that have been overlooked. Glad you got it working though!
     
    Alic likes this.
  21. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    So if I understand correctly, gravity not scaling is intentional but everything else is either a bug/oversight?
     
  22. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Correct (Min/Max Particle Size is also intentionally ignored, as that is a screen-space percentage for optimization purposes)

    Thanks :)
     
    Alic and QFSW like this.
  23. olejuer

    olejuer

    Joined:
    Dec 1, 2014
    Posts:
    211
    Resurrecting this old thread:

    I find it very unintuitive that particle systems cannot be easily scaled. I understand that there is a number of possible behaviours that one might expect and it's not easy to find the right solution for everyone.
    Simulation space, gravity, sub emitters, scaling modes, ...

    Still, I would like to have the ability to scale an entire particle system without affecting its look. This is very often needed when integrating assets from the store into a project of different scale. Creating a script that would cover all settings to achieve this reliably seems to be quite complex.

    Could it be that by now there is a solution to this?
     
  24. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Sure - just set the scaling mode to Hierarchy, in the main module settings.
     
  25. olejuer

    olejuer

    Joined:
    Dec 1, 2014
    Posts:
    211
    Thanks!
    I am aware of scaling modes. However, this thread is about scaling particle systems with a gravity modifier. While most properties of a particle system scale as you would expect, the effect of gravity does not. I think the rationale behind that is that gravity is a global physics property and there is a "Force over Lifetime" module that can be used instead. This makes sense, but I recon the use case of scaling a particle system AND the gravity modifier multiplier is common. Personally, I need this to use effects from asset packs that make heavy use of gravity modifier.
     
    Julian_Nementic likes this.
  26. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    hmmm indeed, that’s a tricky one. I can imagine wanting both options (scale gravity, don’t scale gravity) depending on the use case. And you’re right - we don’t have anything for that right now.

    It’s not ideal, but you could have a script component that stores the initial gravity multiplier in Start, then sets it in each Update based on the transform scale. Eg gravityModifier = InitialValue * transform.scale.y;

    though this only works for uniform scale.
     
  27. olejuer

    olejuer

    Joined:
    Dec 1, 2014
    Posts:
    211
    Yeah, that's what was proposed before. I have written a script that does that with [ExecuteInEditMode] so that the system can be previewed in the editor. But it does not account for rotations, scewing, dirty flags, subsystems, ... I agree it's tricky.
    I just wanted to raise awareness that this diminishes the value of various assets, which is unfortunate.

    Thanks for taking the time to think about it!