Physik in einem Unity-Projekt am Beispiel des Mobile Fighting


Die Physik ist zu einem festen Bestandteil jedes modernen Spiels geworden. Egal, ob es sich um eine einfache Gewebesimulation oder eine vollwertige Verkehrsphysik handelt. Handyspiele sind keine Ausnahme. Wenn Sie jedoch die Physik für sie einrichten, müssen Sie auf die Einschränkungen zurückblicken, die mit der relativ schlechten Leistung der unterstützten Geräte der älteren Generation verbunden sind. Der führende technische 3D-Künstler Banzai.Games Roman Tersky berichtete, wie sein Team die Physik in das Gameplay des mobilen Kampfspiels Shadow Fight 3 integriert hat, welche Techniken für die Optimierung verwendet wurden und wie er die Physik für Charaktere von Grund auf neu schrieb, um ihren vollständigen Determinismus in synchronem PVP zu erreichen.

Festkörperphysik




Die Ausrüstung der Charaktere in Shadow Fight 3 besteht aus vielen Elementen, die einer physikalischen Simulation unterliegen, die dem Geschehen auf dem Bildschirm Dynamik verleiht. Eine der Hauptschwierigkeiten, auf die wir bei der Einrichtung der Physik für diese Elemente gestoßen sind, ist die Tatsache, dass sich die Knochen, an die sie gebunden sind, innerhalb der Hierarchie des Skeletts der Figur selbst befinden. Beim Bewegen wiederholen sie die Transformation der Elternknochen und erhalten keinen physikalisch realistischen Impuls.

Knochendetektor


Die einfachste Lösung war eine Knochenablösung. Nachdem alle Ausstattungselemente mithilfe eines Skripts initialisiert wurden, entfernen wir die Knochen der physisch aktiven Elemente aus der Hierarchie des Charakterskeletts und stellen mit der Zeichenverbindungskomponente eine Verbindung mit dem übergeordneten Knochen her.



Wir hatten jedoch einen kleinen Fehler, der sich aus dem fps-Drawdown ergab: In diesem Fall „holt“ ein Knochen, der einer physikalischen Simulation unterzogen wurde, mit einer leichten Verzögerung den Knochen ein, mit dem das Gelenk verbunden ist. Dieser Fehler ist in der Regel so gering, dass er vernachlässigt werden kann. In anderen Fällen wurde eine alternative Lösung angewendet.

Gefälschter Impuls


Betrachten Sie diese Lösung am Beispiel eines Marodeur-Helms, dessen spartanisches Wappen einer physikalischen Simulation unterzogen wird. Wir teilten den Kamm in 5 Teile, von denen jeder auf verschiedene Knochen gehäutet wurde. In den Gelenkeinstellungen dieser Knochen legen Sie die Grenzen für die Drehung entlang der gewünschten Achse fest und legen den Parameter Twist Limit Spring fest , der für den Federeffekt verantwortlich ist.



Für eine physikalisch realistische Simulation wurden die Kammknochen aus der Zeichenhierarchie herausgenommen. Im Falle eines fps-Drawdowns, zum Beispiel auf einem schwachen Gerät, wurde das Netz hässlich gedehnt, weil Knochen „aufgeholt“ wurden.



Aus diesem Grund haben wir beschlossen, die Kammknochen in der Charakterhierarchie zu belassen und ihre Dynamik zu erhöhen, um ihnen einen falschen Impuls zu geben. Dazu mussten wir in jeder Animation (mit Ausnahme der Kampfhaltung) den Zeitpunkt bestimmen, an dem der Impuls angewendet werden soll, sowie die Richtung.

Man könnte die Anzahl der Bilder in der aktuellen Animation lesen, dann 15-20 Bilder von diesem Wert abziehen und einen Impuls nach der empfangenen Differenz anwenden. Wir haben es jedoch geschafft, unnötige Arithmetik zu vermeiden, indem wir den Moment des Impulses mit dem Ende des ununterbrochenen Animationsintervalls verknüpft haben.

Jede Animation (wieder mit Ausnahme der Kampfhaltung) hat einen vorkonfigurierten Zeitraum, in dem der Spieler sie nicht unterbrechen kann. Nach dieser Zeit oder zum Zeitpunkt des Eintreffens des Aufpralls beendet das ununterbrochene Intervall seine Wirkung und in diesem Moment wird unser Impuls ausgelöst. Es mussten lediglich Ausnahmen für mehrere Animationen konfiguriert werden.



