Як робиться локальне уникнення RTS?


15

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

Для таких ігор RTS, як Starcraft 2, як робиться місцеве уникнення? Фізика моделюється чи всебічний контролер вирішує, де все має бути? Я знаю, що це питання може бути трохи широким, тому я конкретно запитую, як досягти локальної поведінки уникнення Starcraft 2; хоча все, що працює, буде дуже вдячним.

Я не шукаю жодного коду - просто корисні ресурси або пояснення того, як Starcraft 2 (або подібні ігри) поводиться з місцевим уникненням.

На даний момент у мене реалізовано виявлення зіткнення (з вектором проникнення), сили зіткнення та рух за швидкістю. Кожен блок перевіряється на інше на предмет зіткнення - якщо вони стикаються, об'єкти негайно зміщуються вектором проникнення, тоді застосовується сила зіткнення. Потім інша петля переміщує об’єкти за їх швидкістю і застосовує перетягування до швидкостей. Зсув пом'якшує проблему надмірних зусиль зіткнення, застосованих на збірних блоках, але підрозділи все ще іноді вистрілюють.

Я шукаю рішення, щоб задовольнити наступні вимоги (як у Starcraft 2):

  • Об'єкти не повинні перетинатися; або хоча б перекриття повинні бути врешті вирішені.
  • Об'єкти не відштовхують один одного більше, ніж потрібно, тому 2 одиниці можуть стояти і рухатися поруч один з одним у формуванні.
  • Не повинно бути ніяких дивних способів поведінки, коли об’єкти стискаються до одного місця призначення.
  • Можуть підтримувати одиниці різних розмірів і навіть різної опуклої форми.

Те, про що я думав дотепер, це замість виявлення зіткнень, виявлення для майбутніх зіткнень, щоб перекриття ніколи не відбувалося. Потім застосуйте обмеження, переконавшись, що швидкості 2 одиниць не змушують їх перетинатися. Я все ще розмовляю з алгоритмом обмеження руху поза перекриттям.


"зграйна поведінка" (термін google) - дуже широка проблема,
грохот фрик

Це було в черзі голосів закритих голосів як "занадто широке" - я схильний погодитися. Спроба звузити: що ви спробували? Яких «небажаних ефектів» ви хочете уникати? Я прав, кажу, що ви хочете, щоб одиниці залишалися у формуванні?
Анко

Ігри RTS часто працюють у кожного клієнта, виконуючи одне і те ж детерміноване моделювання на кожній машині. Таким чином, якщо ви зможете вирішити це для однієї машини, ви можете застосувати те саме рішення до мультиплеєрних ситуацій, незалежно від того, з якою локальною технікою ви уникаєте.
Алан Вулф

Дякуємо за відгук щодо питання. Я трохи звузив питання і пояснив, що конкретно я намагаюся досягти.
JPtheK9

Це чудовий ресурс: red3d.com/cwr/steer
tbkn23

Відповіді:


11

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

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

Тепер, щоб виконати моделювання:

  1. Для кожного агента, припускаючи, що він нерухомий, обчисліть усі швидкості, які призвели до його зіткнення в будь-якій точці майбутнього з будь-яким з інших рухомих агентів. Це можна представити у "просторі швидкостей" у вигляді набору пересічних напівплощин (також відомих як перешкода швидкості ).
  2. Визначте точку в цьому просторі, найближчу до v_pцього, це нова швидкість одиниці.

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

Для обчислення двох етапів алгоритму, описаних вище, ви можете використовувати підсумки Міньковського, щоб визначити, що таке перешкода швидкості, а потім використовувати лінійну модель програмування (наприклад, алгоритм Simplex ), щоб визначити найближчу точку до того, v_pщо дозволяє уникнути перешкоди швидкості. Крім того, код для запобігання зіткненням доступний для вашого ознайомлення і перенесений на C # для використання в ігрових двигунах типу Unity. Ця методика була використана принаймні в Warhammer 40,000: Space Marine та, можливо, в інших іграх .


Це була дивовижна стаття, і я відчуваю, що я прочитав половину її з вашого пояснення. Дякуємо за цю інформацію.
JPtheK9

0

Я не знаю, як працюють ваші підрозділи, але я припускаю, що вони схожі на державну машину:

Можливі стани

  • Пробіг до (x, y, z)
  • Напад (ворог_ід)
  • Збір ресурсу (ressource_id)

Якщо ви звернете увагу на те, як зоряні кораблі підходять до цієї проблеми, ви виявите, що:

  1. Якщо є простір для переміщення в напрямку, характер рухається в цьому напрямку.
  2. Якщо місця немає, одиниця в дорозі буде рухатися, щоб зробити пробіл
  3. Якщо підрозділ, якому потрібно рухатись, щоб зробити пробіл, вже має команду, він збереже команду, але трохи змінить її, щоб врешті-решт зайняти місце.

