Wie mache ich meine Charaktere weich, während ich auf einem Pfad gehe (Liste der Koordinaten)?


15

Ich habe eine Liste mit Koordinaten - die vom A * -Algorithmus ausgegeben werden - und ich möchte, dass meine Zeichen diesem Pfad reibungslos mit Rotationen folgen.

Also habe ich so etwas wie A und ich möchte C bekommen

Bildbeschreibung hier eingeben

Wie kann ich das machen ?

BEARBEITEN

Um es mir etwas klarer zu machen:

Ich interessiere mich mehr für sanftes Drehen, da ich bereits weiß, wie man von einem Knoten zum anderen geht.

BEARBEITEN

Wie viele Menschen finden , das nützlich (ich auch) Ich bin Entsendung Link zu Daniel Shiffman der „Nature of Code“ , wo er eine Menge Spiel diskutiert AI (und Physik) Probleme zB Lenkverhalten http://natureofcode.com/book/chapter- 6-autonome-agenten / # chapter06_section8


Ist die Pfadfindung nicht in Unity integriert?
Joltmode

@Tom Na ja aber ich habe meine Version trotzdem implementiert. Bei dieser Frage geht es darum, sanfte Kurven (Rotationen) zu erzielen, während Sie auf dem Weg gehen.
Patryk

3
Ein schöner Begriff für Google in dieser Hinsicht ist "Lenkverhalten" :)
Roy T.

3
@RoyT. Na sicher ! Ich habe dies vor ein paar Wochen gelesen und bereits vergessen: / Dies ist ein großartiger Artikel auf dem Weg, der mit einer großartigen Erklärung für
Patryk

1
Ich wollte mich nur bei @Patryk für den Link bedanken - sieht sehr informativ aus, und ich habe nach einer guten Ressource zum Lenkverhalten gesucht.
Christian

Antworten:


7

Wenn Sie Pfade in einer kachelbasierten Umgebung glätten möchten, können Sie auf keinen Fall eine Pfadglättung für Ihre A * -Wegpunkte anwenden . In seinem Buch über das Programmierspiel AI beschreibt Matt Buckland einen einfachen und schnellen Algorithmus zum Glätten eines Pfades (im Grunde genommen entfernen Sie alle Kanten, die entfernt werden können, ohne eine Kreuzung mit Ihren Hindernissen zu verursachen).

Sobald Sie unnötige Kanten wie diese entfernt haben, ist Ihr erster Fall ( A -> B ) gelöst. Das Glätten der Kanten in Ihrem Diagramm kann auf verschiedene Arten erfolgen. Höchstwahrscheinlich würden Hermite-Splines funktionieren (abhängig von Ihrer Hindernisdichte und Fliesengröße). Eine andere Möglichkeit ist das Steuern von Verhaltensweisen, bei denen Sie zum nächsten Wegpunkt steuern, sobald Sie eine halbe Kachel vom aktuellen Ziel entfernt sind (dies hängt wirklich davon ab, wie schnell sich Ihr "Agent" bewegt / dreht).


9

Wie andere bereits erwähnt haben, müssen Sie für den zweiten Fall eine Art Spline implementieren oder (besser für Ihr Beispiel geeignet) dem Gerät eine Art Lenkverhalten verleihen.

Für den ersten Fall gibt es jedoch eine Lösung, die sowohl einfacher ist als auch bessere Ergebnisse liefert als die Pfadglättung. Es heißt Theta * und ist eine einfache (und relativ neue) Erweiterung von A * in Gittern, die es Einheiten ermöglicht, sich in jede Richtung zwischen Gitterpunkten zu bewegen.

Glättung von Theta * gegen Pfad

Es gibt einen schönen Artikel erklärt Theta * (von dem stahl ich das Bild oben) hier


2

Um eine menschlichere, realistischere Bewegung zu erreichen, sollten Sie versuchen, Lenkverhalten zu integrieren. (C # -Version des klassischen OpenSteer http://sharpsteer.codeplex.com/ ) Sie erhalten die Ausgabe von AStar und lassen das Lenkverhalten auf die Bewegung achten.


1

Bei der Navigation von Punkt zu Punkt habe ich die Winkeldifferenz (Richtung des aktuellen Spielers gegenüber der Richtung vom aktuellen Punkt zum nächsten Punkt) verwendet und dann den Winkel schrittweise in den Endwinkel geändert, während die Bewegung erfolgt. Überprüfen Sie dieses Spiel hier, wo sich die Flugzeuge von einem Punkt zu einem anderen bewegen, aber die Wende nicht abrupt ist, sondern wenn Sie genau hinschauen, können Sie die Punkte des Pfades identifizieren. (Das Spiel funktioniert nur auf dem Handy, vorzugsweise iPhone / iPad).


Genau das habe ich letztendlich getan.
Patryk

1

Ich hatte viel Glück mit Catmull-Rom-Splines (eine Art kubischer Spline, wie auch von @bummzack empfohlen). Das Gute daran ist, dass der Spline immer die Kontrollpunkte durchläuft, viele andere nicht. Implementiere so etwas:

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

* time ist ein Wert [0,1] zwischen den Kontrollpunkten 1 und 2.


0

A-> B kann mithilfe von Navigationsnetzen anstelle eines Gitters gelöst werden. Dies impliziert eine große Änderung bei der Generierung von Pfadfindungsdaten.

Fälle wie C und D sind nur Eckschnitte: Wenn sich ein Zeichen auf einem Pfad und in einer "Ecke" (Zelle, in der sich vorherige, aktuelle und nächste Zellen nicht auf einer geraden Linie befinden) bewegt, schieben Sie es in Richtung der vorherigen und nächsten Zelle . Das einzige Problem besteht darin, die Entfernung von der realen Position (die Schubdistanz) zu bestimmen. Das würde wahrscheinlich die Entfernung von der aktuellen Zelle als Eingabe erfordern. Etwas wie das:

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.