Связанные этапы частиц: sub-emitter
Связь источников, режимы событий, вместимость и завершение цепочки.
Связь sub-emitter передаёт рождения частиц из одной GPU-системы в другую существующую GPU-систему. Она не создаёт дочернюю Entity или новую Entity системы для каждой частицы. Оба источника могут быть соседями в дереве сцены.
Настройте связь и событие
- Создайте обе GpuParticles3D с материалами симуляции и отображаемыми мешами в нужном World3D.
- Назначьте Sub Emitter основного источника путём к целевому. Путь разрешается от основного источника, не от корня сцены.
- В ParticleProcessMaterial основного выберите Sub Emitter Mode, отличный от Disabled, и нужное количество/частоту.
- Оставьте автономную Emitting цели выключенной: рождения задаёт основной источник. Не перезапускайте цель постоянно как обычный циклический эффект.
- Запустите основной источник и проверьте границы, материалы и вместимость обоих. Правильный путь не включает отключённый режим материала.
Перед назначением пути в коде создайте и добавьте обе Entity. После смены родителя или замены цели разрешите связь заново: сохранённый EntityPath не чинит автоматически каждую будущую иерархию.
Нужен поддерживаемый GPU-путь. Текущая реализация материала предупреждает о неподдерживаемых неотключённых sub-emitter-режимах в Compatibility. Пример исполнен на Windows Forward+/Vulkan и не подтверждает все целевые устройства.
Запустите пару AtEnd в C#
using System;
using Reckfell;
public static class ParticleChain
{
private static GpuParticles3D Emitter(string name, Color color)
{
var surface = new StandardMaterial3D
{
ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded,
AlbedoColor = color,
};
return new GpuParticles3D
{
Name = name, Emitting = false, Amount = 32, Lifetime = 1.2,
LocalCoords = false, UseFixedSeed = true, Seed = 42,
DrawPass1 = new QuadMesh { Size = new Vector2(0.12f, 0.12f), Material = surface },
VisibilityAabb = new Aabb(new Vector3(-3, -3, -3), new Vector3(6, 6, 6)),
};
}
public static (GpuParticles3D primary, GpuParticles3D secondary) Create(Entity root)
{
if (!root.IsInsideTree()) throw new ArgumentException("Add the root to the tree first.");
var primary = Emitter("Primary", Colors.Red);
primary.Amount = 4; primary.OneShot = true; primary.Lifetime = 0.3;
primary.Explosiveness = 1;
primary.ProcessMaterial = new ParticleProcessMaterial
{
Direction = Vector3.Right, Spread = 0, Gravity = Vector3.Zero,
InitialVelocityMin = 0.6f, InitialVelocityMax = 0.6f,
SubEmitterMode = ParticleProcessMaterial.SubEmitterModeEnum.AtEnd,
SubEmitterAmountAtEnd = 2,
};
var secondary = Emitter("Secondary", Colors.Blue);
secondary.ProcessMaterial = new ParticleProcessMaterial
{
Direction = Vector3.Up, Spread = 0, Gravity = Vector3.Zero,
InitialVelocityMin = 0.4f, InitialVelocityMax = 0.4f,
};
root.AddChild(primary);
root.AddChild(secondary);
// Both Entities exist before resolving the relative target path.
primary.SubEmitter = primary.GetPathTo(secondary);
return (primary, secondary);
}
}Из Entity, уже находящейся в дереве, вызовите var (primary, secondary) = ParticleChain.Create(this); и primary.Restart();. Активная камера должна охватывать эффект. Красные частицы основного источника запускают синие в конце своей жизни. Геометрия функциональная: для готового эффекта замените ассеты и материалы.
Нативная проверка подтверждает отсутствие мгновенного запуска цели при AtEnd и последующее появление после основного этапа. AtStart показывает цель у начала цикла. Entity остаётся две. Отключение режима материала или очистка пути предотвращает дальнейшие рождения цели.
Осознанно выберите режим
| Режим | Условие / настройка |
|---|---|
| Disabled | Материал не генерирует sub-emission. |
| AtStart | Рождение основной частицы; SubEmitterAmountAtStart. |
| AtEnd | Конец жизни основной частицы; SubEmitterAmountAtEnd. |
| AtCollision | Подходящий контакт частицы; SubEmitterAmountAtCollision. Нужны рабочие GPU-столкновения. |
| Constant | Повторная эмиссия, пока основная частица активна; SubEmitterFrequency в герцах. |
Количество относится к каждой сработавшей основной частице, не одному глобальному всплеску. Частота Constant должна быть конечной и положительной; setter переводит Hz в интервал. Ограничения шага симуляции не позволяют обещать точный поток произвольной высокой частоты при любом шаге.
SubEmitterKeepVelocity управляет передачей скорости основной частицы. В генерируемом пути она может заменить инициализацию начальной скорости цели; не считайте это простым сложением со всеми её скоростями/силами. Это сверено по исходникам, но не входит в текущие сравнения пикселей.
Учитывайте вместимость и жизненный цикл
Amount цели остаётся её вместимостью. Большее число запрошенных рождений не гарантирует их размещение и отдельную видимость. Оценивайте число основных частиц × события × дочерние рождения с учётом жизни цели, наложений и следующих этапов. Цепочка не бесплатна и не должна быть бесконечной.
Не задавайте прямую ссылку на себя и косвенные циклы. Это не поддерживаемые рецепты рекурсивных эффектов. Проектируйте конечные этапы, а не рассчитывайте на самостоятельное завершение рекурсии.
Finished основного источника не подтверждает исчезновение цели. У неё собственные частицы и время жизни; готового единого события завершения всей цепочки нет. Не освобождайте/возвращайте всю пару в пул только по основному сигналу. Учитывайте также ограничение SpeedScale/Finished.
При работе с префабами Editable Children определяет доступность редактирования экземпляра в редакторе, а не общее runtime-разрешение на разрешение пути. Проверяйте реальную иерархию и назначайте связь после появления нужных Entity.
Найдите причину отсутствия второго этапа
| Симптом | Что проверить |
|---|---|
| Основной виден, цели нет | Относительный путь, существование цели, режим основного материала и отображение цели. |
| Не работает только AtCollision | Сначала CollisionMode, GPU-коллайдеры и маски, затем sub-emission. |
| Частиц цели мало | Её Amount, время жизни, число событий и наложение геометрии. |
| Цель исчезает при завершении основного | Пул/жизненный цикл может слишком рано освобождать пару. |
| Не работает замена цели из префаба | Разрешение от основного после создания/смены родителя. |
| Материал обновляется с задержкой | Обновление/подготовку шейдера и перезапуск контролируемого сравнения; не судите по одному промежуточному кадру. |
Проверены относительная связь, AtEnd/AtStart/Disabled, удаление связи и неизменная иерархия Entity. Constant, AtCollision, передача скорости, циклы, сложный пул, другие рендереры/экспорты и производительность этим примером не подтверждены.