Schwingende Physik für Spielerbewegungen (wie in Spider-Man 2 und Energy Hook zu sehen)

Hallo! Ich bin Jamie Fristrom von Happion Laboratories. Sie erinnern sich vielleicht an Spiele wie Die By The Sword, Spider-Man 2 und Schizoid…, die alle in der einen oder anderen Form Seil beinhalteten. Ich habe kürzlich an einem Spiel namens Energy Hook gearbeitet, das kürzlich bei Kickstarter lanciert wurde und bei dem es um Seil geht. (Nun, es geht sowieso nur um Ihren Graviton-angetriebenen Greifbalken.)


Ich werde besprechen, wie ich gerne eine seilschwingende Gameplay-Mechanik implementieren möchte. Als ich anfing, an Energy Hook zu arbeiten, habe ich meistens alles mit meinem eigenen Code gemacht. Ich glaube, es ist möglich, einfach in Unity einzusteigen und mit dem konfigurierbaren Gelenk etwas sehr ähnliches zu tun, aber zu der Zeit war es noch nicht verfügbar. Ich bin mir ziemlich sicher, dass dies ohnehin der richtige Anruf war, weil ich damit die Kontrolle über alles habe - und ich kann es mit Ihnen teilen.


Die Grundlagen des Swingens wie ich es tat - mit Einschränkungen - sind eigentlich ganz einfach. (Ich hoffe, Sie werden nicht enttäuscht, wenn Sie sehen, was sich unter der Haube befindet.) Es funktioniert auf die gleiche Weise, ob Sie ein 2D-Spiel oder ein 3D-Spiel erstellen. Es ist nur so, dass die Vektoren unterschiedlich sind, also beginne ich mit 2D und dann besprechen Sie einige Falten, wenn Sie zu drei Dimensionen gehen.

In diesem Artikel wird auch davon ausgegangen, dass Sie eine Spiel-Engine wie Unity verwenden, die einen Großteil der Arbeit für Sie erledigen kann, z. B. Raycasting gegen Geometrie und das Ausrichten eines Charakters mit einfachen Funktionsaufrufen. Wenn Sie Ihre eigene Engine verwenden, müssen Sie dies möglicherweise selbst berechnen.



Physikalische Simulationen vs. Bewegungsspiel

Es gibt zwei Möglichkeiten, wie Spielsimulationen häufig funktionieren. Die meisten Spiele der dritten Person haben alles eingemacht; Animierte Animationen und Bewegungen aus der Dose, damit alles perfekt aussieht, die Füße der Figur gleiten nicht direkt vom Animationsprogramm des Animators zu uns. Die Alternative ist eine viel physischere Simulation - Sie simulieren Physik: Beschleunigung, Geschwindigkeit, Schwerkraft - viele Ego-Spiele tun dies, aber Spiele von Dritten verpassen dies, da es viel einfacher ist, die Füße der Figur zu haben Folie und das physische Material passen nicht zur Animation.

Wenn Sie eine Seilschaukel ohne Dosen machen möchten (im Gegensatz zu einer Seilschaukel mit Dosen, wie in der ersten Pitfall-Szene oder bei den frühen Spider-Man-Spielen wie Neversofts auf der PSX), handelt es sich um eine Seilschaukel, die eigentlich körperlich ist Simulation und kann daher vielleicht Freiheit und Nuance haben und das viszerale Gefühl, das die echte Schwerkraft und der Schwung geben können, dann wollen Sie es auf die zweite Art tun - haben Sie alles eine physische Simulation und vermeiden Sie die Verwendung von Dosen, die töten der Schwung des Charakters. Dann wird alles fließen.

So mache ich Dinge mit Energy Hook.


Es gibt eine Menge Artikel über das Simulieren von Physik - hier ist einer mit einer coolen Flash-Demo. Sie können Euler-Integration oder Verlet-Integration machen, es spielt keine Rolle. (Ich werde Sie nicht über Euler vs. Verlet hier unterrichten, aber lassen Sie mich nur sagen, dass die Konzepte nicht so unheimlich sind, wie sie klingen.)

Nehmen wir an, wir machen die einfache Euler-Integration. Der Spielzeitschritt unseres Charakters könnte so aussehen, wobei die Beschleunigung durch die Schwerkraft bestimmt wird und wie Sie auf den Stock drücken:

 avatar.velocity = avatar.velocity + avatar.acceleration * deltaT; avatar.position = avatar.position + avatar.velocity * deltaT;