Ось сценарій 1:

введіть тут опис зображення

У мене є місце, щоб поїхати туди? Так ? Тоді йди

Сценарій 2:

введіть тут опис зображення

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

Отже, що вам потрібно буде реалізувати:

  • Підрозділи повинні знати про своє оточення
  • Підрозділи повинні мати спосіб спілкування один з одним
  • Ви повинні реалізувати спосіб утримати виконання команди під час використання іншого блоку

Дякуємо за інформацію та візуалізацію. Зараз я використовую функцію виявлення зіткнень, щоб з’ясувати, чи може підрозділ переміститися в інше місце, чи інший підрозділ займає його. Головне, що я намагаюся розібратися, це якийсь алгоритм, щоб сказати іншому блоку, яку відстань рухати чи яку швидкість регулювати. Іншими словами, як блокуючий блок розмістить блок, який намагається пройти.
JPtheK9

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

Що ви маєте на увазі під "рухами, поки не вийде з ладу"? Як в першу чергу рухається одиниця?
JPtheK9

Вибачте, я забув згадати: Підрозділ не є державними машинами. У їх шафці є багато здібностей, що імітують кожен кадр - за винятком цих здібностей, вони діють лише при активації, незалежно від відстані до місця призначення X чи за наявності цілі. Рух одиниці - результат її швидкості, яка може бути змінена здатністю.
JPtheK9

0

Один із способів зробити це - одиниці формувань, які формуються автоматично, і їх спроба утриматись у положенні відносно центру формування . Потім замість того, щоб переміщувати кожну одиницю окремо, переміщуйте центр формування навколо.

Ось основний спосіб зробити це за допомогою коробчатої форми та простих пружин, щоб утримувати пристрої у відповідних положеннях:

// Defines a phalanx (box) formation
class Formation
    // Center of the box in the world
    Position center;
    // Width in # of units
    int width;
    // Height in # of units
    int height;
    // Space between units
    float scale;
    // How much force units will apply to stay near
    // their assigned spot.
    float springforce;

    // Return a position of a unit at the given row and column
    // Todo: add a rotation to this formation so it can rotate when moving.
    Position GetUnitPhalanxPosition(int row, int column)
        return new Position(center.X + column * scale - width * scale /2, 
                            center.Y + row * scale    - height* scale / 2);

// Represents a simple point object with a velocity and position;
// it belongs to a formation.
class Unit
    Position pos;
    Velocity vel;
    Formation formation;
    // What's our assigned spot in the formation?
    int row;
    int column;

    void Update(float dt)
        // Get the desired target position in the formation
        Position target = formation.GetUnitPhalanxPosition(row, column);
        // Apply a spring force toward the position (todo: you might want to damp this)
        vel += (target - position) * dt * formation.springforce;
        // Move along the velocity vector.
        pos += vel * dt;

Спасибі! Це дійсно цікаве та креативне рішення. Я реалізував щось подібне до цього для поведінки / формувань натовпу, але у мене все ще є проблема перекриття одиниць. Що має статися, якщо 2 утворення натрапляють один на одного?
JPtheK9

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

Мета-утворення звучать дійсно складно і буйно: C. Зображення, яке ви зв'язали, може бути саме тим, що мені потрібно. Я збираюся зробити ще кілька досліджень щодо рульових сил. Чи є у вас посилання на статтю зображення?
JPtheK9

У мене схожа проблема з вашою, було б цікаво дізнатися, як ви її вирішили. Один кадр ідеї прийшов до тями після написання цієї статті: можливо, комбінуючи Pathfinding (A *) для планування макроколій, використовуючи силу відштовхування для уникнення мікро зіткнення:
ColdSteel

0

Я знаю, що деякі люди нахмурилися на демпінгу посилань, однак я знайшов багатоагентський підхід, орієнтований на поле для стратегічних ботів у реальному часі (ISBN 978-91-7295-160-0), як дуже просвітницький документ, і це, очевидно, передає набагато більше, ніж я міг би розробити далі. У статті досліджено поля штучного потенціалу (концепція, що походить від робототехніки), щоб полегшити локальне уникнення зіткнень у контексті розвитку ігор.


Спасибі! Дослідження для мене так само корисні, як і пояснення. Я занурюся в цей документ.
JPtheK9

У мене вже створена карта впливу, але це здається занадто складним для моїх смаків. Головне - генерувати потенційні поля для різних одиниць для переміщення їх, а також перетворювати дані з потенційного поля у швидкість, на яку потрібно рухатись. В основному, я не думаю, що це буде працювати для одиниць різної величини. Це чудове читання, хоча з великою кількістю цікавих ідей.
JPtheK9
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.