Разработка системы частиц и VFX для мобильной игры

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Разработка системы частиц и VFX для мобильной игры
Средний
~3-5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    743
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1160
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    968
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    562

Мы разрабатываем системы частиц и VFX для мобильных игр, которые выглядят убедительно даже на бюджетных устройствах. В нашей практике десктопный эффект из 50 000 частиц на iPhone 11 приводил к перегреву и 20 FPS. Мы нашли предел: эффект выглядит качественно при 10 000 частицах или меньше, соблюдая температурный режим. С накопленным опытом более 5 лет мы подбираем оптимальный стек и технику для каждой платформы. Правильная система частиц повышает retention игроков на 15% по нашим данным, при этом не требует дорогих устройств.

Выбор инструмента: Unity vs SpriteKit vs Metal

Большинство мобильных игр используют одно из трёх: Unity Particle System (Shuriken), Apple SpriteKit SKEmitterNode, или кастомную систему на Metal/OpenGL ES/Vulkan для особых требований. Сравним их в таблице.

Инструмент Платформа Производительность Гибкость Когда использовать
Unity Shuriken Cross-platform Высокая (GPU Instancing) Средняя 2D/3D игры на Unity
SpriteKit SKEmitterNode iOS Очень высокая (нативный) Низкая 2D игры только на iOS
Metal Compute Shaders iOS Максимальная Высокая Сложные кастомные эффекты

Unity Shuriken — де-факто стандарт. Визуальный редактор, поддержка Sub Emitters, GPU Instancing, Burst компилятор для CPU-симуляции. VFX Graph (GPU-симуляция через Compute Shaders) работает на мобиле начиная с Metal (iOS 12+) и Vulkan (Android API 24+). На старых устройствах VFX Graph недоступен — нужен fallback на Shuriken.

SpriteKit SKEmitterNode — для 2D-игр нативно на iOS. Простой, быстрый, без overhead Unity. Но ограниченный: нет Sub Emitters, нет custom shaders без Metal. Для несложных эффектов (огонь, дождь, конфетти) достаточно.

Какой инструмент выбрать для VFX в мобильной игре?

Если проект кросс-платформенный, берите Unity Shuriken. Для iOS-only 2D-игр хватит SpriteKit. Если нужны уникальные эффекты с полным контролем — пишите кастомные шейдеры на Metal. Наша команда гарантирует, что выбранный стек не упрётся в ограничения GPU на целевых устройствах.

Бюджет частиц и GPU ограничения

На мобильных GPU (Apple A-серия, Adreno, Mali) bottleneck часто не в числе частиц, а в overdraw — количестве раз, которое один пиксель экрана перерисовывается за кадр.

Полупрозрачные частицы с аддитивным blending (Additive shader mode) дают overdraw кратно числу слоёв. На взрыве из 5000 частиц в центре экрана реальный overdraw может быть 50–100x. Это убивает fill rate даже на A15.

Стратегии снижения:

  • Texture Atlasing: все спрайты частиц — в один атлас 512×512 или 1024×1024. Минус drawcall на каждую смену текстуры
  • Billboard imposters: для объёмных эффектов (облако взрыва) — quad с запечённой текстурой вместо сотен сфер
  • LOD для частиц: на расстоянии / при низком fps — уменьшить maxParticles вдвое через QualitySettings.particleRaycastBudget или кастомный LOD-менеджер
// Unity: динамический LOD системы частиц по FPS
public class ParticleLODManager : MonoBehaviour {
    [SerializeField] private ParticleSystem targetSystem;
    private ParticleSystem.MainModule _main;
    private float _fpsTimer;

    void Start() {
        _main = targetSystem.main;
    }

    void Update() {
        _fpsTimer += Time.deltaTime;
        if (_fpsTimer < 1f) return;
        _fpsTimer = 0;

        float fps = 1f / Time.smoothDeltaTime;
        if (fps < 45f) {
            _main.maxParticles = Mathf.Max(100, _main.maxParticles / 2);
        } else if (fps > 58f && _main.maxParticles < originalMax) {
            _main.maxParticles = Mathf.Min(originalMax, _main.maxParticles * 2);
        }
    }
}

Почему overdraw — главный враг производительности?

GPU-симуляция через VFX Graph работает в 4 раза быстрее CPU-симуляции на A14 Bionic, но overdraw съедает этот выигрыш. При аддитивном смешении каждый пиксель может перерисовываться десятки раз. Чтобы этого избежать, мы применяем Texture Atlasing и сокращаем количество частиц с высоким альфа-наложением.

Кастомные шейдеры для мобильных VFX

Встроенные Unity шейдеры для частиц (Particles/Standard Unlit) безопасны, но ограничены. Для dissolve-эффекта, heat distortion, energy shield — нужен кастомный шейдер.

