Movement Component в Unreal Engine

Друзья, приветствую, с Вами Будуев Антон. В данной статье мы обсудим абстрактный компонент Movement Component, отвечающий в Unreal Engine (UE5, UE4) за функциональность передвижения. Разберём настройки данного компонента, а также Blueprint-функции, связанные с ним.

Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.

Movement Component в Unreal Engine

Movement Component в Unreal Engine — это абстрактный компонент, который отвечает за логику перемещения связанного с ним Updated Component (обновляемого компонента, обычно это Root-компонент Актора-владельца), обновляя его положение и ориентацию каждый кадр. Этот компонент предоставляет широкий набор функций для управления движением, коллизиями и взаимодействием с физическим миром.

Абстрактный компонент (Abstract Component) — это класс компонента, который не может быть создан напрямую. Он служит в качестве основы или шаблона для других, более конкретных (неабстрактных) компонентов.

Вследствие своей абстрактности, Movement Component через ряд других компонентов является базовым классом для более специализированных компонентов движения, таких как Character Movement Component, Floating Pawn Movement и других классов, наделяя эти классы дополнительной функциональностью, а именно:

  • передвижение Актора-владельца (обычно, его Root-компонента);
  • ограничение движения по плоскости или оси;
  • автоматическая регистрация тика компонента (Tick);
  • поиск компонента для перемещения на Акторе-владельце;
  • вспомогательные C++ функции (SlideAlongSurface(), ComputeSlideVector(), TwoWallAdjust()) для специальной обработки коллизии (результатов столкновений);
  • дополнительные C++ функции для перемещения при возможном первоначальном проникновении объектов друг в друга (SafeMoveUpdatedComponent(), ResolvePenetration()).
Функциональность абстрактного компонента Movement Component, расширяющая настройки компонентов Floating Pawn Movement и Character Movement
Функциональность абстрактного компонента Movement Component, расширяющая настройки компонентов Floating Pawn Movement и Character Movement

Updated Component

Как уже писалось выше, абстрактный компонент Movement Component перемещает связанный с ним Updated Component.

По сути, Updated Component — это целевой компонент, на который применяются все вычисления и действия, связанные с движением. Он имеет тип Scene Component (компонент сцены). Это означает, что обновляемым компонентом может быть любой компонент, унаследованный от Scene Component, например Static Mesh Component, Skeletal Mesh Component, Capsule Component. Важно, чтобы это был именно компонент сцены, потому что Movement Component использует его трансформацию (местоположение, вращение и масштаб) для вычисления и применения движения.

Чаще всего в качестве Updated Component используется Root-component (корневой компонент) Актора. Корневой компонент — это «основа» Актора, и его перемещение влечет за собой перемещение всего Актора (включая все прикрепленные к нему компоненты). Именно поэтому, если не указано иное, Movement Component часто автоматически пытается назначить Root-component Актора в качестве Updated Component (если параметр данного компонента Auto Register Updated Component установлен в значение True).

Однако, Updated Component не обязательно должен быть Root-компонентом. В некоторых случаях может потребоваться перемещать только часть Актора, оставив остальное на месте. Переназначить обновляемый компонет для Movement Component позволяет специализированная функция Set Updated Component, которая назначает новый компонент для перемещения и обновления.

Настройки Movement Component во вкладке Details

Компонент Movement Component является дочерним от класса Actor Component. Соответственно, многие настройки вкладки Details также были унаследованы от родительского компонента. Чтобы не повторяться, в этой статье рассмотрим только дополнительные настройки, относящиеся к Movement Component.

Остальные повторяющиеся настройки (Component TickTagsReplicationVariableCookingAsset User DataNavigation) Вы можете изучить в отдельной статье: Details в Actor Component.

Velocity

Настройки Velocity абстрактного компонента Movement Component
Настройки Velocity абстрактного компонента Movement Component
  • Velocity (скорость) — текущая скорость обновленного компонента.

Planar Movement

Категория Planar Movement (движение по плоскостям) определяет ограничения движения компонента в пределах плоскости. Это может быть полезно для создания 2D-игр или для ограничения движения в 3D-игре.

