理解Unity ParticleSystem中的"结构"

Dev*_*per 2 c# struct unity-game-engine particle-system

下面的代码是有效的,"Particle"是类"ParticleSystem"的一个实例.

"Particle.emission"是一个get-only属性返回结构"ParticleSystem.EmissionModule"

"em.rate"是一个属性,类型是struct"ParticleSystem.MinMaxCurve"

ParticleSystem.EmissionModule em = Particle.emission; 
em.rate = new ParticleSystem.MinMaxCurve(5);
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么上面的代码可以改变"粒子"实例中的速率?

注意struct不是引用,因此不能直接更改,否则会导致CS1612

目前,我的猜测是结构"ParticleSystem.EmissionModule"存储了一些可以链接或与原始"粒子"实例相关的引用?

Pro*_*mer 6

我也注意到了这种行为,但是在深入研究.NET Reflector后我发现了正在发生的事情.

使用最新Unity版本的代码的完整示例:

ParticleSystem particle = GetComponent<ParticleSystem>();
ParticleSystem.EmissionModule em = particle.emission;
em.rate = new ParticleSystem.MinMaxCurve(5);
Run Code Online (Sandbox Code Playgroud)

要记住的事情:

ParticleSystem 是一个class.

EmissionModule是一个struct.

要在Unity 5及更高版本中更改粒子的发射速率,必须先将其ParticleSystem.emission存储在临时EmissionModule(struct)中然后可以修改它的rate变量

这是如何运作的?

当你这样做时:

ParticleSystem particle = GetComponent<ParticleSystem>(); 
Run Code Online (Sandbox Code Playgroud)

或者ParticleSystem通过编辑器创建/实例化新的或附加一个,Unity将创建新的EmissionModule实例.EmissionModule有一个internal构造函数ParticleSystem作为参数.Unity将立即将当前ParticleSystem实例传递给此EmissionModule构造函数,并将该实例存储在EmissionModulestruct 中的临时变量中供以后使用.

它看起来像这样:

private ParticleSystem tempParticleSystem;
internal EmissionModule(ParticleSystem particleInstance)
{
    this.tempParticleSystem = particleInstance;
}
Run Code Online (Sandbox Code Playgroud)

当你这样做时:

ParticleSystem.EmissionModule em = particle.emission;
Run Code Online (Sandbox Code Playgroud)

Unity将从EmissionModule当前粒子(particle)创建新实例并返回它.这将包含ParticleSystem已保存的(tempParticleSystem)引用.请记住,这ParticleSystem是一个类,所以引用仍然存在.该emission属性只具备get存取.没有set访问者.因此,它是一个只读属性.

emission属性看起来像这样:

public EmissionModule emission
{
    get
    {
        return new EmissionModule(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,当你这样做时:

em.rate = ....
Run Code Online (Sandbox Code Playgroud)

或者更改发射率,保存的引用用于更改Unity的本机端的粒子速率,该速率是用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

为了简化这一点,我们可以将其称为a class(ParticleSystem)中的struct(EmissionModule)结果.