На мобиле правила жёсткие: нет discard в шейдере (ранний Z-test ломается, fill rate падает), минимум texture samples, избегаем dependent texture reads. Shader Model 2.0 как baseline для широкого охвата.

Пример простого distortion-эффекта для взрыва (Unity HLSL):

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

sampler2D _NoiseTex;
float _DistortionStrength;
float _FadeEdges;

fixed4 frag (v2f i) : SV_Target {
    float2 noise = tex2D(_NoiseTex, i.uv + _Time.y * 0.3).rg * 2 - 1;
    float2 distortedUV = i.uv + noise * _DistortionStrength * i.color.a;

    float edge = 1 - saturate(distance(distortedUV, float2(0.5, 0.5)) * _FadeEdges);
    fixed4 col = tex2D(_MainTex, distortedUV) * i.color;
    col.a *= edge;
    return col;
}
ENDCG

i.color.a — это alpha частицы от Unity Particle System, синхронизируется с lifetime. Distortion затухает вместе с частицей автоматически.

Эффекты на SpriteKit: огонь и конфетти

SKEmitterNode настраивается либо в редакторе Xcode (.sks файл), либо программно. Программно — предпочтительно для динамических параметров:

func makeFireEmitter() -> SKEmitterNode {
    let emitter = SKEmitterNode()
    emitter.particleTexture = SKTexture(imageNamed: "spark")
    emitter.particleBirthRate = 120
    emitter.particleLifetime = 1.2
    emitter.particleLifetimeRange = 0.4
    emitter.particleSpeed = 80
    emitter.particleSpeedRange = 40
    emitter.emissionAngle = .pi / 2  // вверх
    emitter.emissionAngleRange = .pi / 8
    emitter.particleScale = 0.15
    emitter.particleScaleSpeed = -0.1
    emitter.particleAlphaSpeed = -0.8
    emitter.particleColorSequence = SKKeyframeSequence(
        keyframeValues: [SKColor.yellow, SKColor.orange, SKColor.red, SKColor.clear],
        times: [0, 0.3, 0.7, 1.0]
    )
    emitter.particleBlendMode = .add
    return emitter
}

.add blending — аддитивное смешение. Огонь и искры выглядят светящимися. Не используем для дыма и пыли — там нужен .alpha.

Инструменты профилирования GPU

Xcode Metal Debugger — frame capture для Metal-игр. Видно каждый draw call, текстуры, overdraw visualization. Для Unity на iOS: через Xcode GPU Frame Debugger при подключении через USB.

Android GPU Inspector (AGI) — от Google для Adreno и Mali. Frame Profiler показывает pipeline stages, где GPU ждёт.

Unity Profiler — встроенный, покажет время CPU/GPU на рендер каждого эффекта. Rendering → ParticleSystem.Update занимает > 2ms — смотрим на CPU-симуляцию и снижаем maxParticles или переходим на GPU Mode.

Что входит в работу

  • Разработка кастомных шейдеров под целевую платформу
  • Оптимизация existing систем частиц (LOD, атласинг, overdraw)
  • Интеграция в игровой движок (Unity, SpriteKit, кастомный)
  • Профилирование и настройка под слабые устройства
  • Документация по параметрам и поддержка

Процесс работы

Технический арт-дирекшн: какие эффекты нужны, их частота на экране одновременно, целевые устройства. Разработка шейдеров и систем частиц в редакторе с профилированием на слабом Android-девайсе. Настройка LOD-системы. Интеграция в игровой движок, тест на тепловые throttling (10-минутная игровая сессия с анализом температуры).

Ориентиры по срокам

3–5 рабочих дней на базовый набор VFX (3–5 типов эффектов). Сложная кастомная система на Metal Compute Shaders — от 2 недель. Конкретная стоимость рассчитывается индивидуально после анализа ваших требований. Оценим ваш проект: свяжитесь с нами для предварительного анализа. Получите консультацию по выбору инструмента для ваших эффектов.

Анимации в мобильных приложениях: Lottie, Rive, Spring и Reanimated

Мы сделали анимации для десятков проектов — от игровых интерфейсов до bank-grade приложений. Знаем, как заставить 120 fps работать даже на Android с ProGuard. Если анимация дёргается — проблема не в инструменте, а в выборе подхода. Ниже покажем, как мы выбираем между Lottie и Rive, почему Spring physics побеждает UIView.animate, и как Reanimated 3 выжимает 60 fps на старых устройствах. Получите консультацию по вашему проекту — оценим анимационный слой бесплатно.

Почему UIView.animate ломается на сложных сценариях

UIView.animate(withDuration:) и ObjectAnimator на Android — правильный выбор для простых переходов. Но как только анимация становится интерактивной (пользователь тянет элемент, скорость зависит от жеста), нужен другой подход.

