I noticed this behavior too but I found out what's happening after digging deeper with .NET Reflector.
The complete example of your code with the latest Unity version:
ParticleSystem particle = GetComponent<ParticleSystem>();
ParticleSystem.EmissionModule em = particle.emission;
em.rate = new ParticleSystem.MinMaxCurve(5);
Things to bear in mind:
ParticleSystem
is a class
.
EmissionModule
is a struct
.
To change the Particle's emission rate in Unity 5 and above, you must get the ParticleSystem.emission
then store it in a temporary EmissionModule
(struct) then you can modify it's rate
variable
How does this work?
When you do:
ParticleSystem particle = GetComponent<ParticleSystem>();
or create/instantiate new ParticleSystem
or attach one through the Editor, Unity will create new EmissionModule
instance. EmissionModule
has a an internal
constructor that takes ParticleSystem
as a parameter. Unity will immediately pass the current ParticleSystem
instance to this EmissionModule
constructor and that instance is stored in a temporary variable in the EmissionModule
struct for later use.
It looks something like this:
private ParticleSystem tempParticleSystem;
internal EmissionModule(ParticleSystem particleInstance)
{
this.tempParticleSystem = particleInstance;
}
When you do:
ParticleSystem.EmissionModule em = particle.emission;
Unity will create new instance of EmissionModule
from the current particle (particle
) and return it. That will contain that ParticleSystem
(tempParticleSystem) reference that was saved. Remember that ParticleSystem
is a class, so the reference is still there. The emission
property only have the get
accessor. No set
accessor. Because of this, it is a read only property.
The emission
property looks something like this:
public EmissionModule emission
{
get
{
return new EmissionModule(this);
}
}
Finally, when the you do:
em.rate = ....
or change the emission rate, that saved reference is used to change the Particle rate in the native side of Unity which is written in C++.
public ParticleSystem.MinMaxCurve rate
{
get
{
ParticleSystem.MinMaxCurve curve = new ParticleSystem.MinMaxCurve();
getParticleRate(this.tempParticleSystem, ref curve);
return curve;
}
set
{
setParticleRate(this.tempParticleSystem, ref value);
}
}
To simplify this, we can call this a result of a class
(ParticleSystem
) inside a struct
(EmissionModule
).