Понимание «структуры» в системе частиц Unity

#c# #unity3d #struct #particle-system

#c# #unity3d #структура #система частиц

Вопрос:

Приведенный ниже код работает, «Particle» является экземпляром класса «ParticleSystem».

«Particle.emission» — это свойство, доступное только для получения, возвращающее структуру «ParticleSystem.EmissionModule»

«em.rate» — это свойство, тип — struct «Система частиц.MinMaxCurve»

 ParticleSystem.EmissionModule em = Particle.emission; 
em.rate = new ParticleSystem.MinMaxCurve(5);
  

Моя проблема в том, почему приведенный выше код может изменять скорость в экземпляре «Частицы»?

Обратите внимание, что структура не является ссылочной, поэтому ее нельзя изменить напрямую, иначе это вызовет CS1612

В настоящее время, я предполагаю, что в структуре «ParticleSystem.EmissionModule» хранятся некоторые ссылки, которые могут связывать или относиться к исходному экземпляру «Particle»?

Комментарии:

1. Очень трудно сказать без полного примера — вы уверены , что EmissionModule это структура? И что, если вы используете Particle.emission.rate , вы увидите новую скорость?

2. Да, я уверен, поэтому я могу указать их тип и описать эту проблему.

3. Как вы убедились, что изменение rate фактически изменяет скорость эмиссии для Particle ? Что произойдет, если вы зарегистрируете значения Particle.emission.rate до и после внесенного вами изменения?

4. Изменено, первоначально равно 10, после — 5

5. Как это действительно ужасно. Нарушает все ожидания…

Ответ №1:

Я тоже заметил это поведение, но я узнал, что происходит, после более глубокого изучения .NET Reflector.

Полный пример вашего кода с последней версией Unity:

 ParticleSystem particle = GetComponent<ParticleSystem>();
ParticleSystem.EmissionModule em = particle.emission;
em.rate = new ParticleSystem.MinMaxCurve(5);
  

Что следует иметь в виду:

ParticleSystem является class .

EmissionModule является struct .

Чтобы изменить скорость излучения частиц в Unity 5 и выше, вы должны получить, ParticleSystem.emission затем сохраните его во временном EmissionModule (struct), затем вы можете изменить его rate переменную

Как это работает?

Когда вы делаете:

 ParticleSystem particle = GetComponent<ParticleSystem>(); 
  

или создайте / создайте экземпляр нового ParticleSystem или прикрепите его через редактор, Unity создаст новый EmissionModule экземпляр. EmissionModule имеет internal конструктор, который принимает ParticleSystem в качестве параметра. Unity немедленно передаст текущий ParticleSystem экземпляр этому EmissionModule конструктору, и этот экземпляр будет сохранен во временной переменной в EmissionModule структуре для последующего использования.

Это выглядит примерно так:

 private ParticleSystem tempParticleSystem;
internal EmissionModule(ParticleSystem particleInstance)
{
    this.tempParticleSystem = particleInstance;
}
  

Когда вы делаете:

 ParticleSystem.EmissionModule em = particle.emission;
  

Unity создаст новый экземпляр EmissionModule из текущей частицы ( particle ) и вернет его. Это будет содержать ту ParticleSystem ссылку (tempParticleSystem), которая была сохранена. Помните, что ParticleSystem это класс, поэтому ссылка все еще там. У emission свойства есть только get средство доступа. Нет set средства доступа. Из-за этого это свойство доступно только для чтения.

emission Свойство выглядит примерно так:

 public EmissionModule emission
{
    get
    {
        return new EmissionModule(this);
    }
}
  

Наконец, когда вы делаете:

 em.rate = ....
  

или измените скорость выбросов, эта сохраненная ссылка используется для изменения скорости частиц в родной части 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);
    }
}
  

Чтобы упростить это, мы можем назвать это результатом class ( ParticleSystem ) внутри struct ( EmissionModule ).

Комментарии:

1. Спасибо, это также, как я догадывался раньше, struct «EmissionModule» хранит ссылку на класс частиц!

2. Да, это было первое, о чем я тоже подумал. Хотел проверить перед публикацией, и это оказалось правдой после использования Reflector для проверки.