На iOS для gesture-driven анимации правильный инструмент — UIViewPropertyAnimator. Он позволяет приостанавливать, обращать и модифицировать анимацию в процессе. Типичный кейс: bottom sheet, который следует за пальцем, продолжает движение с инерцией после отпускания и притягивается к ближайшей позиции. С UIView.animate это либо не работает совсем, либо требует ручной физики.

В SwiftUI withAnimation работает из коробки, но интерактивность ограничена — нет прямого аналога UIViewPropertyAnimator. Обходной путь: .gesture(DragGesture()) + @GestureState + явное вычисление позиции. Или уходим в SwiftUI Animations API с Animation.spring(duration:bounce:) из iOS 17.

Как React Native Reanimated обходит JS-мост

React Native Animated API выполняет анимации в JS thread — это источник джанка при загруженном bridge. Reanimated 3 решает проблему через worklets: функции, которые компилируются и выполняются прямо на UI thread без пересечения JS-моста.

Пример: parallax scroll header. На базовом Animated.Value при быстром скролле FPS падает до 40-45 на mid-range Android. На Reanimated с useAnimatedScrollHandler — стабильные 60 fps, потому что весь пересчёт позиции происходит на UI thread.

Reanimated 3 с useSharedValue, useAnimatedStyle и withSpring/withTiming — это текущий стандарт для анимаций в React Native. Gesture Handler v2 плотно интегрирован: useAnimatedGestureHandler заменяет PanResponder и тоже работает на UI thread.

Почему Lottie может снижать FPS на Android

Lottie экспортирует After Effects анимацию в JSON. На iOS с lottie-ios работает стабильно, но на Android при сложных эффектах (blur, частицы, градиенты) векторный рендеринг через Canvas приводит к просадкам до 30-40 fps. Решение — либо упрощать анимацию, либо использовать Rive с аппаратным рендерингом. Мы тестировали: Lottie-файл с размытием 5 МБ на Xiaomi Redmi Note 10 даёт 48 fps, аналогичная анимация в Rive (.riv 400 КБ) — 60 fps.

Lottie vs Rive: что выбрать для интерактивных интерфейсов

Оба инструмента решают задачу «дизайнер делает анимацию, разработчик добавляет файл». Но принципиально по-разному.

Подробное сравнение в таблице
Критерий Lottie Rive
Формат JSON векторная анимация Бинарный .riv
Интерактивность Нет (линейное воспроизведение) State Machine, реакции на ввод
Производительность Средняя (blur/частицы тяжелы) Аппаратный рендеринг Metal/OpenGL
Размер файла 2-5 МБ 200-500 КБ
Поддержка платформ iOS, Android, Web, Flutter, RN iOS, Android, Web, Flutter, RN

Выбор прост: статичная декоративная анимация (splash screen, onboarding иллюстрации) — Lottie. Интерактивные UI-элементы с состояниями — Rive. Например, кнопка с hover, pressed, loading, success — одна Rive-анимация с четырьмя состояниями против четырёх отдельных Lottie-файлов.

Дополнительно: Lottie — стандарт для размеченной векторной анимации, Rive — более гибкий инструмент с физикой и state machine.

Spring-физика и Hero transitions: как добиться естественности

Spring-анимация ощущается естественно потому что имитирует физику — массу, жёсткость и демпфирование. В SwiftUI: Animation.spring(response:dampingFraction:). В Android Compose: spring(dampingRatio = Spring.DampingRatioMediumBouncy).

Для Hero-переходов (элемент «перелетает» между экранами) на iOS используем UIViewControllerTransitioningDelegate + UIViewControllerAnimatedTransitioning. В SwiftUI с iOS 17 — matchedTransitionSource + navigationTransition(.zoom). На Flutter — Hero виджет, который работает из коробки.

Как избежать типичных ошибок в Hero transitions?

Анимация начинается нормально, но на целевом экране элемент «прыгает» в финальную позицию. Причина — AutoLayout constraints применяются до завершения анимации. Решение: layoutIfNeeded() в блоке анимации или использование transform вместо frame-изменений.

Что входит в работу: анимационный слой под ключ

  • Интеграция Lottie/Rive-файлов в дизайн-систему
  • Код gesture-driven переходов (bottom sheets, drawers, карусели)
  • Тестирование на реальных устройствах (iOS 15–17, Android 10–14)
  • Документация по анимациям (архитектура, ключи состояний)
  • Поддержка при обновлении дизайна (гарантия 30 дней)

У нас 5+ лет опыта в мобильной разработке, более 30 проектов с анимациями, сертифицированные iOS/Android разработчики.

Сроки выполнения

  • Базовые экранные переходы и микроинтеракции — 1 неделя.
  • Lottie/Rive интеграция с дизайн-системой — 3-5 дней после получения финальных файлов.
  • Кастомная gesture-driven интерактивность (sheet, drawer, карусель с физикой) — 1-2 недели.

Напишите нам — добавим анимации под ключ за 2 недели. Первая консультация бесплатно.