So lassen Sie den Player reibungslos gegen das Gelände gleiten


11

Diagramm

Ich mache ein isometrisches Spiel. Wenn der Spieler versucht, diagonal in eine Wand zu gehen, möchte ich, dass sie reibungslos darüber gleiten, sodass jeder Teil der Bewegung verwendet wird, der legal ist, und alles, was in Richtung des Normalen geht, weggeworfen wird. Wände können einen beliebigen Winkel haben, nicht nur vertikal oder horizontal, und der Player hat eine 360-Grad-Bewegung.

Ich fühle mich fast da, aber ich kann das letzte Stück nicht in Position bringen.

Update: Tolle Neuigkeiten an alle! Ich habe es funktioniert. Aber ... ich bin ein bisschen verwirrt, was ich normalisieren soll und was nicht. Das Normale muss nur ein Einheitsvektor sein, oder? aber dann mische ich das mit meiner Eingabe, damit ich das normalisiere - irre ich mich?

Übrigens habe ich auch festgestellt, dass ich den Player 1 Pixel in Richtung Normal schieben muss, damit sie nicht an Dingen hängen bleiben - funktioniert gut.

Antworten:


13

Projizieren Sie einfach Ihren Bewegungsvektor auf die Ebenennormale und subtrahieren Sie dann das Ergebnis von Ihrem Bewegungsvektor.

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;

So etwas sowieso. Obwohl in Ihrem schönen Diagramm die Eingabe von der Wand entfernt zu sein scheint, bin ich etwas verwirrt.


Entschuldigung, er soll dort vor einer senkrechten Wand stehen. schreckliche Zeichnung
Iain

1
Ich bin ein bisschen verwirrt über Punktprodukt. Ist das Punktprodukt nicht ein Skalar?
Iain

1
Ja, aber Sie multiplizieren es mit der Normalen (einem Vektor), um den Vektor Ihrer unerwünschten Bewegung zu erhalten. Ein Vektor (x, y, z) multipliziert mit dem Skalar s ergibt den Vektor (sx, sy, sz).
Chris Howe

Fertig, die Variablen so geändert, dass sie hoffentlich mit dem Diagramm übereinstimmen. :)
Chris Howe

@Iain Ich versuche wirklich zu verstehen, wie man diese Antwort verwendet, aber ich kann sie scheinbar nicht verstehen. Wenn ich genau diesen Code erstelle, bekomme ich wirklich seltsame desiredMotionErgebnisse. Hast du das jemals zum Laufen gebracht?
Test

1

Während es einfach ist, nur die Komponente der Bewegung zu entfernen, die in Richtung der Normalen verläuft, kann es für Ihr Gameplay geeignet sein, stattdessen den Bewegungsvektor zu drehen. In einem Action-Spiel für Dritte kann es beispielsweise leicht sein, sich leicht an Wänden und anderen Grenzen aufzuhängen, sodass Sie einige Vermutungen anstellen können, was der Spieler beabsichtigt.

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
   // tune this to get where you stop when you're running into the wall,
   // vs. bouncing off of it
   static float k_runningIntoWallThreshold = cos(DEG2RAD(45));

   // tune this to "fudge" the "push away" from the wall
   static float k_bounceFudge = 1.1f;

   // normalize input, but keep track of original size
   float inputLength = input.GetLength();
   input.Scale(1.0f / inputLength);

   float dot = DotProduct(input, normal);

   if (dot < 0)
   {
      // we're not running into the wall
      return input;
   }
   else if (dot < k_runningIntoWallThreshold)
   {
      Vector intoWall = normal.Scale(dot);
      intoWall.Scale(k_bounceFudge);

      Vector alongWall = (input - intoWall).Normalize();
      alongWall.Scale(inputLength);

      return alongWall;
   }
   else
   {
      // we ran "straight into the wall"
      return Vector(0, 0, 0);
   }
}

Nett. Aber wenn Sie nach einem Fudge-Faktor skalieren, stoßen Sie dann an der Wand entlang oder rutschen daran entlang, oder handelt es sich nur um eine Optimierung?
Chris Howe

Mein Gedanke ist, dass Sie es optimieren, um in Ordnung auszusehen; Sicherlich, wenn es zu groß ist, sieht es so aus, als würden Sie abprallen, aber wenn es subtil genug ist, wird es Sie nur davon abhalten, an leichten Biegungen in der Oberfläche hängen zu bleiben.
Dash-Tom-Bang
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.