Daher wird der Impuls vor dem Ende jeder Animation mehrere Frames lang ausgelöst, je nach Bedarf. Zum Zeitpunkt der Pulsinitialisierung lesen wir die Koordinaten, in denen sich der Knochen im vorherigen und aktuellen Frame befand, und empfangen seinen Bewegungsvektor. Auf diese Achse wird unser Impuls angewendet.

Ausrüstungsgegenstände


Zur Optimierung versuchen wir, Collider so wenig wie möglich zu verwenden, wenn wir die Physik für verschiedene Elemente der Ausrüstung von Charakteren simulieren. In den meisten Fällen erreichen wir dies, indem wir in den Gelenkeinstellungen der Bones, für die die Simulation durchgeführt wird, nur die Einschränkungen entlang der Achsen bearbeiten.



In einigen Fällen (zum Beispiel bei Metallplatten) ist die Verwendung von Kollidern unvermeidlich. Die Hauptlast ist jedoch nicht das Vorhandensein von Kollisionen, sondern die Berechnung ihrer Kollisionen. Die Feinabstimmung der Ebenenkollisionsmatrix in den Projekteinstellungen trägt zur Minimierung dieser Belastung bei. Für solche Elemente verwenden wir zwei separate Ebenen, die nur untereinander kollidieren, wodurch die Fehleinschätzung von Kollisionen mit Kollidern anderer Ebenen (Waffen, Böden, Wände usw.) vermieden wird.



Physischer Klon


Shadow Fight 3 verfügt über verschiedene Arten von Waffen, für die außerhalb von Angriffsanimationen eine physikalische Simulation verwendet wird. Im Moment ist dies ein Messer an einer Kette, Kusarigama, Nunchaku und Dreschflegel. Aus den oben beschriebenen Gründen haben wir beschlossen, die Knochen der Waffe aus der Charakterhierarchie außerhalb der angreifenden Animationen zu entfernen und sie zurückzusenden, wenn keine physische Simulation erforderlich ist. Durch Manipulieren des Parameters Is Kinematic in der Rigidbody- Komponente der Knochen schalten wir je nach Situation die Physik für sie ein und aus.

Bei Verwendung von Kusarigama und einem Messer an der Kette stießen wir jedoch auf eine erhöhte Last bei schwachen Geräten und bekamen einen fps-Verlust. Das Problem trat genau dann auf, wenn die Knochen in die Hierarchie des Charakters zurückkehrten und die physikalische Simulation für ihn ausgeschaltet wurde. Dies liegt an der Tatsache, dass das Ändern der übergeordneten Knochentransformationen in der Skeletthierarchie die Physik-Engine für jeden Tochterknochen belastet, für den eine Rigidbody- Komponente vorhanden ist, selbst wenn der Parameter Is Kinematic aktiv ist. Und je länger die Hierarchie ist, desto größer ist die Last.



Die Lösung bestand darin, einen physischen Klon zu erstellen. Betrachten Sie dies am Beispiel eines Messers an einer Kette.

Während des Ladens des Kampfes werden 2 Skelette für ihn initialisiert: das Haupt-Skelett, das sich in der Hierarchie des Charakters befindet, und sein physischer Klon. Es gibt keine Rigidbody- Komponente in den Bones des Hauptskeletts, nur Animationsspuren wirken sich auf deren Transformation aus. Die Knochen des zweiten haben abgestimmte Verbindungen (Gelenke) und eine Rigidbody- Komponente mit dem aktiven Parameter Is Kinematic.

Während die Transformation der Knochen des Hauptskeletts durch die Animationsspur beeinflusst wird, z. B. während eines Treffers, bleibt der Parameter Is Kinematic in der Rigidbody- Komponente der Knochen des physischen Klons aktiv. Knochen werden nicht transformiert und unterliegen keiner physikalischen Simulation. Während des letzten Frames der Animation werden die Knochentransformationen der beiden Skelette synchronisiert. Ein physischer Klon liest die Position und Rotation der Knochen des Hauptskeletts und legt genau dieselben Parameter fest. Is Kinematic wird dann deaktiviert und die Knochen des physischen Klons werden simuliert. Bis zum Beginn der nächsten angreifenden Animation, die bereits das Hauptskelett ist, liest jeder Frame die Transformationen der Knochen des physischen Klons, die sich in diesem Moment in der Physik bewegen, und setzt diese Parameter auf ihre Knochen. Dieser Ansatz hat die Belastung der Physik-Engine erheblich verringert und die Leistung schwacher Geräte verbessert.



Gewebesimulation


