Як змусити моїх персонажів плавно повертатися під час ходьби стежкою (список координат)?


15

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

Тож у мене є щось на кшталт A, і я хочу отримати C

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

Як я можу це зробити?

EDIT

Щоб зробити себе трохи більш зрозумілим:

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

EDIT

Оскільки багато людей вважають це корисним (і я), я розміщую посилання на "Природу коду" Даніеля Шиффмана, де він обговорює багато проблем із ІІ (та фізикою), наприклад, поведінка з рульовим керуванням http://natureofcode.com/book/chapter- 6-автономні агенти / # Chapter06_section8


Чи не вбудований набір маршрутів в Unity?
joltmode

@Tom Ну, але у мене все-таки реалізована моя версія. Сенс цього питання полягає в тому, щоб отримати плавні повороти (обертання) під час прогулянки по стежці.
Патрик

3
Гарний термін для Google в цьому плані - "Рульова поведінка" :)
Рой Т.

3
@RoyT. Звичайно ! Я читав це кілька тижнів тому і вже забув: / Це чудова стаття про шлях, що йде з приголомшливою математикою + поясненням фізики natureofcode.com
Патрик

1
Я просто хотів подякувати @Patryk за посилання - виглядає дійсно інформативно, і я шукав хороший ресурс щодо поведінки керма.
Крістіан

Відповіді:


7

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

Після того, як ви видалите подібні зайві краї, ваш перший випадок ( A -> B ) вирішено. Вирівнювання країв вашого графіка можна виконати кількома способами. Швидше за все, сплави Hermite спрацювали (залежно від щільності вашої перешкоди та розміру плитки). Іншим варіантом може бути керування поведінкою, коли ви починаєте спрямовуватись до наступної точки, як тільки ви перебуваєте на пів плитки від поточної цілі (це дійсно залежить від того, наскільки швидко ваш «агент» рухається / перетворюється).


9

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

Однак у першому випадку є рішення, яке є і простішим, і дає кращі результати, ніж згладжування контуру. Це називається Theta * , і є простим (і відносно новим) розширенням A * на сітках, що дозволяє одиницям рухатися в будь-якому напрямку між точками сітки.

Тета * проти згладжування шляху

Тут є приємна стаття, що пояснює Theta * (з якої я вкрав вищезгадане зображення) тут


2

Для більш реалістичного руху людини спробуйте інтегруватися з рульовими поведінками. (C # версії класичного OpenSteer http://sharpsteer.codeplex.com/ ) Ви отримуєте висновок AStar і нехай рульове догляд поведінки про movimentation (один із зразків показують exactely , як це зробити, перейдіть наступний шляхом)


1

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


Саме це я і закінчила.
Патрик

1

Мені пощастило з сплайнами Catmull-Rom (тип кубічного сплайну, як це також рекомендує @bummzack). Хороша частина цих питань полягає в тому, що сплайн завжди буде проходити через контрольні точки, багато інших - ні. Реалізуйте щось подібне:

t    = <time*>
t12  = t + 1.0
t23  = t
t34  = t - 1.0
t123 = (t + 1.0) / 2.0
t234 = t / 2

c1 = controlpoint[0];
c2 = controlpoint[1];
c3 = controlpoint[2];
c4 = controlpoint[3];

l12 = lerp(c1, c2, t12);
l23 = lerp(c2, c3, t23);
l34 = lerp(c3, c4, t34);
position = lerp(lerp(l12, l23, t123), lerp(l23, l34, t234), t);

* час - це значення [0,1] між контрольними точками 1 і 2.


0

A-> B можна вирішити, використовуючи навігаційні сітки замість сітки. Це означає велику зміну в генеруванні даних за маршрутом.

Такі випадки, як C і D, - це просто кутове вирізання: якщо персонаж рухається шляхом і всередині "кута" (клітинка, де попередні, поточні, наступні комірки не знаходяться по прямій лінії), натисніть на неї в напрямку попередньої і наступної комірки . Єдина проблема - визначити відстань від реального положення (відстань, що висувається). Це, ймовірно, вимагатиме відстані від поточної комірки як вхідного. Щось на зразок цього:

push_dir = average( prevcell.pos, nextcell.pos ) - curcell.pos;
push_dist = cell_half_width - distance( char.pos, curcell.pos );
char.pos += push_dir * push_dist;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.