Как заставить моих персонажей становиться плавными при ходьбе по пути (список координат)?

15

У меня есть список с координатами - вывод из алгоритма A * - и я бы хотел, чтобы мои персонажи плавно следовали по этому пути с поворотами.

Итак, у меня есть что-то вроде A, и я хочу получить C

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

Как я могу это сделать ?

РЕДАКТИРОВАТЬ

Чтобы сделать себя немного более понятным:

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

РЕДАКТИРОВАТЬ

Поскольку многие люди находят это полезным (и я тоже), я публикую ссылку на «Природу кода» Дэниела Шиффмана, где он обсуждает множество проблем игрового ИИ (и физики), например, управление поведением http://natureofcode.com/book/chapter- 6-автономные агенты / # chapter06_section8

Patryk
источник
Разве поиск пути не встроен в Unity?
Joltmode
@ Tom Хорошо, да, но я все равно реализовал свою версию. Смысл этого вопроса - совершать плавные повороты (повороты) при ходьбе по дорожке.
Патрик
3
Хороший термин для Google в этом отношении - «Поведение рулевого управления» :)
Рой Т.
3
@RoyT. Конечно ! Я читал это несколько недель назад и уже забыл: / Это отличная статья о пути с потрясающим объяснением по математике + физике natureofcode.com
Patryk
1
Я просто хотел поблагодарить @Patryk за ссылку - выглядит действительно информативно, и я искал хороший ресурс по поведению рулевого управления.
Кристиан

Ответы:

7

Если вы хотите сгладить траектории в среде на основе тайлов, нет никакого способа применить сглаживание траектории к вашим путевым точкам A *. В своей книге о программировании игрового ИИ Мэтт Бакленд описывает простой и быстрый алгоритм сглаживания пути (в основном удаляет все ребра, которые можно удалить, не вызывая пересечения с вашими препятствиями).

Как только вы удалите ненужные ребра, как это, ваш первый случай ( A -> B ) решен. Сглаживание краев на вашем графике может быть выполнено несколькими способами. Скорее всего, сплайны Эрмита будут работать (в зависимости от плотности препятствий и размера плитки). Другим вариантом может быть управление поведением, когда вы начинаете двигаться в направлении следующей путевой точки, как только вы находитесь на расстоянии половины клетки от текущей цели (это действительно зависит от того, насколько быстро ваш «агент» двигается / поворачивается).

bummzack
источник
9

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

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

Тета * против сглаживания пути

Есть хорошая статья, объясняющая Theta * (из которой я украл изображение выше) здесь

BlueRaja - Дэнни Пфлугхофт
источник
2

Для более реалистичного человеческого движения, попробуйте интегрироваться с поведением рулевого управления. (C # версия классического OpenSteer http://sharpsteer.codeplex.com/ ) Вы получаете выходные данные AStar и позволяете поведению рулевого управления заботиться о перемещении (Один из примеров показывает, как это сделать, перемещаться по пути)

Tpastor
источник
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;
snake5
источник