Beim Einrichten der Gewebesimulation als Teil der Leistung mobiler Geräte besteht die Haupteinschränkung in der Verwendung von Gewebekollisionen mit Kollidern. Eine billigere Alternative ist die Feinabstimmung der Oberflächenpenetration für Stoffkonstrate. Da es in unserem Spiel viele Animationen und verschiedene Posen von Charakteren gibt, wurde eine Liste der "gefährlichsten" zusammengestellt, bei der alle Gewebe auf das Eindringen in andere Körperteile überprüft wurden.



Wir haben auch eine Gewebesimulation verwendet, um den FX-Flammeneffekt auf Waffen und den Kopf des Bosses Shadow Mind zu erzeugen. In den Stoffeinstellungen für diese Elemente haben wir den Einfluss der Schwerkraft ausgeschaltet und die Beschleunigungswerte entlang der Y-Achse festgelegt: konstant, sodass sich die Flamme für den Flattereffekt nach oben und zufällig bewegt. Damit bei Bewegungen die Geometrie nicht stark verzerrt wird, setzen wir den erhöhten Widerstandswert ( Damping ). Somit haben wir einen relativ realistischen und in Bezug auf Leistung günstigen Flammeneffekt erhalten.





Deterministische Physik für synchrones PvP


Zum Zeitpunkt des Todes und in bestimmten Situationen, wenn in Shadow Fight 3 Charaktere angegriffen werden, wird eine Simulation der Physik aktiviert. Lange Zeit wurde hierfür die Festkörperphysik von Unity Stock verwendet. Bei der Einführung von synchronem PVP in das Projekt musste es jedoch zugunsten seiner eigenen Entwicklung aufgegeben werden.

Synchrones PVP impliziert die gleiche Simulation eines Spiels auf zwei Clients. Es gibt keine Probleme mit der Animation, da alles im Voraus berechnet wurde, während bestimmte Probleme mit der Physik auftreten.

Tatsache ist, dass Gleitkommaberechnungen, die in Unity in der Physik verwendet werden, auf Prozessoren verschiedener Hersteller unterschiedlich funktionieren. In dieser Hinsicht häufen sich während des Spiels Fehler in der Position der Charaktere - auf einem Client befindet sich der Charakter anders als der andere. Und wenn diese Diskrepanz außerhalb der Physik leicht durch periodisches Synchronisieren der Position auf der Grundlage von Indikatoren von einem der Clients korrigiert werden kann, dann entwickelt sich zum Zeitpunkt der Initialisierung der Physik aufgrund des Startfehlers der Position die physikalische Simulation auf zwei Clients unterschiedlich.

Infolgedessen befindet sich der Charakter signifikant an verschiedenen Orten und an verschiedenen Positionen. Nach einer solchen Diskrepanz tritt früher oder später eine Situation auf, in der Angriffe auf einen Client und nicht auf den anderen Client aufgezeichnet werden.

Die auf den ersten Blick einfachste Lösung besteht darin, die Position des Charakters auf einem Client zu erfassen und auf einen anderen zu übertragen, während sie während einer physischen Simulation synchronisiert werden. Das Regdoll des Charakters besteht jedoch aus einer langen Hierarchie von Knochen mit einer großen Anzahl separater unabhängiger Körper (Gliedmaßen, Kopf), damit die Position, an der Sie eine große Datenmenge in kurzer Zeit übertragen müssen, korrekt synchronisiert werden kann. Diese Option erwies sich als zu „teuer“, sodass wir beschlossen, unsere eigene Physik zu schreiben, die deterministisch sein würde. Damit wir sicher sein können, dass auf jedem Client die physischen Zustände der Zeichen übereinstimmen, unabhängig davon, auf welchem ​​Prozessor die Berechnungen durchgeführt werden.



Also, was ist unsere Regdoll? Der Körper besteht aus Knoten, die materielle Punkte sind. Sie haben keine Orientierung, aber es gibt eine Position und Masse, und zwischen ihnen werden Verbindungen mit einstellbarer Steifheit realisiert. Eine Gruppe solcher Knoten ist mit jedem Knochen im Skelett des Charakters verbunden. Diese Architektur impliziert das Fehlen von internen Kollisionen und Einschränkungen in den Gelenken, und externe Kollisionen und Reibung werden auf Knotenebene implementiert. Wenn sich Knoten im Raum bewegen, werden Schwerkraft, äußere Kräfte und Trägheit berücksichtigt.

Zwischen Knoten gibt es zwei Arten von Verbindungen: starre Rippen (blau) und elastische Muskeln (rot). Die Rippen spielen die Rolle von Knochen und zwingen die Knoten, in einem bestimmten Abstand voneinander zu sein, und verhindern, dass sie sich in verschiedene Richtungen zerstreuen. Muskeln aus jeder Ausgangsposition bilden eine bestimmte Pose aus den Knoten, ziehen sie zusammen, wenn der Abstand zwischen ihnen größer als der Zielwert ist, und schieben sie auseinander, wenn er kleiner ist.



