#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 для проверки.