- PVSM.RU - https://www.pvsm.ru -

Steering behavior. Виды изменения направления движения персонажа на ходу

При разработке игр часто возникает необходимость реализации следования некоторому маршруту. Например, персонажу нужно проложить путь из точки A в точку B. Допустим рассчитали его по какому-нибудь алгоритму поиска пути, идем. И тут оказывается, что из точки C в точку D идет другой юнит и пересекает нам дорогу и надо бы его обойти. Что делать? Постоянно перестраивать путь – накладно, много лишних вычислительных расходов, когда достаточно слегка изменить направление уже во время движения, чтобы избежать столкновения.
Виды изменения направления по ходу движения и есть steering behaviors.

Данная заметка — является переводом первой статьи из цикла Understanding Steering Behaviors [1], написанного Fernando Bevilacqua.

В русском языке оказалось сложно подобрать адекватный перевод я решил использовать термин «стиринг», который встречал на просторах рунета чаще всего. Стиринг помогает персонажам двигаться в реалистичной манере, с использованием простых сил, объединение которых позволяет добиться очень натурального перемещения персонажей по окружающему их миру. Идеи, лежащие в основе стиринга, были предложены Крейгом Рейнольдсом [2]. В них не используются сложные стратегии, связанные с планированием пути или огромные вычисления, вместо этого используется доступная информация, например, силы, действующие на соседних персонажей (юнитов). Это делает их простыми для понимания и реализации, при этом, позволяя очень сложные паттерны перемещения.
Для понимания данной статьи следует иметь общее представление о математике векторов. Для тех кто хочет освежить знания в памяти, рекомендую ознакомиться со следующей статьей (Линейная алгебра для разработчиков игр [3]).

Позиция, Скорость и Движение

Реализовать все силы, участвующие в изменении направления по ходу движения можно при помощи математических векторов. Так как эти силы будут влиять на скорость и положение персонажа, использование векторов — это хороший подход.

Хотя вектор должен иметь направление, оно будет игнорироваться, когда мы говорим про вектор положения персонажа (будем предполагать, что радиус-вектор направлен к текущему местоположению персонажа).

Steering behavior. Виды изменения направления движения персонажа на ходу
На рисунке выше изображён персонаж – его координаты (x,y); V(a, b) – вектор скорости. Движение рассчитывается по методу Эйлера [4].

position = position + velocity

Направление вектора скорости, будет контролировать куда персонаж направляется, в то время как длина вектора показывает как далека переместится персонаж за единицу времени. Чем больше длина вектора, тем быстрее будет перемещаться персонаж. Как правило вектор скорости может быть ограничен каким-либо значением, как правило используется максимальная скорость в моделируемом мире.
Скорость рассчитывается следующим образом:

velocity = normalize(target - position) * max_velocity,

где target – цель к которой мы движемся, position – текущее положение персонажа, max_velocity – максимальная скорость

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

Расчёт сил

Одной из идей стиринга является влияние на движение персонажа, посредством добавления управляющих сил (steering forces). В зависимости от них, персонаж будет двигаться в ту или иную сторону.

Для поведения Стремление (seek bahavior) добавление управляющей силы к персонажу, заставляет его плавно регулировать свою скорость, избегая резких изменений маршрута. Если цель переместится, то персонаж будет постепенно изменять свой вектор скорости, пытаясь достигнуть цели в его новом местоположении.

Поведение Стремление использует две силы: желаемую скорость (desired velosity) и управляющую силу (steering force):

Steering behavior. Виды изменения направления движения персонажа на ходу

Желаемая скорость — это сила, которая направляет персонажа к своей цели по кратчайшему возможному пути. Управляющая сила является результатом вычитания текущей скорости из желаемой и толкает персонаже в направлении цели. Эти силы рассчитываются следующим образом (следует помнить, что все операции производятся над векторами):

desired_velocity = normalize(target - position) * max_velocity
steering = desired_velocity – velocity

Добавление сил

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

Steering behavior. Виды изменения направления движения персонажа на ходу

Добавление этих сил и окончательный расчёт скорости и местоположения выглядят следующим образом:

steering = truncate (steering, max_force)
steering = steering / mass
 
velocity = truncate (velocity + steering , max_speed)
position = position + velocity

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

Убегаем прочь

Поведение Избегание (flee behavior) использует те же самые силы, что и в Стремлении (Seek Behavior), но они позволяют персонажу перемещаться прочь от цели.

Steering behavior. Виды изменения направления движения персонажа на ходу

Новый вектор желаемой скорости рассчитывается путем вычитания положения персонажа из положения цели. В результате получается вектор который идет от цели к персонажу. Управляющая сила рассчитывается практически аналогично:

desired_velocity = normalize(position - target) * max_velocity
steering = desired_velocity – velocity

Желаемая скорость в этом случае представляет собой простейший маршрут, который персонаж может использовать, чтобы убежать от цели. Управляющая сила позволяет персонажу отказаться от текущего маршрута, толкая его в направлении желаемого вектора скорости.
Таким образом между итоговыми векторами в поведении Стремления и Избегания можно установить следующее соответствие:

flee_desired_velocity = -seek_desired_velocity

Другими словами вектора противоположны друг другу по направлению.

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

Steering behavior. Виды изменения направления движения персонажа на ходу

Заключение

Стиринг является хорошим средством для создания реалистичных моделей движения. Несмотря на то, что расчёт прост в реализации, метод показывает очень хорошие результаты на практике.

Автор: LeXeR3

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/70049

Ссылки в тексте:

[1] Understanding Steering Behaviors: http://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732

[2] Крейгом Рейнольдсом: http://www.red3d.com/cwr/

[3] Линейная алгебра для разработчиков игр: http://habrahabr.ru/post/131931/

[4] методу Эйлера: https://ru.wikipedia.org/wiki/Метод_Эйлера

[5] Источник: http://habrahabr.ru/post/237621/