JirkaDellOro / FUDGE

Furtwangen University Didactic Game Editor
https://jirkadelloro.github.io/FUDGE
MIT License
33 stars 28 forks source link

Pathfinding #404

Open Plagiatus opened 7 months ago

Plagiatus commented 7 months ago

Pathfinding

So, nachdem ich mich jetzt lange und ausführlich damit beschäftigt habe, sind hier meine Erkenntnisse und Vorschläge:

Pathfinding is hoch individuell und projektspezifisch. Daher müssen generische Lösungen entweder sehr simpel sein, damit auf ihnen aufgebaut werden kann, oder sehr komplex, damit sie möglichst viele Anwendungsfälle abdecken. Auch gibt es viele verschiedene Möglichkeiten das ganze zu implementieren und parametrisieren, manche davon mehr aufwändig und andere weniger.

Daher also meine Vorschläge:

Waypoints

Ein vergleichweise simples System welches die Erstellung von Wegpunkten in der Szene ermöglicht. Diese Wegpunkte können dann miteinander verbunden werden, um so die Navigation von einem beliebigen Punkt zu einem anderen beliebigen Punkt zu ermöglichen. So weit so einfach, hier sind einige Überlegungen dazu, wie diese Funktionalität erweitert werden kann:

"Nav Mesh"

Vorneweg, die Implementierung welche mir vorschwebt ist in der Komplexität sehr reduziert um hoffentlich sowohl mir als auch dem Anwender die Nutzung ultimativ zu erleichtern. Sie ist nicht zu vergleichen mit den Fähigkeiten die z.B. das NavMesh in Unity aufweist. Daher auch der Name in Anführungszeichen, da es sich dabei nicht wirklich um ein ausgereiftes NavMesh handlen würde. Der Hauptgrund, da bin ich ehrlich, für diese "vereinfachte" Variante ist, dass ich mir nicht zutraue, in vertretbarer Zeit ein dynamisches NavMesh, welches am besten noch live und dynamisch sich an die Gegebenheiten anpasst und generierten Polygonen sich aufbaut, überhaupt geschweige denn besonders performant umzusetzen.

Ich stelle mir das wie folgt vor:

So ist innerhalb einer Zone die Bewegung trivial (einfach linear von Punkt zu Punkt) und zwischen Zonen kann letztendlich ein kaum modifizierter A* Algorithmus angewandt werden. Auch diese Methode kann entweder den berechneten Pfad ausspucken oder ggf. die Bewegung direkt selbst übernehmen.

Mögliche Erweiterungen:

Was es NICHT beinhaltet:

Auf diese Weise kann man immernoch mit etwas manuellem Aufwand relativ komplexe Bewegungsmöglichkeiten erstellen, ohne dass das Mesh alles selbst automatisiert abdecken muss.

Feedback und Diskussion

Ich poste das ganze hier nicht nur, um meine Gedanken zu sortieren, sondern vorallem um Feedback zu erhalten und andere Sichtweisen und Ideen zu hören. Habe ich etwas wichtiges vergessen? Sollte ich doch lieber ein "richtiges" NavMesh implementieren weil das eigentlich so schwierig nicht sein sollte? Mache ich mir zu viel Aufwand für etwas das am Ende vielleicht sowieso niemand nutzt und sollte daher lieber nur eines von beiden Implementieren? usw.

Also, lasst mich gerne an euren Gedanken teilhaben und lasst uns diskutieren wie wir das am besten Umsetzen können.

plojo commented 7 months ago

Muss das NavMesh zwingend rechteckig sein? Und du sagst, es muss flach sein, wie ist das gemeint? Es sollte doch schon möglich sein, dass in einer 3D-Szene z.B. auch Treppen hinauf navigiert werden kann. Ich fände es besser, wenn wir nur eine Lösung implementieren. Für mich hört sich ein NavMesh sinnvoller an, da es die Funktionalität von denn Waypoints doch eigentlich beinhaltet, oder?

Plagiatus commented 7 months ago

Mit "flach" meine ich, dass ein Mesh nur zweidimensional sein darf, also keine gewölbten Flächen abdecken würde. Das würde natürlich bedeuten, dass irgendwie ein schönes, nicht flaches Terrain nicht funktionieren würde.

Und ja, das Nav-Mesh soll zwingend rechteckig sein, da die innere Aufteilung nach meinem Vorschlag auch in rechtecken (oder sogar quadraten) passieren würde. Allerdings kann man ja mehrere Nav-Meshes anlegen, solange diese eine gemeinsame Kante mit einem anderen NavMesh haben würden die als verbunden erkannt werden. So kannst du z.B. auch eine Rampe (Treppe ist etwas schwieriger, aber Treppen sind sowieso immer überraschend schwierig) anlegen welche zwei NavMeshes auf unterschiedlichen Ebenen miteinander verbindet, solange jeweils eine Kante mit der anderen verbunden ist.