(Randbemerkung: Dies ist eigentlich eine grobe Annäherung - Sie können eine bessere, weniger Frameraten-abhängige Annäherung erhalten avatar.position = avatar.position + (avatar.oldvelocity + avatar.velocity) * deltaT / 2.0f, und Sie können mit so etwas eine nahezu perfekte Simulation erhalten - aber Ihre Spieler werden es wahrscheinlich nicht bemerken.)

zusammenhängende Posts
  • Simulieren Sie zerreißbare Tücher und Ragdolls mit einfacher Verlet-Integration
  • So erstellen Sie eine benutzerdefinierte 2D-Physik-Engine

Beschränke es

Ihr Spiel hat wahrscheinlich ein System, um mit der Weltgeometrie zu kollidieren. Es sieht wahrscheinlich so aus:

 Vektor testPosition = avatar.position + avatar.velocity * deltaT; Vektorkreuzung if (RayCast (position, testPosition, out intersection)) // Wir sind durch eine Wand gegangen, lass uns den Charakter zurückziehen, // mit der Normalen der Wand // mit einem einzeiligen Raum für Atmungsraum testPosition = Kreuzung + Kreuzung.normal; 

Was passiert mit der Geschwindigkeit Ihres Avatars, wenn er auf ein Hindernis trifft? Es ist für Ihren Avatar nicht sinnvoll, die gleiche Geschwindigkeit durch die Wand zu halten. Bei einigen Spielen schlagen Sie möglicherweise auf die normale Stelle, an der Sie sich kreuzten, um Ihre Geschwindigkeit wiederzugeben. Bei anderen Spielen können Sie an der Wand entlang gleiten. andere werden irgendwo dazwischen sein. Schauen wir uns den Code zum Rutschen an einer Wand an:

 avatar.velocity = (testPosition - avatar.position) / deltaT; avatar.position = testPosition;

(Wenn Sie eine Verlet-Integration durchführen, bei der jeder Frame bereits die Geschwindigkeit bestimmt, indem Sie einfach die vorherigen Positionsdaten betrachten, ist dieser Schritt bereits für Sie erledigt.)

Auch wenn Videospiele die hackigen Dinge sind, die sie sind, werden Sie wahrscheinlich oft feststellen, dass die Position Ihres Charakters in bestimmten Fällen plötzlich von einem Frame zum nächsten rastet. Wenn dies geschieht, wird ihre Geschwindigkeit durch das Dach gehen. Meine Lösung dafür ist einfach ein Hack: Überprüfen Sie, ob ihre Geschwindigkeit zu extrem wird, und korrigieren Sie sie, wenn dies der Fall ist.

Was macht dieser Code, wenn Sie schräg gegen eine Wand stoßen? Das erste Bild ändert die Geschwindigkeit dramatisch, wenn Sie gegen die Wand schlagen, aber es drückt Sie immer noch durch die Wand. Beim nächsten Bild wird Ihr Avatar wieder in die Wand gebracht und dann wieder herausgeschoben, aber jetzt ist die Geschwindigkeit die neue Position des Avatars, die entlang der Wand ohne die alte Position gegen die Wand geschoben wird, also parallel zur Wand.

Dies ist eine enorme Vereinfachung dessen, was in der realen Welt vor sich geht, wenn ein Objekt mit einem anderen kollidiert, aber die meisten Ihrer Spieler werden es nicht bemerken oder interessieren.

An diesem Punkt haben wir jedoch die Position und Geschwindigkeit unseres Avatars mit den Wänden und Böden unseres Spiels erfolgreich eingeschränkt. Jetzt sind wir soweit.

Beschränkung mit Haltegurten anstelle von Wänden

Stellen Sie sich nun vor, dass Ihr Avatar bereits an einem virtuellen Punkt mit einem virtuellen Seil befestigt ist. Was uns betrifft, können wir einfach eine unsichtbare runde oder sphärische Wand betrachten. Wir können die Kollision testen, indem wir sehen, ob Sie sich zu weit vom Zentrum des Kreises entfernt haben, und den Avatar wieder hineinziehen.

 if (amITethered) if (testPosition - tetherPoint) .Length ()> tetherLength) // wir sind am Ende unseres Seils // ziehen den Avatar zurück. testPosition = (testPosition - tetherPoint) .Normalized () * Haltelänge; 

