Jak sprawić, by moje postacie obracały się płynnie podczas chodzenia po ścieżce (lista współrzędnych)?

15

Mam listę ze współrzędnymi - wyjściem z algorytmu A * - i chciałbym, aby moje postacie płynnie podążały tą ścieżką z obrotami.

Mam więc coś takiego jak A i chcę uzyskać C

wprowadź opis zdjęcia tutaj

W jaki sposób mogę to zrobić ?

EDYTOWAĆ

Aby wyrazić się trochę bardziej jasno:

Bardziej interesuje mnie płynne skręcanie, ponieważ już wiem, jak chodzić z jednego węzła do drugiego.

EDYTOWAĆ

Ponieważ wiele osób uważa to za przydatne (również dla mnie), zamieszczam link do „Natury kodu” Daniela Shiffmana, gdzie omawia wiele problemów AI (i fizyki) w grze, np. Zachowania sterujące http://natureofcode.com/book/chapter- 6-autonomiczny-agent / # rozdział06_section8

Patryk
źródło
Czy w Unity nie jest wbudowane wyszukiwanie ścieżek?
joltmode,
@ Tom No tak, ale i tak mam zaimplementowaną wersję. Celem tego pytania jest uzyskanie płynnych zwrotów (obrotów) podczas chodzenia po ścieżce.
Patryk
3
Pod tym względem fajny termin dla Google to „Zachowanie sterujące” :)
Roy T.
3
@RoyT. Oczywiście ! Czytałem to kilka tygodni temu i już zapomniałem: / To świetny artykuł na temat podążania ścieżką z niesamowitym wyjaśnieniem z matematyki i fizyki natureofcode.com
Patryk
1
Chciałem tylko podziękować @Patrykowi za link - wygląda naprawdę pouczająco i szukałem dobrego źródła na temat zachowania sterującego.
Christian

Odpowiedzi:

7

Jeśli chcesz mieć gładkie ścieżki w środowisku opartym na kafelkach, nie ma możliwości obejścia wygładzania ścieżek na punktach A *. W swojej książce o programowaniu sztucznej inteligencji Matt Buckland opisuje prosty i szybki algorytm wygładzania ścieżki (w zasadzie usuwa wszystkie krawędzie, które można usunąć bez powodowania przecięcia przeszkód).

Po usunięciu takich niepotrzebnych krawędzi pierwsza sprawa ( A -> B ) zostanie rozwiązana. Wygładzanie krawędzi na wykresie można osiągnąć na kilka sposobów. Najprawdopodobniej zadziałałyby sploty Hermite (w zależności od gęstości przeszkody i wielkości płytek). Inną opcją mogą być zachowania kierownicze, w których zaczynasz kierować się w stronę następnego punktu, gdy tylko znajdziesz się w odległości pół płytki od bieżącego celu (to naprawdę zależy od tego, jak szybko twój agent porusza się / skręca).

grzmot
źródło
9

Jak wspomnieli inni, w drugim przypadku konieczne będzie zastosowanie jakiegoś splajnu lub (w rzeczywistości lepsze dopasowanie do twojego przykładu) nadanie jednostce pewnego rodzaju sterowania.

Jednak w pierwszym przypadku istnieje rozwiązanie, które jest zarówno prostsze, jak i daje lepsze wyniki niż wygładzanie ścieżki. Nazywa się Theta * i jest prostym (i stosunkowo nowym) rozszerzeniem A * na siatkach, które umożliwia jednostkom przemieszczanie się w dowolnym kierunku między punktami siatki.

Theta * a wygładzanie ścieżki

Jest ładny artykuł wyjaśniający Theta * (z którego ukradłem powyższy obraz) tutaj

BlueRaja - Danny Pflughoeft
źródło
2

Aby uzyskać bardziej realistyczny ruch, spróbuj zintegrować go z zachowaniem sterowania. (Wersja C # klasycznej wersji OpenSteer http://sharpsteer.codeplex.com/ ) Otrzymujesz dane wyjściowe AStar i pozwalasz zachowaniu kierowania dbać o ruch (Jedna z próbek dokładnie pokazuje, jak to zrobić, nawiguj po ścieżce)

Tpastor
źródło
1

W przypadku nawigacji od punktu do punktu użyłem różnicy kątów (aktualny kierunek gracza względem kierunku od bieżącego punktu do następnego punktu), a następnie stopniowo zmieniałem kąt do końcowego kąta w miarę ruchu. Sprawdź tę grę , w której samoloty przemieszczają się z jednego punktu do drugiego, ale tura nie jest gwałtowna, ale po uważnym obserwowaniu można zidentyfikować punkty na ścieżce. (gra działa tylko na urządzeniach mobilnych, ale najlepiej iPhone / iPad).

Ani
źródło
Właśnie to skończyłem.
Patryk,
1

Miałem szczęście z splajnami Catmull-Rom (rodzaj splajnu sześciennego zalecany również przez @bummzack). Zaletą tych elementów jest to, że splajn zawsze przechodzi przez punkty kontrolne, a wiele innych tego nie robi. Zaimplementuj coś takiego:

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);

* czas jest wartością [0,1] między punktami kontrolnymi 1 i 2.

Jonas Byström
źródło
0

A-> B można rozwiązać za pomocą siatek nawigacyjnych zamiast siatki. Oznacza to dużą zmianę w generowaniu danych w poszukiwaniu ścieżek.

Przypadki takie jak C i D są po prostu cięciem narożnika: jeśli postać porusza się po ścieżce i wewnątrz „rogu” (komórki, w której poprzednie, bieżące, następne komórki nie znajdują się na linii prostej), popchnij ją w kierunku zarówno poprzedniej, jak i następnej komórki . Jedynym problemem jest określenie odległości od rzeczywistej pozycji (odległość pchania). Prawdopodobnie wymagałoby to wprowadzenia odległości od bieżącej komórki. Coś takiego:

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
źródło