In meinen Augen deckt das NavMesh nicht zwingend die Waypoints ab. Mit Waypoints kann man spezielle Punkte definieren und genau festlegen, wie man zu ihnen hin kommt, während man bei einem NavMesh einen (oder mehrere) Bereiche festlegt, auf denen man sich dynamich bewegen kann. Das NavMesh gibt also mehr Freiheiten was die Bewegung angeht, welche ggf nicht gewünscht sind.

JirkaDellOro commented 7 months ago

Das Waypoint-System ist besonders sinnvoll für z.B. Adventure-Games, insbesondere 2D-Adventures mit einer 3D-Anmutung. Durch Zusatzinfo an den Wegpunkten können Figuren und ihre Bewegung auch entsprechend skaliert werden.

JirkaDellOro commented 7 months ago

Ein solches System, dass auch im Editor erscheint, hatte ich mal rudimentär für Alida implementiert, siehe https://github.com/KohlerAl/Thesis bzw. https://kohleral.github.io/Thesis/

plojo commented 7 months ago

Aber man kann doch trotzdem mit einem NavMesh die Waypoints nachahmen, indem man sein NavMesh halt einfach aus engen Pfaden aufbaut (eher wie ein Spinnennetz) anstelle von großen Flächen. Wenn man nur Rechtecke verwenden kann, ist das natürlich nicht so praktisch. Ist es denn viel schwieriger, ein auf Dreiecken basierendes NavMesh zu implementieren?

Plagiatus commented 7 months ago

Ein NavMesh für etwas zu verwenden das auch mit einem Waypoint system gut zu lösen wäre ist ein bisschen so wie mit Kanonen auf Tauben zu schießen - geht schon, ist aber overkill. Ein NavMesh ist ein deutlich komplexeres System, sowohl für den Nutzer beim setup als auch für die Engine zum berechnen. Daher würde ich beides bereitstellen.

Einen beliebigen Polygon Bereich in Dreiecke zu zerschneiden ist weniger das Problem, und auch die Navigation durch diese Dreiecke sollte keine Probleme machen sondern exakt so funktionieren wie bei den Rechtecken. Ich bin mir nur vorallem nicht sicher, wie ich in solch einem Fall eine möglichst gute Hinderniserkennung machen können soll, so dass die Dreiecke möglichst gut um die Hindernisse herum gelegt werden. Mein Google-Fu scheint auch nicht stark genug zu sein, da ich dazu bisher auch noch keine Hilfestellungen im Netz finden konnte.

Außerdem muss man sich dann auch überlegen, wie man diese Bereiche definiert, wenn nicht über eine simple Rechteckige Auswahl.

Randnotiz: Wenn man das ganze über Dreiecke aufbaut, dann könnte man sich überlegen, letztendlich jedes existierende Mesh als Grundlage für die Navigation nutzen zu können. Allerdings kommen dann wieder weitere Überlegungen ins Spiel wie "Kletterfähigkeiten" (wie steil kann ein Agent den Berg hoch laufen?) oder "wo ist eigentlich oben und ist das überhaupt wichtig?" welche es immer schwieriger machen ein allgemeines NavMesh zu entwickeln ohne es übermäßig zu verkomplizieren.

Plagiatus commented 7 months ago

Um das ganze in Dreiecke aufzubauen könnte man das oben genannte Verfahren anwenden: Aufteilung der Fläche in ein kleinrasteriges Gitter / Zonen, check jeder Zone auf Begehbarkeit, auf Basis dieser Flächen die gesamte begehbare Fläche aufbauen und dann in Dreiecke aufteilen.

Plagiatus commented 7 months ago

Aber jetzt, da ich auch bei der Gizmoimplementierung die ich für die NavMesh Implementierung haben wollte, auf Hürden stoße, setze ich mich zunächst an die hoffentlich leichtere Umsetzung der Wegpunkte.

Gibt es noch Vorschläge und Feedback zu der konkreten Implementation dieser? Besonders auch zu den Vorschlägen Zwecks Gruppierungsmöglichkeiten, Splines und autonomer Bewegung.

JirkaDellOro commented 7 months ago

Wegen dem Handling im Editor kannst Du dich vielleicht schon am Beispiel oben etwas orientieren. Hast Du mal reingeschaut? Ich habe dafür damals einiges bezüglich Listendarstellung angepasst.