Dynamic Variable in C#

Unity 5.5 obsolete particle system code

particle.startLifetime:

First of all, what Unity did in Unity 5.5 was to add new futures to the ParticleSystem. They also exposed some ParticleSystem API that was hidden before.

ParticleSystem.MainModule.startLifetime is now a type of MinMaxCurve instead of float like ParticleSystem.startLifetime.

By doing this, you are now given more options such as modifying the startLifetime as a curve.

Reading or writing to ParticleSystem.MainModule.startLifetime depends on the value of ParticleSystem.MainModule.startLifetime.mode which is set through the Editor or via code.

enter image description here

The default value of ParticleSystem.MainModule.startLifetime.mode is ParticleSystemCurveMode.Constant

So your m_OriginalLifetime = m_System.main.startLifetime.constant; is fine.

If startLifetime is dynamically or randomly changed to another mode during run-time, then you will have to do something like this:

ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;

ParticleSystem.MinMaxCurve minMaxCurve = main.startLifetime;

if (minMaxCurve.mode == ParticleSystemCurveMode.Constant)
{
m_OriginalLifetime = m_System.main.startLifetime.constant;
}
else if (minMaxCurve.mode == ParticleSystemCurveMode.Curve)
{
AnimationCurve animCurveLifetime = m_System.main.startLifetime.curve;
}
...

particle.startSize:

The-same thing apply to particle.startSize.
The particle.startSize property is now m_System.main.startSize;

Although you can't do m_System.main.startSize.constant *= myMultiplier; because your old code was particle.startSize *= myMultiplier.

You need to get m_System.main.startSize, modify it then assign the modified m_System.main.startSize back to m_System.main.startSize.

particle.startSize *= myMultiplier should be:

ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;

ParticleSystem.MinMaxCurve minMaxCurve = main.startSize; //Get Size

minMaxCurve.constant *= myMultiplier; //Modify Size
main.startSize = minMaxCurve; //Assign the modified startSize back

Then, what are particle.main.startSizeMultiplier and particle.main.startSize used for?

This two variables can also be used to change startLifetime and startSize. It's main advantage is that it is very efficient. It does not not require that you make a copy of MinMaxCurve like we did above, in order to change startSize or startSizeMultiplier.

ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;
main.startSizeMultiplier = 5;

and

ParticleSystem m_System = GetComponent<ParticleSystem>();
ParticleSystem.MainModule main = m_System.main;
main.startLifetimeMultiplier = 8;

Use them if your ParticleSystem.MainModule.startLifetime.mode is constant. This will to change the overall lifetime multiplier or the the overall size multiplier efficiently.


Changing Color and Color Modes

Color:

There is an implicit operator that lets you use:

ParticleSystem.MainModule main = trailPartical.main;
main.startColor = Color.red;

but startColor is not actually type of Color. The startColor variable is now a type of ParticleSystem.MinMaxGradient.

This is how you should be changing the particle startColor:

//Create Color
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.Color;
color.color = Color.red;

//Assign the color to your particle
ParticleSystem.MainModule main = trailPartical.main;
main.startColor = color;

Gradient:

public ParticleSystem particleSystem;

void Start()
{
//Create Gradient key
GradientColorKey[] gradientColorKey;
gradientColorKey = new GradientColorKey[3];
gradientColorKey[0].color = Color.red;
gradientColorKey[0].time = 0f;
gradientColorKey[1].color = Color.blue;
gradientColorKey[1].time = 0.5f;
gradientColorKey[2].color = Color.green;
gradientColorKey[2].time = 1f;

//Create Gradient alpha
GradientAlphaKey[] gradientAlphaKey;
gradientAlphaKey = new GradientAlphaKey[3];
gradientAlphaKey[0].alpha = 1.0f;
gradientAlphaKey[0].time = 0.0f;
gradientAlphaKey[1].alpha = 0.5f;
gradientAlphaKey[1].time = 0.5f;
gradientAlphaKey[2].alpha = 1f;
gradientAlphaKey[2].time = 1f;

//Create Gradient
Gradient gradient = new Gradient();
gradient.SetKeys(gradientColorKey, gradientAlphaKey);

//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.Gradient;
color.gradient = gradient;

//Assign the color to particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
}

Random Between Two Colors:

//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.TwoColors;
color.colorMin = Color.red;
color.colorMax = Color.green;

//Assign the color to the particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;

Random Between Two Gradients:

public ParticleSystem particleSystem;

