For the complete documentation index, see llms.txt. This page is also available as Markdown.

Эффекты

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

Эффекты можно использовать на игроках, NPC или любой сущности. Они особенно полезны, когда вам нужно:

  • Движение, которым вы управляете в коде (рывок/отбрасывание/кувырок)

  • На короткое время "заблокировать" ввод игрока для последовательности (еда, воскрешение, катсцена)

  • Ограниченное по времени состояние (неуязвимость, замедление, оглушение)

  • UI, привязанное к временным состояниям (таймер возрождения)

Активные и пассивные

All Out поддерживает два типа эффектов:

  • Активные эффекты: по одному за раз на сущность. Назначение нового активного эффекта прерывает текущий активный эффект.

  • Пассивные эффекты: можно прикреплять несколько одновременно (стекаемые баффы/дебаффы/статусы).

Активный эффект также добавляется в список эффектов сущности, поэтому он появляется в effect_iterator так же, как и пассивные эффекты.

Быстрый старт (простой эффект с таймером)

Создайте класс, который наследуется от Effect_Base, затем прикрепите его к сущности.

Apple_Pop_Effect :: class : Effect_Base {
    sprite: Sprite_Renderer;
    start_scale: v2;
    start_pos: v2;

    effect_start :: method() {
        sprite = entity.get_component(Sprite_Renderer);
        start_scale = entity.local_scale;
        start_pos = entity.local_position;
        set_duration(0.4); // автоматически удаляется через 0.4 с
    }

    effect_update :: method(dt: float) {
        t := get_elapsed_time() / 0.4;

        // Увеличить, а затем уменьшить до нуля
        scale_curve: float;
        if t < 0.3 {
            scale_curve = lerp(1.0, 1.3, Ease.out_back(t / 0.3));
        } else {
            scale_curve = lerp(1.3, 0.0, Ease.in_back((t - 0.3) / 0.7));
        }

        entity.set_local_scale(start_scale * scale_curve);

        // Слегка всплываем вверх
        rise := Ease.out_quad(t) * 0.5;
        entity.set_local_position({start_pos.x, start_pos.y + rise});

        // Почти в конце исчезаем
        if sprite != null {
            alpha := 1.0 - Ease.in_quad(max(0.0, (t - 0.5) / 0.5));
            sprite.color.w = alpha;
        }
    }

    effect_end :: method(interrupt: bool) {
        // Очистить ресурсы по завершении (или при прерывании)
        entity.destroy();
    }
}

Добавьте его как активный эффект:

Жизненный цикл эффекта

Эффекты основаны на колбэках. Реализуйте только то, что нужно:

  • effect_start(): вызывается один раз, когда эффект прикрепляется

  • effect_update(dt): вызывается каждый кадр

  • effect_late_update(dt): вызывается каждый кадр после effect_update

  • effect_end(interrupt): вызывается, когда эффект удаляется

Активные эффекты (эксклюзивное управление)

Используйте set_active_effect для эффектов, которые должны быть взаимоисключающими (рывок, подготовка атаки, последовательность смерти).

Если у сущности уже есть активный эффект, он завершается с interrupt = true.

Пассивные эффекты (стекаемые баффы / статусы)

Используйте add_passive_effect для эффектов, которые могут складываться (замедление, яд, щит, окно неуязвимости).

Справочник API

Effect_Base

Применение / удаление эффектов

Проверка / перебор эффектов

freeze_player по сравнению с disable_movement_inputs

  • player_specific.freeze_player = true: полностью блокирует положение игрока.

  • player_specific.disable_movement_inputs = true: игнорирует ввод, но ваш эффект всё ещё может перемещать игрока (рывок/кувырок).

Оба варианта применяются только когда player != null (то есть эффект находится у сущности, у которой есть Player компонент).

Эмоции игрока

Эмоции игрока используют встроенный активный эффект. Запуск другой эмоции прерывает текущую эмоцию, а любой другой активный эффект не даёт запустить новую эмоцию. Движение прерывает эмоции и восстанавливает основную анимационную прослойку, кроме Emote/T_Pose, которая позволяет двигаться.

Используйте причины блокировки, когда геймплей должен временно запретить колесу эмоций запускать эмоцию:

Причины учитываются как записи, поэтому важно вызывать add/remove в паре. remove_emote_block_reason удаляет одну совпадающую запись и возвращает, была ли она найдена. Вы также можете напрямую запросить или управлять встроенным эффектом:

try_trigger_emote возвращает false когда анимация не экипирована, эмоции заблокированы или другой тип активного эффекта уже управляет игроком. Обычное колесо эмоций использует тот же путь.

Примеры эффектов

Рывок / кувырок (активный эффект)

Окно неуязвимости (пассивный эффект)

Используйте пассивный эффект для представления состояния неуязвимости и проверяйте его везде, где наносите урон.

Увеличение размера в 2 раза на несколько секунд (пассивный эффект)

Последовательность смерти / возрождения (активный эффект с локальным UI)

Блокировка катсцены (активный эффект)

Плавные пользовательские визуальные эффекты

Симуляция работает с фиксированной частотой, тогда как рендеринг может идти быстрее. Отрисовка из колбэка компонента автоматически привязывается к сущности этого компонента. В других случаях:

  • Оберните отрисовку в мировом пространстве для другой сущности в UI.begin_world_space_ui(entity) и UI.end_world_space_ui().

  • Для движущейся позиции, которая не принадлежит сущности, храните постоянный Position_Interpolation_Helper. Передавайте смещение из update(position) в UI.push_interpolation_offset, затем уберите его после отрисовки.

  • Используйте постоянный Float_Interpolation_Helper с UI.quad_fill для изменяющегося значения полосы.

  • Вызывайте entity.mark_teleported() после резкого изменения позиции.

Храните вспомогательные объекты интерполяции в постоянном состоянии компонента или UI. Вспомогательный объект, созданный внутри метода draw, не имеет предыдущего кадра, от которого можно интерполировать.

Лучшие практики

  • Используйте set_active_effect когда эффект на короткое время "владеет" сущностью (рывок/атака/смерть/катсцена).

  • Используйте add_passive_effect для накапливаемого состояния (баффы/дебаффы/статусы).

  • Используйте set_duration(...) для эффектов с таймером вместо ручных таймеров.

  • Всегда восстанавливайте любое изменённое состояние в effect_end (трение, масштаб, триггеры анимации и т. д.).

  • Запускайте игровые эффекты в общем предсказанном пути.

  • Рисуйте UI, связанный с эффектами, из ao_late_update игрока и защищайте его с помощью is_local_or_server().

Последнее обновление