Steering behavior. Види зміни напрямку руху персонажа на ходу

При розробці ігор часто виникає необхідність реалізації проходження певного маршруту. Наприклад, персонажеві треба прокласти шлях з точки A в точку B. Припустимо розрахували його з якого-небудь алгоритму пошуку шляху, йдемо. І тут виявляється, що з точки C в точку D йде інший юніт і перетинає нам дорогу і треба б його обійти. Що робити? Постійно перебудовувати шлях — накладно, багато зайвих обчислювальних витрат, коли достатньо злегка змінити напрямок вже під час руху, щоб уникнути зіткнення.
Види зміни напрямку по ходу руху і є steering behaviors.

Дана замітка — є перекладом першої статті із циклу Understanding Steering Behaviors, написаного Fernando Bevilacqua.

У російській мові виявилося складно підібрати адекватний переклад я вирішив використовувати термін «стиринг», який зустрічав на просторах рунета найчастіше. Стиринг допомагає персонажам рухатися в реалістичній манері, з використанням простих сил, поєднання яких дозволяє домогтися дуже натурального переміщення персонажів з оточуючого їх світу. Ідеї, що лежать в основі стиринга, були запропоновані Крейгом Рейнольдсом. У них не використовуються складні стратегії, пов'язані з плануванням шляху або величезні обчислення, замість цього використовується доступна інформація, наприклад, сили, що діють на сусідніх персонажів (юнітів). Це робить їх простими для розуміння і реалізації, при цьому, дозволяючи дуже складні патерни переміщення.
Для розуміння даної статті слід мати загальне уявлення про математику векторів. Для тих хто хоче освіжити знання в пам'яті, рекомендую ознайомитися з наступною статтею (Лінійна алгебра для розробників ігор).

Позиція, Швидкість і Рух

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

Хоча вектор повинен мати напрям, воно буде ігноруватися, коли ми говоримо про вектор стану персонажа (будемо припускати, що радіус-вектор спрямований до поточного розташування персонажа).


На малюнку вище зображено персонаж — його координати (x,y); V(a, b) — вектор швидкості. Рух розраховується за методом Ейлера.

position = position + velocity

Напрям вектора швидкості, буде контролювати куди персонаж спрямовується, в той час як довжина вектора показує як далека переміститься персонаж за одиницю часу. Чим більше довжина вектора, тим швидше буде переміщатися персонаж. Як правило вектор швидкості може бути обмежений певним значенням, як правило використовується максимальна швидкість в моделюваному світі.
Швидкість розраховується наступним чином:

velocity = normalize(target - position) * max_velocity,

де target — мета, до якої ми рухаємося, position — поточний стан персонажа, max_velocity — максимальна швидкість

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

Розрахунок сил

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

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

Поведінка Прагнення використовує дві сили: бажану швидкість (desired velosity) і керуючу силу (steering force):



Бажана швидкість — це сила, яка направляє персонажа до своєї мети найкоротшим можливого шляху. Керуюча сила є результатом віднімання поточної швидкості з бажаної і штовхає персонажа в напрямку мети. Ці сили розраховуються наступним чином (слід пам'ятати, що всі операції здійснюються над векторами):

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

Додавання сил

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



Додавання цих сил і остаточний розрахунок швидкості і місця розташування виглядають наступним чином:

steering = truncate (steering, max_force)
steering = steering / mass

velocity = truncate (velocity + steering , max_speed)
position = position + velocity

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

Втікаємо геть

Поведінка Уникання (flee behavior) використовує ті ж самі сили, що й у Прагненні (Seek Behavior), але вони дозволяють герою переміщатися геть від мети.



Новий вектор бажаної швидкості розраховується шляхом вирахування положення персонажа з положення цілі. У результаті виходить вектор який йде від цілі до персонажа. Керуюча сила розраховується практично аналогічно:

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

Бажана швидкість в цьому випадку являє собою найпростіший маршрут, який персонаж може використовувати, щоб втекти від мети. Керуюча сила дозволяє персонажеві відмовитися від поточного маршруту, штовхаючи його в напрямку бажаного вектора швидкості.
Таким чином між підсумковими векторами в поведінці Прагнення і Уникнення можна встановити наступне відповідність:

flee_desired_velocity = -seek_desired_velocity

Іншими словами вектора протилежні один одному за напрямом.

Після того, як розрахований вектор керуючої сили, він повинен бути доданий до вектора швидкості персонажа. Таким чином ця сила штовхає персонаж від мети, і в кожен момент часу персонаж перестає рухатися до мети і почати рухатися від неї (помаранчева крива на малюнку нижче)


Висновок

Стиринг є хорошим засобом для створення реалістичних моделей руху. Незважаючи на те, що розрахунок простий в реалізації, метод показує дуже хороші результати на практиці.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.