Nun, die gleiche Geschwindigkeitsanpassung, durch die wir an Wänden entlanggleiten, gleitet auch innerhalb dieses virtuellen Kreises oder dieser Kugel.


Schwingende Physik: Mit einem Haltegurt fallen - Bild 1
Schwingende Physik: Fallen mit einem Haltegurt - Bild 2
Schwingende Physik: Mit einem Haltegurt fallen - Bild 3

Etwas Subtilität und Nuance

An diesem Punkt haben Sie ein schwingendes Spiel. Aber es wird wahrscheinlich ein paar Dinge geben, die den Spielern Spaß bereiten, und hier kann ein bisschen Hacking die Dinge verbessern.

Locker, nachgiebig

Abhängig von Ihrem Spiel, und ob es sich um eine Seillänge oder eine elastische Bahn oder einen Greifbalken handelt, haben Sie möglicherweise unterschiedliche Ansätze für Lockerheit und Elastizität. Sie können eine Menge simulieren, indem Sie die Haltelänge. Wenn Sie Ihrem federnden Netz- oder Greifbalken Spiel entziehen möchten, können Sie das kürzen Haltelänge wenn sich der Spieler dem Haltepunkt nähert:

 tetherLength = (avatar.position - tetherPoint) .Length ();

Aber wenn es sich um ein nicht elastisches Seil handelt, würden Sie das Seil verlassen Haltelänge unberührt.

Für die Sprungkraft können Sie eine haben Gewünschte Länge das ist fix und a currentLength das ständig versucht, sich dem zu nähern Gewünschte Länge - Dies wird auch für unseren nächsten Schritt nützlich sein:

Aber ich will nicht auf den Boden schlagen!

Was ist, wenn Ihr Avatar an einem niedrigen Ort anfängt und versucht zu schwingen? Es ist ziemlich offensichtlich, dass sie nicht weit kommen werden. Eine schnelle Lösung für dieses Problem ist, zu überprüfen, wie hoch der Punkt ist, von dem aus er schwingen möchte, und die Länge der Leine zu verkürzen, damit der Boden frei wird.

Sie können es jedoch nicht einfach um ein Bild verkürzen, da sie plötzlich in die Luft schnappen Gewünschte Länge das ist kurz genug, um den Boden nicht zu berühren und a currentLength das nähert sich schnell Gewünschte Länge wird Ihnen die Freigabe geben, die Sie wollen.

Der Avatar ist auf

Wenn Ihr Avatar eine menschliche Figur ist, ist es wenig sinnvoll, wenn er ständig perfekt vertikal erscheint, wenn er schwingt. Wenn Sie sie so ausrichten, dass sie so aussehen, als hingen sie am Seil hängen - wenn sie beispielsweise eine Schleife ausführen, könnten sie auf dem Kopf stehen - könnte in Unity so aussehen:

 Vector myUp = (avatar.position - tetherPoint); avatar.rotation = Quaternion.LookRotation (avatar.rotation.forward, myUp);

Dadurch wird der Avatar rückwärts geschwenkt. Sie können auch die Geschwindigkeit des Avatars für den Vorwärtslauf verwenden (das ist es, was ich mache) - oder ihn verrückt drehen lassen ...

Um die Dinge wickeln

In der realen Welt wickeln sich Seile um Dinge. Ein schneller Weg, um zu simulieren, dass in Ihrem Code ein Raycast jedes virtuellen Rahmens entlang des virtuellen Seils ausgeführt wird, und wenn er auf etwas trifft, legen Sie einen neuen Verbindungspunkt an dem Schnittpunkt fest. Das sieht nicht richtig aus, wenn der Avatar dann an einem nicht klebenden Seil zurückschwingt, eignet sich jedoch gut für einen klebrigen Steg, eine Zunge oder einen Greifer.

