Ich frage mich, ob jemand eine Anleitung geben könnte.
Ich versuche, ein pendelartiges Verhalten im 2D-Raum in Unity zu erstellen, ohne ein Scharniergelenk zu verwenden.
Im Wesentlichen möchte ich einen fallenden Körper so beeinflussen, als ob er im Radius eines Punktes festgehalten würde und der Schwerkraft und Reibung usw. ausgesetzt wäre.
Ich habe viele Modifikationen dieses Codes ausprobiert und mir ein cooles Verhalten wie ein seltsamer Attraktor ausgedacht, aber ich kann für mein ganzes Leben keine realistische Pendel-ähnliche Aktion erstellen.
Das habe ich bisher:
startingposition = transform.position; //Get start position
newposition = startingposition + velocity; //add old velocity
newposition.y -= gravity * Time.deltaTime; //add gravity
newposition = pivot + Vector2.ClampMagnitude(newposition-pivot,radius); //clamp body at radius???
velocity = newposition-startingposition; //Get new velocity
transform.Translate (velocity * Time.deltaTime, Space.World); //apply to transform
Also arbeite ich die neue Position basierend auf der alten Geschwindigkeit + Schwerkraft aus und beschränke sie dann auf einen Abstand von einem Punkt, der das Element im Code ist, das ich nicht richtig bekommen kann. Ist das ein logischer Weg?
Antworten:
Ich dachte, dies wäre ein relativ einfaches Problem, aber ich verbrachte ein paar Tage damit, herauszufinden, wie zum Teufel man Pendelbewegungen simuliert. Ich wollte nicht schummeln und nur die x-, y-Position basierend auf den Kurven sin (Theta) und cos (Theta) ändern. Stattdessen wollte ich mich mit den beiden Kräften befassen, die im wirklichen Leben angewendet werden, Schwerkraft und Spannung . Das Hauptstück, das mir fehlte, war die Zentripetalkraft.
Die Wikipedia-Seite Pendel (Mathematik) enthält eine großartige Animation (unten links), die die Pendelbewegung erklärt. Sie können sehen, dass mein Ergebnis (rechts) diesem Diagramm auffallend ähnlich ist
Der "Bob" ist das schwingende Objekt und der "Pivot" ist der Ursprung / die Wurzel.
Ich fand auch diesen Artikel und das Diagramm (unten) ziemlich hilfreich:
Theta
entspricht dem Winkel zwischen dem Seil und der Richtung der Schwerkraft.Wenn sich der Bob links oder rechts befindet, ist die Spannung gleich:
Der Grund, warum die Spannungskraft größer ist, wenn sich der Bob dem Gleichgewichtspunkt (Mitte) nähert, liegt in der Zentripetalkraft :
Die Formel für die Gesamtspannung sieht also so aus, wie der Bob schwingt:
Es gibt zwei Kräfte im Pendelsystem:
GravityForce = mass * gravity.magnitude
GravityDirection = gravity.normalized
TensionForce = (mass * gravity * Cos(theta)) + ((mass * velocityTangent^2)/ropeLength)
TensionDirection = ropeDirection = bob to pivot
Wenden Sie einfach die Schwerkraft auf Ihr Objekt an, wie Sie es für ein normales Objekt tun würden, und wenden Sie dann die Spannung an. Wenn Sie die Kräfte anwenden, multiplizieren Sie die Kraft einfach mit der Richtung und der DeltaTime.
Unten ist das
Pendulum.cs
Skript (auch als GitHub Gist ). Es funktioniert recht gut, aber es gibt einige Rundungsfehler, wenn Sie es für eine Weile verlassen (kehrt nicht zu genau derselben Position zurück).Das Skript funktioniert in 3D, aber natürlich schwingt ein Pendel nur in einer 2D-Ebene. Es funktioniert auch mit der Schwerkraft in jede Richtung. Wenn Sie beispielsweise die Schwerkraft umkehren, arbeitet das Pendel verkehrt herum.
Edit->Project Settings->Physics->Gravity
Es ist sehr wichtig, beim Aktualisieren des Pendels eine konsistente, relativ kleine DeltaTime zu haben, damit Sie nicht um die Kurve springen. Ich verwende die in diesem Artikel beschriebene Technik, FIX YOUR TIMESTEP! von Glenn Fiedler , um dies zu erreichen. Überprüfen Sie die
Update()
Funktion unten, um zu sehen, wie ich sie implementiert habe.Auch als GitHub Gist
Weitere Glamour-Shots:
quelle
dt
kann hilfreich sein, da deltaTime kleiner ist, wodurch es weniger interpoliert, aber auch mehr Ungenauigkeit im Dezimalbereich bedeutet. Ich denke, das eigentliche Problem ist, dass ich den Abstand zum Drehpunkt begrenzen kann, da sich das Seil nicht dehnen kann (siehe untenPendulumUpdate
). Denken Sie auch daran, dass dies ein Seil und keine starre Stange ist. Wenn Sie also den Bob in die Mitte legen, fällt er frei, bevor Sie das Ende des Seils treffen und anfangen zu schwingen.return this.GetPointOnLine(pivot_p, currentStatePosition + movementDelta, distance <= this.ropeLength ? distance : this.ropeLength);
.