Настройки Planar Movement абстрактного компонента Movement Component
Настройки Planar Movement абстрактного компонента Movement Component
  • Plane Constraint Normal (нормаль ограничения плоскости) — нормаль или ось плоскости, которая ограничивает движение, если включена опция Constrain To Plane. Значение 0 — движение по оси разрешено, значение 1 — движение по оси заблокировано.
  • Plane Constraint Origin (начало ограничительной плоскости) — начало координат плоскости, которая ограничивает движение, если включена опция Constrain To Plane.
  • Constrain to Plane (ограничить плоскостью) — если установлено значение True, движение будет ограничено плоскостью. Включает или отключает ограничение движения в заданной плоскости. Полезно для создания 2.5D игр или для ограничения движения в определенных областях.
  • Snap to Plane at Start (привязать к плоскости при старте) — если установлено значение True, и включены ограничения плоскости, обновленный компонент будет привязан к плоскости при первом подключении. Параметр гарантирует, что Актор начнёт движение непосредственно на плоскости, если включено ограничение.
  • Plane Constraint Axis Setting (настройка оси ограничения плоскости) — параметр, который контролирует поведение, когда движение ограничено 2D-плоскостью, определяемой конкретной осью/нормалью, в связи с чем движение вдоль заблокированной оси невозможно.

Movement Component

Категория Movement Component (компонент движения) определяет базовые настройки обновления компонента в Unreal Engine (UE4, UE5).

Основные настройки абстрактного компонента Movement Component
Основные настройки абстрактного компонента Movement Component
  • Update Only if Rendered (обновлять только если отображается) — если Актор не виден на экране, его движение не будет обновляться (функция TickComponent() пропускается), что экономит ресурсы. Может вызвать проблемы, если объект должен двигаться за пределами видимости.
  • Auto Update Tick Registration (автоматически обновлять регистрацию Tick) — если установлено значение True, всякий раз, когда обновленный компонент изменяется, Movement Component включит или отключит свой Tick в зависимости от того, есть ли что-то для обновления. Автоматически включает и отключает Tick компонента движения в зависимости от того, нужно ли ему выполнять обновление. Помогает оптимизировать производительность.
  • Tick Before Owner (выполнять Tick перед владельцем) — если установлено значение True, Tick компонента Movement Component выполняется перед Tick его владельца. Порядок Tick может быть важен для правильной работы некоторых систем. Эта опция гарантирует, что компонент движения будет обновлён до того, как будет обновлен Актор-владелец.
  • Auto Register Updated Component (автоматически регистрировать обновляемый компонент) — если установлено значение True, движок регистрирует корневой компонент Актора-владельца в качестве Updated Component, если в данный момент нет назначенного компонента для обновления. Иначе говоря, параметр автоматически назначает корневой компонент Актора в качестве компонента, который будет перемещаться.
  • Auto Register Physics Volume Updates (автоматически регистрировать обновления объёма физики) — параметр позволяет компоненту движения автоматически обновлять информацию о Physics Volume, в котором находится Актор.
  • Component Should Update Physics Volume (компонент должен обновлять объём физики) — параметр определяет, влияет ли компонент движения на обновление Physics Volume, что может быть важно для обеспечения стабильного поведения при движении в разных средах.

Blueprint-функции, связанные с абстрактным компонентом Movement Component

Управление плоскостью ограничения движения

Функции управления плоскостью ограничения движения
Функции управления плоскостью ограничения движения
  • Constrain Direction to Plane — ограничивает вектор направления движения ограничением плоскости.
  • Constrain Location to Plane — ограничивает заданную позицию в пространстве плоскостью ограничения.
  • Constrain Normal to Plane — ограничивает вектор нормали (единичной длины) ограничением плоскости.
  • Set Plane Constraint Axis Setting — устанавливает ось ограничения движения по плоскости, изменяя нормаль плоскости.
  • Set Plane Constraint Enabled — включает или отключает ограничение движения по плоскости.
  • Set Plane Constraint from Vectors — вычисляет плоскость ограничения движения на основе векторов Forward (вперёд) и Up (вверх).
  • Set Plane Constraint Normal — задаёт нормаль плоскости, ограничивающую движение, принудительно применяемую, если включено ограничение плоскости.
  • Set Plane Constraint Origin — задаёт начало координат плоскости, ограничивающей движение, принудительно применяемой, если включено ограничение плоскости.
  • Snap Updated Component to Plane — перемещает Updated Component на плоскость ограничения. Это полезно для инициализации положения компонента или для исправления его положения, если он каким-то образом оказался вне плоскости

Получение информации

Функции получения информации
Функции получения информации
  • Get Plane Constraint Axis Setting — возвращает текущую настройку оси ограничения движения по плоскости.
  • Get Plane Constraint Normal — возвращает текущий вектор нормали плоскости ограничения.
  • Get Plane Constraint Origin — возвращает текущую точку начала координат плоскости ограничения.
  • Get Gravity Z — возвращает силу тяжести (силу гравитации), влияющую на этот компонент.
  • Get Max Speed — возвращает максимальную скорость компонента в текущем режиме движения (например, при ходьбе, беге, плавании).
  • Get Physics Volume — возвращает указатель на Physics Volume, в котором находится компонент. Если компонент не находится ни в одном Physics Volume, возвращается Physics Volume по умолчанию для мира.
  • Is Exceeding Max Speed — возвращает значение True, если текущая скорость компонента превышает заданную максимальную скорость. Используется для предотвращения слишком быстрого движения компонента.

