2016-03-20 2 views
4

Dieses Skript aufgerufen, wenn der Benutzer die Maustaste loslassen:Probleme mit Rotationsskripten?

float rot_duration = 3f; 
float rot_speed = 1.8f; 
Quaternion final_rot; 

void Start() 
{ 
    cubeMesh = GameObject.FindWithTag("CubeMesh"); 

    Vector3 initial_rot = transform.rotation.eulerAngles; 
    final_rot = Quaternion.Euler(new Vector3(initial_rot.x, initial_rot.y, 180)); 
} 

public void Update() 
{ 
    if (Input.GetMouseButtonUp(0)) 
    { 
     StartCoroutine (DelayRotate (0.1F)); 
    } 
} 

IEnumerator DelayRotate(float waitTime) 
{ 
     yield return new WaitForSeconds (waitTime); 
     float rot_elapsedTime = 0.0F; 
     while (rot_elapsedTime < rot_duration) { 
     cubeMesh.transform.rotation = Quaternion.Slerp (transform.rotation, final_rot, rot_elapsedTime); 
      rot_elapsedTime += Time.deltaTime * rot_speed; 
      yield return null; 
     } 
} 

Dieses Skript macht ein Gameobject drehen, 0,1 Sekunden nach dem Release Maustaste. Das Problem ist, dass es das GameObject schnell "umdreht" und sich dann dreht.

Ich glaube, es ist wegen final_rot2 = Quaternion.Euler(new Vector3(initial_rot.x, initial_rot.y, 180)); Spiegeln (wegen 180 Wert) Was sollte ich stattdessen tun?

+0

@Prix Die 'while' es sein muss, sonst wird es nicht drehen. –

+0

niemals quaternions *** aus irgendeinem Grund - jemals ***. Verwenden Sie den Aufruf "Drehen". Transform.Rotate (Time.deltaTime, 0, 0); viele Beispiele hier http://docs.unity3d.com/ScriptReference/Transform.Rotate.html – Fattie

+0

Worin ist final_rot initialisiert? – Programmer

Antwort

0

Das Problem hier ist, dass dies nicht für jeden Frame aktualisiert wird. Ich sehe, dass Sie Time.deltaTime hinzufügen, aber es wird nicht pro Frame aktualisiert, es verwendet nur den Wert für den aktuellen Frame mehrmals, da Sie alles in einem Update tun.

könnte Dieser Code funktioniert:

float rot_duration = 10f; 
float rot_speed = 3f; 
float rot_elapsedTime = 3f; 
Quaternion final_rot; 

public void Update() 
{ 
    if (Input.GetMouseButtonUp(0)) 
    { 
     StartCoroutine (Delay (1)); 
    } 
    if (rot_elapsedTime < rot_duration) { 
     cubeMesh.transform.rotation = Quaternion.Slerp (transform.rotation, final_rot, rot_elapsedTime); 
     rot_elapsedTime += Time.deltaTime * rot_speed; 
} 

IEnumerator Delay(float waitTime) 
{ 
    yield return new WaitForSeconds (waitTime); 
    rot_elapsedTime = 0.0F; 
} 

Aber wie gesagt, transform.Rotate ist wahrscheinlich besser.

Edit: Aktualisiert nach OPs Bearbeitung mit neuem Code, Hinzufügen einer Verzögerung von 1 Sekunde.

+0

Entschuldigung, ich habe die 1-sekündige Verzögerung zuerst nicht bemerkt, aber ich denke, Ihr Problem besteht darin, dass Sie eine While-Schleife haben, was bedeutet, dass Sie die ganze Rotation gleichzeitig durchführen, ohne dass der Frame aktualisiert wird. Ich habe meine Antwort auf Ihren neuen Code bearbeitet. –

+0

Seine while-Schleife ist kein Problem, sie gibt return null zurück, was dasselbe bewirkt wie WaitForEndOfFrame() – JoRouss

1

Ich schaute Code sorgfältig und ich konnte zwei Fehler erkennen.

1. Der ein Fehler, der das Problem verursacht ist:

cubeMesh.transform.rotation = Quaternion.Slerp (transform.rotation, final_rot, rot_elapsedTime); 

Der Kerl über mir gesagt, Sie sollten transform.rotation mit cubeMesh.transform.rotation ersetzen. Das ist in der Nähe, aber wird nicht arbeiten. Was Sie sind suppose bis zu die aktuellen Position des Gameobject erhalten außerhalb die while loop und speichern Sie es irgendwo, dann können Sie es verwenden später auf der Innenseite der while loop. Zum Beispiel

Quaternion currentLocation = cubeMesh.transform.rotation; 
while(...){ 
    cubeMesh.transform.rotation = Quaternion.Slerp (currentLocation, final_rot, rot_elapsedTime); 
...Other codes 
} 

2.Ein weitererFehler Ich fand, dass es, wie Sie das Objekt in der Zeit versuchen, zu drehen aussieht, weil Sie eine Variable namens rot_duration.

Wenn dies der Fall ist, haben Sie einen Fehler gemacht, wenn Sie Quaternion.Slerp (transform.rotation, final_rot, rot_elapsedTime); getan haben.

Wenn das Objekt innerhalb von rot_duration Zeit gedreht werden soll, ändern Sie rot_elapsedTime in rot_elapsedTime/rot_duration. Auch entfernenrot_speed als das wird NICHT arbeiten, wenn Sie im Laufe der Zeit drehen möchten.

Wenn dies NICHT was Sie dann ersten Fehler zu tun versuchen fand ich Ihr Problem zu beheben.

Ihre endgültige Code sollte wie etwas aussehen:

float rot_duration = 10f; 
float rot_speed = 3f; 
Quaternion final_rot; 
GameObject cubeMesh; 

void Start() 
{ 
    cubeMesh = GameObject.FindWithTag("CubeMesh"); 

    Vector3 initial_rot = transform.rotation.eulerAngles; 
    final_rot = Quaternion.Euler(new Vector3(initial_rot.x, initial_rot.y, 180)); 
} 

public void Update() 
{ 
    if (Input.GetMouseButtonUp(0)) 
    { 
     StartCoroutine(Delay(1)); 
    } 
} 

IEnumerator Delay(float waitTime) 
{ 
    yield return new WaitForSeconds(waitTime); 
    float rot_elapsedTime = 0.0F; 

    //Get the current rotation 
    Quaternion currentLocation = cubeMesh.transform.rotation; 

    while (rot_elapsedTime < rot_duration) 
    { 
     rot_elapsedTime += Time.deltaTime; 
     cubeMesh.transform.rotation = Quaternion.Slerp(currentLocation, final_rot, rot_elapsedTime/rot_duration); 
     yield return null; 
    } 
}