Wie vermeide ich das Stapeln der Bewegungsgeschwindigkeit, wenn mehrere Tasten gedrückt werden?

16

Ich habe ein neues Spiel gestartet, für das keine Maus erforderlich ist, sodass die Bewegung der Tastatur überlassen bleibt. Ich habe versucht, 8 Richtungen zu integrieren; hoch, links, rechts, hoch rechts und so weiter. Wenn ich jedoch mehr als eine Pfeiltaste drücke, stapelt sich die Bewegungsgeschwindigkeit ( http://gfycat.com/CircularBewitchedBarebirdbat ). Wie könnte ich dem entgegenwirken?

Hier ist ein relevanter Teil meines Codes:

var speed : int = 5;

function Update () {
    if (Input.GetKey(KeyCode.UpArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    } else if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.RightArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    } else if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftArrow)) {
        transform.rotation = Quaternion.AngleAxis(315, Vector3.up);
    }
    if (Input.GetKey(KeyCode.DownArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}
eren_tetik
quelle
3
Tangens: Die Einrückung in Ihrem Code war ein wenig durcheinander, so dass ich es zuerst nicht bemerkt habe, aber die Bedingungen in Ihrem Code verhindern, dass das meiste davon ausgeführt wird. Als ob (UpArrow) else if (UpArrow && RightArrow) niemals den Zweig 'else' ausführen würde.
jhocking

Antworten:

13

Trennen Sie Ihren Richtungsauswahlcode vom tatsächlichen Bewegungscode.

  1. Wählen Sie, Directionindem Sie prüfen, welche Tasten gedrückt werden. Speichern Sie es als Einheitsvektor (normalisiert).
  2. Multiplizieren Sie Ihr Directionmit Speedund mit DeltaTime.
  3. Wenden Sie die resultierende Transformation auf Ihr Objekt / Ihre Kamera an.
Kromster sagt Unterstützung Monica
quelle
27

Sie müssen die Summe der Richtungen nehmen, diese normalisieren und dann mit der Geschwindigkeit multiplizieren.

Dies beantwortete ich tangential als Teil meiner Reaktion auf die Verhinderung diagonaler Bewegungen

Speziell:

velX = 0;
velY = 0;

if(keyLeft) velX += -1;
if(keyRight) velX += 1;
if(keyUp) velY += -1;
if(keyDown) velY += 1;

// Normalize to prevent high speed diagonals
length = sqrt((velX * velX ) + (velY * velY ));
if (length != 0)
{
    velX /= length;
    velY /= length;
}

velX *= speed;
velY *= speed;
jzx
quelle
3
Heheh, Larry wäre stolz! c2.com/cgi/wiki?LazinessImpatienceHubris
jzx
3
Beachten Sie, dass Unity bereits Methoden bereitstellt, um die Größe und die quadratische Größe eines Vektors zu ermitteln.
Selali Adobor
1
Dies erzeugt NaN, wenn keine Tasten gedrückt werden
CodesInChaos
1
@jzx In der Tat streben wir danach, wie die sagenumwobenen Hobbits zu sein. youtube.com/watch?v=G49RUPv5-NU
Pharap
11

Der "normalisierte Richtungsvektor" ist, wie diese Aufgabe normalerweise angegangen wird und wie oft ich es mache, aber in letzter Zeit habe ich einfach den resultierenden Bewegungsvektor geklemmt. In der Regel wird das gleiche Endergebnis erzielt, und der Code ist viel einfacher:

var moveSpeed = 6.0f;
function Update() {
  var movement = Vector3.zero;
  movement.x = Input.GetAxis("Horizontal") * moveSpeed;
  movement.z = Input.GetAxis("Vertical") * moveSpeed;
  movement = Vector3.ClampMagnitude(movement, moveSpeed);
  movement *= Time.deltaTime;
  transform.Translate(movement);
}

Einfacherer Code ist fast immer besser: E

jhocking
quelle
Was macht ClampMagnitudees, ist es nicht derselbe Code wie Normalize * Constantin disquise?
Kromster sagt Unterstützung Monica
2
Nicht ganz. Durch "Klemmen" eines Werts wird sichergestellt, dass er innerhalb eines Bereichs / unterhalb des Maximums bleibt, während durch Normalisieren der Wert auf eine Konstante gesetzt wird. Zumindest mit Unity gibt GetAxis () leicht beschleunigte Werte zurück, wodurch Sie eine gleichmäßigere Bewegung erhalten. Durch das Normalisieren des Vektors wird diese Beschleunigung außer Kraft gesetzt, während das Klemmen die Beschleunigung zulässt. Es ist subtil, sieht aber besser aus. Der Endeffekt ist jedoch ziemlich gleich.
jhocking
1
+1 für die einzige Antwort, die direkt im Kontext von Unity geschrieben wurde. Die API bietet alle Arten von nützlichen Vektor / Quaternion-Mathematikmethoden für diese Art von Situation, ohne dass Sie einen Grund haben, Ihre eigenen zu würfeln.
Selali Adobor
Ich würde auf 1 klemmen und erst moveSpeednach dem Klemmen mit multiplizieren und möglicherweise mit der Multiplikation mit zusammenführen deltaTime.
CodesInChaos
Gewinnt diese Änderung mehr als nur das Entfernen einer Multiplikationsoperation? Funktioniert die Klemmung 1 anders als die Klemmung 6?
Ich