void Start()
{

//Create Gradient key Min
GradientColorKey[] gradientColorKeyMin;
gradientColorKeyMin = new GradientColorKey[3];
gradientColorKeyMin[0].color = Color.red;
gradientColorKeyMin[0].time = 0f;
gradientColorKeyMin[1].color = Color.blue;
gradientColorKeyMin[1].time = 0.5f;
gradientColorKeyMin[2].color = Color.green;
gradientColorKeyMin[2].time = 1f;

//Create Gradient alpha Min
GradientAlphaKey[] gradientAlphaKeyMin;
gradientAlphaKeyMin = new GradientAlphaKey[3];
gradientAlphaKeyMin[0].alpha = 1.0f;
gradientAlphaKeyMin[0].time = 0.0f;
gradientAlphaKeyMin[1].alpha = 0.5f;
gradientAlphaKeyMin[1].time = 0.5f;
gradientAlphaKeyMin[2].alpha = 1f;
gradientAlphaKeyMin[2].time = 1f;

//Create Gradient key Max
GradientColorKey[] gradientColorKeyMax;
gradientColorKeyMax = new GradientColorKey[3];
gradientColorKeyMax[0].color = Color.red;
gradientColorKeyMax[0].time = 0f;
gradientColorKeyMax[1].color = Color.blue;
gradientColorKeyMax[1].time = 0.5f;
gradientColorKeyMax[2].color = Color.green;
gradientColorKeyMax[2].time = 1f;

//Create Gradient alpha Max
GradientAlphaKey[] gradientAlphaKeyMax;
gradientAlphaKeyMax = new GradientAlphaKey[3];
gradientAlphaKeyMax[0].alpha = 1.0f;
gradientAlphaKeyMax[0].time = 0.0f;
gradientAlphaKeyMax[1].alpha = 0.5f;
gradientAlphaKeyMax[1].time = 0.5f;
gradientAlphaKeyMax[2].alpha = 1f;
gradientAlphaKeyMax[2].time = 1f;

//Create Gradient Min
Gradient gradientMin = new Gradient();
gradientMin.SetKeys(gradientColorKeyMin, gradientAlphaKeyMin);

//Create Gradient Max
Gradient gradientMax = new Gradient();
gradientMax.SetKeys(gradientColorKeyMax, gradientAlphaKeyMax);

//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.TwoGradients;
color.gradientMin = gradientMin;
color.gradientMax = gradientMax;

//Assign the color to the particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
}

Random Color:

public ParticleSystem particleSystem;

void Start()
{

//Create Gradient key Min
GradientColorKey[] gradientColorKeyMin;
gradientColorKeyMin = new GradientColorKey[3];
gradientColorKeyMin[0].color = Color.red;
gradientColorKeyMin[0].time = 0f;
gradientColorKeyMin[1].color = Color.blue;
gradientColorKeyMin[1].time = 0.5f;
gradientColorKeyMin[2].color = Color.green;
gradientColorKeyMin[2].time = 1f;

//Create Gradient alpha Min
GradientAlphaKey[] gradientAlphaKeyMin;
gradientAlphaKeyMin = new GradientAlphaKey[3];
gradientAlphaKeyMin[0].alpha = 1.0f;
gradientAlphaKeyMin[0].time = 0.0f;
gradientAlphaKeyMin[1].alpha = 0.5f;
gradientAlphaKeyMin[1].time = 0.5f;
gradientAlphaKeyMin[2].alpha = 1f;
gradientAlphaKeyMin[2].time = 1f;

//Create Gradient key Max
GradientColorKey[] gradientColorKeyMax;
gradientColorKeyMax = new GradientColorKey[3];
gradientColorKeyMax[0].color = Color.red;
gradientColorKeyMax[0].time = 0f;
gradientColorKeyMax[1].color = Color.blue;
gradientColorKeyMax[1].time = 0.5f;
gradientColorKeyMax[2].color = Color.green;
gradientColorKeyMax[2].time = 1f;

//Create Gradient alpha Max
GradientAlphaKey[] gradientAlphaKeyMax;
gradientAlphaKeyMax = new GradientAlphaKey[3];
gradientAlphaKeyMax[0].alpha = 1.0f;
gradientAlphaKeyMax[0].time = 0.0f;
gradientAlphaKeyMax[1].alpha = 0.5f;
gradientAlphaKeyMax[1].time = 0.5f;
gradientAlphaKeyMax[2].alpha = 1f;
gradientAlphaKeyMax[2].time = 1f;

//Create Gradient Min
Gradient gradientMin = new Gradient();
gradientMin.SetKeys(gradientColorKeyMin, gradientAlphaKeyMin);

//Create Gradient Max
Gradient gradientMax = new Gradient();
gradientMax.SetKeys(gradientColorKeyMax, gradientAlphaKeyMax);

//Create Color from Gradient
ParticleSystem.MinMaxGradient color = new ParticleSystem.MinMaxGradient();
color.mode = ParticleSystemGradientMode.RandomColor;
color.gradientMin = gradientMin;
color.gradientMax = gradientMax;

//Assign the color to the particle
ParticleSystem.MainModule main = particleSystem.main;
main.startColor = color;
}

