Ich arbeite an einem Spiel, bei dem der Spieler Objekte mit einem Traktorstrahl aufnehmen und herumtragen kann.
Das Objekt in Richtung Strahlmitte anzuziehen ist nicht schwierig. Aber sobald das Objekt nahe genug an der Mitte ist, muss ich es dort halten, während sich der Spieler bewegt, womit ich Probleme habe. Ich kann mir zwei Möglichkeiten vorstellen, und beide haben Probleme:
Aktualisieren Sie die Position des Objekts, wenn sich die Position des Spielers ändert, und halten Sie es auf dem Strahl zentriert.
Aktualisieren Sie die Geschwindigkeit des Objekts so, dass sie direkt auf die Mitte des Strahls zeigt. Je weiter entfernt, desto höher die Geschwindigkeit.
Das Bewegen und Drehen funktioniert bei beiden Ansätzen einwandfrei, aber die Physik ist falsch, wenn das getragene Objekt mit anderen Objekten kollidiert:
Beim ersten Ansatz wird die Physik völlig ignoriert. Das getragene Objekt schiebt einfach alles aus dem Weg. Das liegt daran, dass Positionsänderungen nur als Teil der Weltphysik basierend auf der Geschwindigkeit vorgenommen werden sollen.
Beim zweiten Ansatz verhält sich die Physik grundsätzlich so, wie sie sollte, reagiert jedoch übermäßig. Das Problem ist: Um das getragene Objekt auch beim Drehen und Bewegen in der Mitte des Strahls zu halten, muss ich hohe Geschwindigkeitswerte verwenden. Sobald das getragene Objekt ein anderes berührt, wird die Kollision viel zu schnell.
Wie kann ich das richtig umsetzen? Meine derzeit beste Vermutung ist, den zweiten Ansatz zu wählen und der Weltphysik eine spezielle Handhabung für getragene Objekte hinzuzufügen, um die Geschwindigkeit auf vernünftige Werte für Kollisionen zu reduzieren oder wenn der Spieler aufhört, sie zu tragen. Aber das scheint eine ziemlich unelegante Problemumgehung zu sein.
Bearbeiten: Hinzufügen von Pseudocode, um zu veranschaulichen, wie es jetzt funktioniert (das wäre der zweite Ansatz oben)
void attract_object(object, ticks) {
Vector distance = beam_center - object.center;
// If the object is not close to the beam center, attract it slowly
if (magnitude(distance) > 10) {
object.velocity += distance.normalized() * ticks * 0.1;
return;
}
// Here comes the part we're talking about. That magic 0.5 is just high enough
// that the object isn't lost while moving around. But it's still so high that
// other objects are repelled with way too much force.
object.velocity = distance * ticks * 0.5;
}
Soweit ich weiß, geschieht dies, wenn das getragene Objekt ein anderes Objekt wegschiebt:
- Das getragene Objekt kollidiert mit einem anderen Objekt
- Die Geschwindigkeiten der Objekte sind richtig verteilt, so dass das getragene Objekt dabei von der Mitte des Strahls weggeschoben wird
- Der obige Code bewirkt, dass das getragene Objekt mit so viel Geschwindigkeit in die Mitte des Strahls zurückkehrt, dass es schnell dorthin zurückkehrt
- Wenn sich das getragene Objekt zur Mitte des Strahls zurückbewegt, wird die Hälfte seiner hohen Geschwindigkeit auf das andere Objekt übertragen, wodurch es heftig abgestoßen wird. Da die Anfangsgeschwindigkeit des getragenen Objekts vernünftig zu sein scheint, kann ich mir vorstellen, dass die Schritte 2 bis 4 mehrmals wiederholt werden, wodurch eine so hohe Geschwindigkeit entsteht.
Das scheint die Ursache zu sein. Ich kann mir keinen guten Weg vorstellen, das Problem zu beheben :(