2016-06-02 10 views
2

Ich bin ein neues hier und ich versuche, mit Unity Engine zu arbeiten.Drehen Sie GameObject im Laufe der Zeit

Könnte mir jemand erklären, wie Quaternion.Slerp funktioniert? Weil ich ein Objekt in verschiedenen Winkeln 90, 180 und 270 drehen möchte. Mein Code können Sie unten sehen. Leider mache ich, wenn ich 180 Grad addiere, verrückte Dinge und stelle dann eine Rotation auf (0, 180, 180) für dieses Spielobjekt. Ich möchte bekommen (180,0,0)

public float speed = 0.1F; 
    private float rotation_x; 
    void Update() 
    { 
     if (Input.GetButtonDown("Fire1")) 
     { 
      rotation_x = transform.rotation.eulerAngles.x; 
      rotation_x += 180; 
     } 
     transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(rotation_x, transform.eulerAngles.y, transform.eulerAngles.z), Time.time * speed); 

    } 
+0

Niemals Quaternionen *** aus irgendeinem Grund verwenden ***. Was Sie versuchen, ist lächerlich einfach. *** Alles, was Sie tun müssen, ist umwandeln. Drehen. *** Es ist nur so einfach. Wahrscheinlich so etwas wie ... transform.Rotate (Time.deltaTime, 0, 0); – Fattie

+0

Ich habe versucht, "transform.Rotate" zu verwenden. Leider habe ich keine Ahnung, wie ich diese Drehung interpolieren kann, um eine sanfte Bewegung zu erreichen. Weißt du wie das geht? – Everest1986

Antwort

8

Die meisten Beispiele gibt, einschließlich Unity Beispiele aus ihrer offiziellen Website Lerp in die falsche Art und Weise verwenden. Sie haben sich nicht einmal die Mühe gemacht zu beschreiben, wie es in der API-Dokumentation funktioniert. Sie stärken es einfach in der Update() Funktion und nennen es einen Tag.

Mathf.Lerp, Vector3.Lerp und Quaternion.Slerp Arbeit von einer Position/Dreh zum anderen ändert mit dem t Wert (letzter Parameter) in.That t Wert übergeben wird, ist auch als Zeit kennen.

Die min des t Wert 0F und der max ist 1f.

Ich werde dies mit Mathf.Lerp erklären, um es leichter zu verstehen. Die Lerp Funktionen sind alle gleich für Mathf.Lerp, Vector und Quaternion.

Denken Sie daran, dass Lerp zwei Werte akzeptiert und Werte zwischen ihnen zurückgibt. Wenn wir einen Wert von und haben und wir tun Lerp auf sie:

float x = Mathf.Lerp(1f, 10f, 0f); will return 1. 
float x = Mathf.Lerp(1f, 10f, 0.5f); will return 5.5 
float x = Mathf.Lerp(1f, 10f, 1f); will return 10 

Wie Sie sehen können, gibt die t(0) die min der Zahl übergeben, t(1) gibt den max Wert übergeben und t(0.5) wird Mitte Punkt zwischen dem min und dem max Wert zurückgegeben. Sie tun es falsch, wenn Sie einen t Wert übergeben, der < 0 oder > 1 ist. Dieser Code in dir Update() Funktion macht genau das. Time.time wird jede Sekunde erhöht und wird > 1 in einer Sekunde sein, so dass Sie Probleme damit haben.

Es wird empfohlen, Lerp in einer anderen Funktion/Coroutine anstelle der aktualisierten Funktion zu verwenden.

Hinweis:

Lerp Verwendung hat eine schlechte Seite davon, wenn es um Rotation kommt. Lerp kann nicht Objekt mit dem kürzesten Pfad drehen. Denken Sie also daran. Zum Beispiel haben Sie ein Objekt mit 0,0,90 Position. Nehmen wir an, Sie möchten die Rotation von dieser auf 0,0,120Lerp verschieben kann manchmal links statt rechts drehen, um diese neue Position zu erreichen, was bedeutet, dass es länger dauert, um diese Entfernung zu erreichen.

Nehmen wir an, wir wollen die Rotation (0,0,90) von was auch immer die aktuelle Rotation ist. Der folgende Code ändert die Drehung in 0 Sekunden in 0,0,90.

ROTATION ZEIT:

void Start() 
{ 
    Quaternion rotation2 = Quaternion.Euler(new Vector3(0, 0, 90)); 
    StartCoroutine(rotateObject(objectToRotate, rotation2, 3f)); 
} 

bool rotating = false; 
public GameObject objectToRotate; 
IEnumerator rotateObject(GameObject gameObjectToMove, Quaternion newRot, float duration) 
{ 
    if (rotating) 
    { 
     yield break; 
    } 
    rotating = true; 

    Quaternion currentRot = gameObjectToMove.transform.rotation; 

    float counter = 0; 
    while (counter < duration) 
    { 
     counter += Time.deltaTime; 
     gameObjectToMove.transform.rotation = Quaternion.Lerp(currentRot, newRot, counter/duration); 
     yield return null; 
    } 
    rotating = false; 
} 

Inkremental-Dreh ROTATION ZEIT:

Und drehen Sie einfach das Objekt bis 90 in z-Achse ist der Code unter einem großartiges Beispiel dafür, dass . Bitte beachten Sie, dass es einen Unterschied zwischen dem Bewegen des Objekts zu einem neuen Drehpunkt und dem bloßen Drehen gibt.

void Start() 
{ 
    StartCoroutine(rotateObject(objectToRotate, new Vector3(0, 0, 90), 3f)); 
} 

bool rotating = false; 
public GameObject objectToRotate; 

IEnumerator rotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration) 
{ 
    if (rotating) 
    { 
     yield break; 
    } 
    rotating = true; 

    Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles; 

    Vector3 currentRot = gameObjectToMove.transform.eulerAngles; 

    float counter = 0; 
    while (counter < duration) 
    { 
     counter += Time.deltaTime; 
     gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter/duration); 
     yield return null; 
    } 
    rotating = false; 
} 

Alle meine Beispiele basieren auf der Bildrate des Geräts. Sie können Echtzeit verwenden, indem Sie Time.deltaTime durch Time.delta ersetzen, aber mehr Berechnungen sind erforderlich.

0

Vor allem, Sie können nicht 180 auf Euler Winkel wie das hinzufügen, und das ist hauptsächlich, was Ihr Problem verursacht. Sie sollten stattdessen lieber quaternion direkt verwenden oder an der Transformation selbst arbeiten.

Sie können sich eine Quaternion als Orientierung im Raum vorstellen. Im Gegensatz zu dem, was gesagt wurde, empfehle ich zu lernen, wie man sie benutzt, wenn Sie können. Ich empfehle jedoch nicht, Euler-Winkel zu verwenden, da sie unterschiedlichen Schreibkonventionen unterliegen und manchmal fehlschlagen. Sie können "Gimbal Lock" betrachten, wenn Sie Details darüber möchten.

Einfach ein Slerp oder Lerp (steht für sphärische lineare Interpolation bzw. lineare Interpolation) ist eine Möglichkeit zu interpolieren (von einer Orientierung zur anderen zu gehen, indem man t von 0 auf 1 in einer Koroutine oder anderswo erhöht) Ausrichtung A und B. Der Unterschied zwischen den beiden ist, dass die Slerp Ihnen den kürzesten Weg von A nach B gibt.

Am Ende, wenn t = 1, Lerp (A, B, t) und Slerp (A , B, t) erhalten Sie B.

In Ihrem Fall, wenn Sie ein Objekt im Raum sofort zu einer bestimmten Orientierung drehen möchten, empfehle ich Ihnen, Quaternion.AngleAxis zu verwenden, die der mathematischste Weg ist, mathematisch zu beschreiben Quaternion.

Wenn Sie eine Rotation hinzufügen möchten, sagen 90 ° Sie tatsächliche Orientierung (ohne Animation zwischen den beiden), können Sie etwas tun können:

transform.rotation * = Quaternion.AngleAxis (axis_of_rotation, Winkel) oder transform.rotate verwenden (abhängig von den Parametern kann es eine rechte Multiplikation sein, oder links: lokale oder Welttransformation).

Die Antwort des Programmierers beschreibt, wie Sie Ihre Transformation animieren können. Aber ich schlage vor, dass Sie Quaternion selbst untersuchen, da es Ihnen ein globales Verständnis von Raumtransformationen geben wird.

Verwandte Themen