Understanding the “Struct” in Unity ParticleSystem

前端 未结 1 535
一生所求
一生所求 2020-12-12 01:28

The code below is working, \"Particle\" is an instance of class \"ParticleSystem\".

\"Particle.emission\" is a get-only property return struct \"Par

相关标签:
1条回答
  • 2020-12-12 02:01

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

    0 讨论(0)
提交回复
热议问题