Problem bei der Kollisionserkennung eines sich schnell bewegenden Balles mit einem Schläger, der mit der Maus gesteuert wird

8

In der Einheit habe ich einen Schläger, der einen Ball treffen soll, und der Schläger wird direkt von der Maus gesteuert, dh der Schläger wird mit der Maus über Mausachsen bewegt und die Funktion transform.translate () wird verwendet bewege den Schläger.

Ich habe erwartet, dass die Physik von Unity3d die Bewegung des Schlägers nicht direkt mit der Maus übersetzen und den Ball entsprechend beeinflussen wird, und ich müsste etwas Brauchbares schreiben, und es stellte sich heraus, dass es wahr ist.

Aber die Kollision des Balls wird nicht richtig erkannt, wenn sich der Schläger bewegt. Wenn es still ist, ist alles in Ordnung, und der Ball verhält sich so, wie ich es mag.

Nun ging ich so weit, ein eigenes Physikskript zu schreiben (ich benutze C # für Scripting), in dem ich 4 Raycasts der Länge 0.6F an den Ball anschloss und nach einigen komplexen Vektorberechnungen die Geschwindigkeit des Balls danach berechnete Schlagen Sie den Schläger und wenden Sie ihn direkt auf die Geschwindigkeit des Balls an, indem Sie rigidbody.velocity = velocityVelocity () verwenden. Jetzt funktioniert es wieder gut, wenn sich der Schläger nicht bewegt, aber nicht, wenn ich den Schläger bewege. Das genaue (Symptome des) Problems ist:

Mit eingebauter Physik und Kollisionserkennung: Wenn sich der Schläger bewegt, läuft der Ball manchmal gerade durch den Schläger und manchmal verlangsamt er sich (auf unglaubliche Werte).

Mit meinem Skript Geschwindigkeit berechnen: Das Problem ist das gleiche, aber es lässt mich identifizieren, was falsch ist, wenn ich die Normale des Colliders (der Schläger) drucke. Es gibt manchmal die richtige Normale und manchmal gibt es das Negativ des Normalenvektors, was bedeutet, dass es gerade durch die obere Oberfläche geht und den Treffer mit der Unterseite des Colliders (Schläger) erkennt.

Die Dinge, die ich versucht habe:

  1. Die Größe des Colliders erhöhen (es funktioniert mit dem breiteren Box Collider am Schläger, aber dann bewegt sich offensichtlich der Ball aus einiger Entfernung vom Schläger, und mein eigenes Skript funktioniert hier, die Standard-Physik ist seltsam Ergebnisse, wenn der Schläger bewegt wird), kurz gesagt, bekomme ich nicht die Realität, die ich will.

  2. Den festen Zeitstempel auf 0.001 zu reduzieren, was die Dinge wesentlich verbessert hat, aber immer noch sehr weit entfernt von dem Ergebnis, das ich will, und der Ball ist wieder ziemlich oft auf der falschen Seite des Balls.

  3. Ändern der Kollisionserkennung auf kontinuierliche Dynamik. Was auch die Dinge nicht verbessert hat.

Und zusätzlich zu der falschen Seite, die bei der Kollision ausgewählt wurde, ist ein anderes Problem, das ich beobachtet habe, dass nach dem Abprallen des Schlägers der Ball bewegt wird, aber der Schläger wird schneller bewegt, anstatt sich in einem kompletten Bogen oder einer Linie irgendwie zu bewegen erscheint vor dem Ball und führt zu zwei Schlägen. Es ist eine Vermutung, basierend auf was sichtbar ist.

Es ist auch klar, dass der "Bewegungs" -Aspekt des Schlägers nicht von der eingebauten Physik von Unity3d gelesen wird, was zu einem seltsamen Verhalten führt, wenn der Schläger mit der Maus den Ball bewegt.

Ich stecke fest, ich habe keine Ahnung, wohin ich mich von hier aus bewegen soll. Bitte sag mir, was ich falsch mache.

    
SpeedBirdNine 09.09.2011, 16:47
quelle

4 Antworten

8

Wie andere betont haben, besteht das Problem darin, dass der Ball von einer Seite des Pads in einem Frame zur nächsten auf der anderen Seite wechselt. Sich schnell bewegende Objekte tendieren dazu, wenn die Barrieren zu schmal sind.

Es gibt drei sehr einfache Lösungen für dieses Problem:

  • Vergrößern Sie die Größe des Pads oder des Balls, was beim Ändern der Collider-Größe passiert ist.
  • Stellen Sie eine maximale Geschwindigkeit für den Ball her, damit er sich niemals schnell genug bewegen kann, um durch die Pads zu gehen.
  • Erhöhen Sie die Häufigkeit, mit der Unity seine physikalischen Berechnungen durchführt. Es kann in Zeitmanager geändert werden, wodurch der Wert von Fixed Timestep reduziert wird. Hüten Sie sich davor, dies zu sehr zu reduzieren, oder die Physik-Engine wird nicht in der Lage sein, einen Anruf zu beenden, bevor die nächste Runde beginnen wird, und es wird nie in der Lage sein, das Spiel nachzuholen.

Das Festlegen einer maximalen Geschwindigkeit zum Bewegen von Objekten muss immer durchgeführt werden. Sie können nicht riskieren, dass ein wichtiges Objekt während des Spiels in die Höhe schießt und alles in einem unkontrollierten Zustand lässt.

    
Elideb 10.09.2011, 16:58
quelle
5

Was ich denke ist, dass jedes Intervall, in dem der Ball / Schläger passiert, bewegt und dann auf eine Kollision überprüft wird. Das Problem ist, dass sich der Ball / Schläger in einem einzigen Intervall zu weit bewegt und die Kollision verpasst.

%Vor%

Sie müssen also in Ihrer FixedUpdate () - Methode Ihres Balls vorgehen. GameObject wirft einen Strahl von der aktuellen Ballposition auf die vorherige Ballposition. Wenn zwischen diesen beiden Punkten, die getroffen werden sollten (dh der Schläger), etwas ist, rückt der Ball zurück zum gemeldeten Trefferpunkt auf dem Strahl. Dies wird Ihre bestehenden Kollisionserkennung Zeug auslösen.

Der Grund für die Vergrößerung des Colliders ist auch, dass der Ball den Lagercollider nicht überspringt. Dies hat die Nachteile, die Sie in Ihrer Frage erwähnt haben. Das Raycasting vermeidet dieses Problem und ermöglicht es dem Ball / Schläger, sich so schnell oder langsam zu bewegen, wie es nötig ist.

    
Justin808 10.09.2011 00:34
quelle
3

Das ist keine vollständige Antwort, aber ich erinnere mich, dass ich mich vor vielen Jahren mit langsameren Maschinen beschäftigt habe.

Das Problem bestand darin, eine Sprite-basierte Kollisionserkennung zu verwenden. Verlass auf Pixel für das Sprite und das Hindernis, die an den gleichen Koordinaten gerendert werden. Wenn die Bildrate so niedrig ist, dass sich das Sprite mehr als die Hindernisgröße in einem Bild bewegt, kommen Sie in Situationen, in denen es zum Beispiel links vom Hindernis in einem Bild und rechts vom Hindernis im nächsten Bild ist besetzen die gleichen Pixel.

In diesem Fall funktionieren Sprite-basierte Kollisionen nicht, Sie müssen Kollisionen auf Vektoren basieren. Anstatt jedes Sprite-Pixel auf Kollisionen zu überprüfen, notieren Sie die Position und die konvexe Hülle des Sprites. Berechnen Sie nach jedem Bild einen Vektor von der alten Position zur neuen Position und schneiden Sie ihn mit der konvexen Hülle jedes Hindernisses.

Es gibt mehrere Verknüpfungen, die Sie erstellen können, z. B. den Vergleich nur mit Begrenzungsrahmen und die Berechnung der Hülle nur dann, wenn der Vektor eine Begrenzungsbox schneidet, aber dies ist die Grundidee. Viel Glück.

    
Dour High Arch 09.09.2011 17:10
quelle
0

Ich habe auch an einem 3D-Pong-Spiel gearbeitet und bin genau auf die gleichen Probleme gestoßen. Ich werde versuchen, alles zu vergrößern, wie ihr es gemacht habt. Was das Paddel anbelangt, das dem Ball Geschwindigkeit und Spin hinzufügte, verwirrte mich das, bis ich erkannte, dass die Änderung der Position des Paddels seine Geschwindigkeit nicht ändert. Wenn das Paddel vor dem Verschieben auf Geschwindigkeit Null war, wird es bei Null sein, wenn die Physik-Engine das nächste Frame betrachtet. Unchecking ist kenimatic und das Paddel direkt durch die Geschwindigkeitseigenschaft kontrollierend, reparierte das Problem. Es verursachte ein Flattern des Paddels, wenn es auf Wände traf, aber ich reparierte das, indem ich die Wände von der Paddelschicht entfernte und die Grenzen manuell in LateUpdate behandelte. Wenn Sie die Geschwindigkeit aktualisieren, speichern Sie zuerst die neue gewünschte Geschwindigkeit in Update, damit die Kontrollen reibungslos funktionieren, und übernehmen Sie dann die Änderungen in FixedUpdate.

    
user3495617 03.04.2014 20:52
quelle