Unable to get new unity particle system code working post update

Issue A

Only one ParticleSystem component can be attached to any one GameObject at a time. Sub-ParticleSystems must therefore be attached to separate GameObjects too (generally children of the GameObject holding the first ParticleSystem), which can be dropped directly onto public fields.

public ParticleSystem LeafStormParticleSystem;

void Start ()
{
if (LeafStormParticleSystem != null)
{
var main = LeafStormParticleSystem.main;
main.maxParticles = 150;
}
}

Issue B

Your code looks fine, however a critical part of the error message was missing; NullReferenceException which is telling you that a reference in your code is equal to NULL. In your case, that reference would be the ps variable used to store the ParticleSystem reference, which is either a consequence of not attaching this script to the GameObject holding your ParticleSystem or simply that you have no ParticleSystem attached at all. In either case, make sure both script and ParticleSystem are attached to the same GameObject and check your references like so;

void Start ()
{
ParticleSystem ps = GetComponent<ParticleSystem>();

if (ps != null)
{
var main = ps.main;
main.maxParticles = 150;
}
}

Trouble stopping particle emission in unity

I don't have unity opened right now, but I think that

GetComponent<ParticleSystem>().Stop();

is what you need. You can restart the system using

GetComponent<ParticleSystem>().Play();

Also, if you do this often, you should consider keeping your particle system in a class variable.

Can't use c# particleSystem property anymore?

Base on the relevant Unity documentation, this is another property that has been recently (since version 5.4.0) deprecated.

So yes, you will now have to use GetComponent<ParticleSystem>() instead to get a reference to the particle system - and you'll probably want to cache that reference in a variable in the Awake() method in the event that you need to frequently make use of it.

Get particle gradient color

At the moment, we can't read the MinMaxCurve from scripts, as per here: https://blogs.unity3d.com/2016/04/20/particle-system-modules-faq/ (scroll down to the Easing the Pain section).

However, your code returns not a MinMaxCurve, but the Start Color of type Color that you can set via inspector or via script.

For example, if you create a Particle System game object in a scene, and you attach to it this simple script:

using UnityEngine;

public class ParticlesTest : MonoBehaviour {

ParticleSystem myParticleSystem;
public Color myColor;

private void Awake() {
myParticleSystem = GetComponent<ParticleSystem>();
}

private void Update() {
myColor = myParticleSystem.main.startColor.color;
}
}

you can see that myColor changes when you change the Start Color value of the Particle System in Play mode.

Accessing Unity particle emitter via script

Presently, your LeafStormParticleSystem variable gives you a reference to the GameObject that the ParticleSystem component is on, but not the ParticleSystem itself. As a result, you can't access members of the particle system like maxParticles and emission. There are two approaches you can take to correct this:

Call GetComponent<ParticleSystem>() when you need access to the particle system. This can be costly if done too often - syntax to modify members would be:

LeafStormParticleSystem.GetComponent<ParticleSystem>().maxParticles = 500;

Change your LeafStormParticleSystem from a GameObject to a ParticleSystem. This lets you assign to LeafStormParticleSystem a direct reference to the particle system in the editor, and is more efficient than calling GetComponent() repeatedly. Syntax would be:

// Change the datatype
public ParticleSystem LeafStormParticleSystem;

// [...]
// To modify members later, you can do as you're currently doing:
LeafStormParticleSystem.maxParticles = 500;

// Modifying the emission rate is a bit less straightforward, because emission is a struct
var newEmission = LeafStormParticleSystem.emission;
newEmission.rate = new ParticleSystem.MinMaxCurve(5.0f);
LeafStormParticleSystem.emission = newEmission;

Hope this helps! Let me know if you have any questions.



Related Topics



Leave a reply



Submit