Управление движением

Функции управления движением
Функции управления движением
  • Move Updated Component — перемещает Updated Component на вектор Delta и задает новую ориентацию New Rotation. Если Sweep включён, учитывает столкновения, если включён Teleport — телепортирует без столкновений. Возвращает результат столкновения (Hit Result) или None.
  • Set Updated Component — устанавливает новый компонент, который будет перемещаться и обновляться.
  • Stop Movement Immediately — немедленно останавливает движение компонента, обнуляя скорость и, если есть, ускорение.

Совет. Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.


наш Телеграм канал

Оцените статью
( 1 оценка, среднее 5 из 5 )
Поделитесь этой статьей со своими знакомыми в социальных сетях, возможно, эта статья кому-то будет полезна
Unreal Engine - это просто
Добавить комментарий

Нажимая на кнопку "Отправить комментарий", я даю согласие на обработку персональных данных и принимаю политику конфиденциальности.

  1. Lephin

    Создается вот так у меня Character программно. Беру схему и создаю

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    static ConstructorHelpers::FObjectFinderCharacterBP(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter"));

        ACharacter* NewActor_ = GetWorld()->SpawnActor(
            CharacterClass,
            FVector(1690, 1120, 88),
            FRotator(0, 0, 0)
        );
    В самом Character задается через таймер движение

    void ATestProjectCharacter::BeginPlay()
    {
        Super::BeginPlay();
       
        GetWorldTimerManager().SetTimer(
            MoveCheckTimerHandle,
            this,
            &ATestProjectCharacter::UpdateMovementState,
            1.0f,
            true
        );
    }

    void ATestProjectCharacter::UpdateMovementState()
    {

        FVector ForwardDirection = FVector(1.0f, 0.f, 0.f);
        FVector RightDirection = FVector(0.f, 1.0f, 0.f);
        FVector2D MovementVector = FVector2D(-1.0, 0.0f);


        UCharacterMovementComponent* Movement = GetCharacterMovement();
        Movement->Velocity = ForwardDirection + 300;
    }

    То в таком случаи компонент Movement работает исключительно если взять и переместить схему в игровое пространство, при процедурной генерации кодом, movement не работает. Пока не получилось

    Ответить
    1. Будуев Антон автор

      Так по кусочкам кода трудно что-то дельное сказать, но в целом, если движение работает при ручном размещении в мире и не работает при программном спавне, то напрашивается вывод, что проблемы с инициализацией.

      Когда схема размещена в мире, то движок при старте игры стандартным образом перебирает все Акторы в мире и инициализирует их, только потом уже запускает игру. Соответственно, Ваша схема в этом варианте успевает проинициализироваться и работает.

      При программном спавне во время игры, вероятно, что-то не успевает проинициализироваться…

      После спавна персонажа программно, убедитесь, что:

      • Персонаж корректно зарегистрирован в мире.
      • Компоненты (в том числе CharacterMovementComponent) активны и инициализированы.
      • Вызван метод RegisterAllComponents() для активации компонентов, если это необходимо.

      Также в этой строчке, скорее всего, ошибка: Movement->Velocity = ForwardDirection + 300;
      вы складываете вектор и число (ForwardDirection + 300), что некорректно. Вам нужно указать направление движения и скорость (величину) этого движения. Вы уже имеете ForwardDirection (направление), поэтому нужно умножить его на желаемую скорость.

      1
      Movement->Velocity = ForwardDirection * 300.0f; // умножаем вектор направления на скорость
      Ответить
      1. Lephin

        Да, это перегрузка функции. Тем более когда руками размещаешь схему все работает, а процедурная генерация кодом увы нет. Через дебаг смотрел, а там состояния компонента не обновляется. Компонент есть у владельца, который генерируется кодом, и даже задается Velocity, и даже стандартная анимация срабатывает когда меняется состояния Velocity, но вот движение уже Movement не обрабатывает. Да он почему то не зарегистрирован, состояния компонента не обновляется. Если найду детальную причину и решение обязательно напишу

        Ответить
      2. Lephin

        Решение нашлось. Все дело в том, что moment component работает с физикой окружающего мира. И поэтому он должен быть инициализирован в конструкторе GameMode. Если Character создавать после конструктора, то movement не будет работать с физикой окружающей среды. Он будет у Character, но у него не будет таймера обновления. Как привязывать физику к компоненту после конструктора не знаю. Может есть другие ходы, другие решения

        Ответить
        1. Будуев Антон автор

          Здорово, что решение нашлось, благодарю, что написали его.

          Как мы и предполагали с Вами, проблема в инициализации…

          Ответить