Wenn Sie die Art und Weise anpassen, wie Ihre Seilumwicklungen wirken, kann dies einen großen Einfluss auf den Spaß haben. Das plötzliche Umwickeln eines Aufschlusses kann den Spieler überraschen und frustriert machen. Wir hatten eine dreistufige Lösung in Spider-Man 2: Wenn Sie sich dem Aufschlussziel zu nahe kamen, brach das Netz zusammen; Wenn Sie sich in einer mittleren Entfernung befinden, würde sich das Netz wickeln. und wenn Sie weit weg wären, würde das Web einfach durchgehen.


Überlegungen zu 3D

Das Schwierigste an der Umsetzung dieser 2D-Mechanik in 3D ist die Betrachtung der Schnittstelle für den Spieler - wie er Punkte in der Welt auswählt, von denen er schwingt. Verschiedene Spiele verwenden unterschiedliche Methoden, um einen solchen Punkt auszuwählen. In Ratchet & Clank gibt es feste Punkte in der Welt, die du festhalten kannst. mit dem Quake Grappling-Hook-Mod und Bionic Commando: Mit der Neueinstellung richten Sie die Kamera auf das, was Sie anbringen möchten. Spider-Man 2 und Energy Hook werfen Strahlen in Bezug auf den Charakter aus, und wo die Strahlen die physische Geometrie schneiden, ist dies der Punkt, an dem Sie die Verbindung herstellen.


Bei fast allen Methoden handelt es sich um Raycasts gegen die physische Geometrie der Welt, sei es entlang der Kameralinie oder von der Figur bis zum Mausklick. Die Schnittmenge des Raycasts bestimmt Ihren neuen Verbindungspunkt.

Hier ein Beispiel für einen Raycast mit Maus-Look, der für ein Ego-Spiel geeignet sein könnte:

 RaycastHit wallData; if (Physics.Raycast (camera.position, camera.forward, out wallData, maximumTetherLength)) amITethered = true; tetherPoint = wallData.point; tetherLength = Vector3.Distance (wallData.point, avatar.position); 

In Sachen stoßen

Das Anstoßen mit Wänden und dergleichen kommt in einem 3D-Spiel auch häufiger vor als in einem 2D-Spiel, insbesondere wenn es sich um die Wände handelt, an die Sie sich binden. Es gibt eine Vielzahl von Möglichkeiten, um dies weniger lästig zu machen.

  • Lassen Sie den Spieler in die Luft steuern: Die Physik hat dazu nicht viel zu sagen, fühlt sich aber irgendwie richtig an. Das ist eines der Dinge, die wir in Spider-Man 2 gemacht haben und warum Sie in Energy Hook ein Jetpack erhalten.
  • Spielen Sie eine coole Animation: Lassen Sie den Avatar eine Art Flip oder Spin machen, wenn er gegen eine Wand stößt, und dann fühlt er sich weniger wie ein Fehler und eher als "Ich wollte das!"
  • Halten Sie sie von der Wand: Ultimate Spider-Man hat dies getan - wenn Sie zu nahe an eine Wand geraten, würden Sie Sie sanft von der Wand wegschieben. Es sah ein bisschen komisch aus, wenn Sie den Stick loslassen und einfach Ihren Avatar dort hängen lassen - sie würden in einem fremden Winkel von der Wand wegschweben -, aber für den Rest des Spiels war dies eine Verbesserung. (Sie könnten möglicherweise das Beste aus beiden Welten haben, indem Sie nur wegdrücken, wenn der Charakter eine bestimmte Geschwindigkeit erreicht?)
  • Belohnen Sie sie dafür, dass Sie gar nicht erst gegen die Wand geschlagen haben: Dies ist die Energy-Hook-Strategie. Lehren Sie den Spieler, keine Wände zu treffen, indem er sie für saubere Schwünge belohnt. Zum einen ermutigt es sie, sich hübsch zu schwingen; Auf der anderen Seite ist es umso frustrierender, wenn sie gegen die Wand schlagen, weil sie ihre Stilpunkte verlieren.


Also, worauf wartest Du?

Machen Sie weiter und machen Sie Ihre eigenen Swing-Spiele, und lassen Sie mich wissen, was Sie sich vorstellen! Ich kann nie genug von schwingenden Spielen bekommen.

Ich hoffe, Sie fanden diesen Artikel hilfreich. Wenn ja, unterstützen Sie bitte den Energy Hook Kickstarter oder stimmen Sie mit Steam Greenlight ab. Vielen Dank!