Schauen Sie „unter die Haube“ und sehen Sie, wie es funktioniert. Zuerst erlauben wir den Knoten, sich frei zu bewegen, und passen dann iterativ die Verknüpfungen an, damit sie sich auf ihre Zieleigenschaften erholen. Für eine Iteration der Muskelanpassung sind zwei Iterationen der Rippenanpassung erforderlich. Indem wir die Rippen steifer machen, können wir sicher sein, dass die Rippenverbindungen nicht brechen, nachdem die Muskeln den Knoten ausgesetzt sind.



Je stärker sich die Knoten im Stadium der freien Bewegung verschieben, desto mehr Rechenaufwand muss aufgewendet werden, um die Rippen und Muskeln wiederherzustellen. Um diese Kosten und das Risiko von strukturellen Störungen zu minimieren, haben wir uns entschlossen, den iterativen Prozess in mehrere Schritte zu unterteilen. Das heißt, in einem Frame findet mehrmals die freie Bewegung von Knoten und deren Korrektur statt. In einem Schritt können sich die Knoten viel weniger bewegen, und das Anpassen wird viel einfacher. Auf diese Weise sparen wir die Anzahl der für die Anpassung der Rippen und Muskeln erforderlichen Iterationen erheblich ein.



Die Menge der Muskellängen bestimmt die Zielpose, die der Charakter nach dem Übergang zu einer physischen Simulation von jeder Position aus sucht. Um zu abrupte Übergänge und strukturelle Störungen zu vermeiden, haben wir die Interpolationsposition hinzugefügt. Im Moment des Eintritts in die Physik nehmen wir die aktuelle Pose des Charakters und machen sie zum Ziel. Dann interpolieren wir sie für fünfzig Frames auf die voreingestellte Zielpose, um einen reibungslosen Übergang zu erzielen.



Das Hauptproblem, auf das wir bei der Verwendung unserer Physik gestoßen sind, ist das periodische Verdrehen von Gliedmaßen, hauptsächlich von Armen. Dies ist auf die Tatsache zurückzuführen, dass sich der Charakter zum Zeitpunkt des Übergangs in die Physik möglicherweise in einer Position weit vom Ziel entfernt befindet, auf die sich seine Muskeln verengen. Um solche Situationen zu minimieren und in Zukunft vollständig zu vermeiden, wurde eine Reihe von Maßnahmen ergriffen. Zuallererst haben wir mehrere Zielpositionen eingerichtet, an denen die Muskeln die Knoten straffen können. In dem Moment, in dem wir in die Physik eintreten, nehmen wir die aktuelle Pose ein, schauen, welcher der voreingestellten Zielposen sie am nächsten ist, und ziehen die Knoten daran fest.



Anfänglich haben die Muskeln beim Übergang in die Physik die Knoten starr gedrückt und in die gewünschte Position gebracht. Oft führte die Schärfe dieser Abstoßung auch dazu, dass sich die Extremitäten stark verdrehten. Wir haben eine sanfte Steigerung der Muskelkraft hinzugefügt, was die Situation erheblich verbessert hat. Während der ersten beiden Frames nach dem Start der Physiksimulation bleibt die Muskelkraft auf ihrem Maximum, um die Knoten zu stabilisieren, nachdem ein Impuls auf sie ausgeübt wurde. Dann entspannen sich die Muskeln, ihre Kraft wird 55%, und über 120 Frames steigt die Kraft allmählich auf 100% an.



Der letzte Schritt bestand darin, zwei Stabilisierungsknoten hinzuzufügen: den vorderen auf Brusthöhe und den hinteren auf Beinhöhe. Diese Knoten haben Rippenverbindungen mit festen Knoten der Brust bzw. des Beckens, und instabile Knoten ziehen sich mit den Muskeln zusammen. Die Stabilisierungsknoten haben einen niedrigen Massenwert und haben im Gegensatz zu anderen Knoten keine Kollision mit dem Boden.



Im GIF unten sehen Sie das Ergebnis: Wir haben eine vollständig deterministische Physik, die auf ganzzahligen Berechnungen basiert und selbst auf den schwächsten von uns unterstützten Geräten stabil mit 60 fps arbeitet.



Folgen Sie Banzai Games in sozialen Netzwerken: Facebook , Vkontakte , Instagram , LinkedIn

Das Banzai Games-Team benötigt einen erfahrenen VFX-Spezialisten. Lesen Sie hier mehr über die Vakanz.

Source: https://habr.com/ru/post/de480108/


All Articles