2016-09-09 3 views
0

Ich möchte lerp entlang der Z-Achse vor und zurück die gleiche Menge, um zu vermeiden, drehen (wie meine sprite ist keine kreisförmige). Um dies zu tun, plante ich zufällig forward angle, speichern Sie es, lerp zu ihm dann lerp zurück mit der gleichen Menge. Dies führt jedoch zu einem seltsamen Knacken, da, wenn die Rückwärtsdrehungen beginnen, der Startwinkel nicht derselbe wäre, aber es ist derselbe. Wenn ich es anrufe, gebe ich es gleich mal dazwischen. Einiger Code:Quaternion lerp hin und her

IEnumerator LerpQuat(QuatLerpInput rotThis, float time, float leftBoundary, float rightBoundary) 
{ 
    /* 
    * we want to rotate forward, then backward the same amount 
    * to avoid spinning. we store the given value to both of these. 
    */ 

    Transform stuffToRot = rotThis.godRayGO.transform; 

    float lastTime = Time.realtimeSinceStartup; 
    float timer = 0.0f; 
    switch (rotThis.rotState) 
    { 
     case (QuatLerpInput.RotationStates.rotAway): 
      rotThis.deltaRot = Random.Range(leftBoundary, rightBoundary); 
      while (timer < time) 
      { 
       stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y, 
        Mathf.LerpAngle(rotThis.idleRot, rotThis.idleRot + rotThis.deltaRot, timer/time)); 
       timer += (Time.realtimeSinceStartup - lastTime); 
       lastTime = Time.realtimeSinceStartup; 
       yield return null; 
      } 
      rotThis.rotState = QuatLerpInput.RotationStates.setBack; 
      break; 
     case (QuatLerpInput.RotationStates.setBack): 
      while (timer < time) 
      { 
       stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y, 
        Mathf.LerpAngle(rotThis.idleRot + rotThis.deltaRot, rotThis.idleRot, timer/time)); 
       timer += (Time.realtimeSinceStartup - lastTime); 
       lastTime = Time.realtimeSinceStartup; 
       yield return null; 
      } 
      rotThis.rotState = QuatLerpInput.RotationStates.rotAway; 
      break; 
    } 

} 
public class QuatLerpInput 
{ 
    public GameObject godRayGO; 
    public float deltaRot; 
    public float idleRot; 
    public enum RotationStates 
    { 
     rotAway, setBack 
    } 
    public RotationStates rotState = RotationStates.rotAway; 
    public QuatLerpInput(GameObject godRayGO) 
    { 
     this.godRayGO = godRayGO; 
     deltaRot = godRayGO.transform.rotation.z; 
     idleRot = godRayGO.transform.rotation.z; 
    } 
} 

Herausgegeben switch mit Quaternionen:

switch (rotThis.rotState) 
    { 
     case (QuatLerpInput.RotationStates.rotAway): 
      rotThis.deltaRot = Random.Range(leftBoundary, rightBoundary); 
      Quaternion destination = new Quaternion(rotThis.idleQuat.x, rotThis.idleQuat.y, rotThis.idleQuat.z + rotThis.deltaRot, 1.0f); 
      rotThis.deltaQuat = destination; 
      while (timer < time) 
      { 
       stuffToRot.rotation = Quaternion.Slerp(rotThis.idleQuat, rotThis.deltaQuat, timer/time); 
       //stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y, 
       // Mathf.LerpAngle(rotThis.idleRot, rotThis.idleRot + rotThis.deltaRot, timer/time)); 
       timer += (Time.realtimeSinceStartup - lastTime); 
       lastTime = Time.realtimeSinceStartup; 

       yield return null; 
      } 
      rotThis.rotState = QuatLerpInput.RotationStates.setBack; 
      break; 
     case (QuatLerpInput.RotationStates.setBack): 
      while (timer < time) 
      { 
       stuffToRot.rotation = Quaternion.Slerp(rotThis.deltaQuat, rotThis.idleQuat, timer/time); 
       //stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y, 
       // Mathf.LerpAngle(rotThis.idleRot + rotThis.deltaRot, rotThis.idleRot, timer/time)); 
       timer += (Time.realtimeSinceStartup - lastTime); 
       lastTime = Time.realtimeSinceStartup; 

       yield return null; 
      } 
      rotThis.rotState = QuatLerpInput.RotationStates.rotAway; 
      break; 
    } 
+0

Wenn jemand darüber stolperte und nicht helfen konnte, bitte fragen Sie nach einer Klarstellung. Ich habe mein Bestes versucht, aber ich habe mich vielleicht unklar ausgedrückt und ich habe die Antwort immer noch nicht gefunden. – agiro

Antwort

0

Für jeden, der dies sieht, habe ich eine Lösung gefunden.

void LerpQuat(QuatLerpInput rotThis, float time, float leftBoundary, float rightBoundary) 
{ 
    /* 
    * we want to rotate forward, then backward the same amount 
    * to avoid spinning. we store the given value to both of these. 
    */ 

    Transform stuffToRot = rotThis.godRayGO.transform; 

    float lastTime = Time.realtimeSinceStartup; 
    float timer = 0.0f; 

    switch (rotThis.rotState) 
    { 
     case (QuatLerpInput.RotationStates.rotAway): 
      rotThis.deltaRot = Random.Range(leftBoundary, rightBoundary); 
      Quaternion destination = new Quaternion(rotThis.idleQuat.x, rotThis.idleQuat.y, rotThis.deltaRot, 1.0f); 
      rotThis.deltaQuat = destination; 
      rotThis.deltaEulerAngle = Vector3.forward * rotThis.deltaRot;    
      StartCoroutine(RotateMe(rotThis, rotThis.idleQuat, rotThis.deltaEulerAngle, initiateAlphaSwap)); 
      break; 
     case (QuatLerpInput.RotationStates.setBack): 
      StartCoroutine(RotateMe(rotThis, rotThis.deltaQuat,-1.0f * rotThis.deltaEulerAngle, initiateAlphaSwap)); 
      break; 
    } 
} 
IEnumerator RotateMe(QuatLerpInput whatToRotate,Quaternion fromWhere,Vector3 byAngles, float inTime) 
{ 
    Quaternion fromAngle = fromWhere; 
    Quaternion toAngle = Quaternion.Euler(whatToRotate.godRayGO.transform.eulerAngles + byAngles); 
    toAngle = new Quaternion(toAngle.x, toAngle.y, toAngle.z, 1.0f); 

    if(whatToRotate.rotState == QuatLerpInput.RotationStates.setBack) 
    { 
     fromAngle = new Quaternion(whatToRotate.RotEndPos.x, whatToRotate.RotEndPos.y, whatToRotate.RotEndPos.z, 1.0f); 
     toAngle = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 
    } 

    for (float t = 0.0f; t < 1.0f; t += Time.deltaTime/inTime) 
    { 
     whatToRotate.godRayGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t); 
     yield return null; 
    } 
    if(whatToRotate.rotState == QuatLerpInput.RotationStates.rotAway) 
    { 
     whatToRotate.rotState = QuatLerpInput.RotationStates.setBack; 
     whatToRotate.RotEndPos = new Vector3(toAngle.x, toAngle.y, toAngle.z); 
    } 
    else 
    { 
     whatToRotate.rotState = QuatLerpInput.RotationStates.rotAway; 
    } 

} 

Die Abhilfemaßnahme wurde mit Quaternion.Lerp continuosly in einem loop und stellen Sie die Staaten, nachdem die Schleife beendet hat. So macht es, was ich will.

0

Statt den Winkel lerping, sollten Sie das Ziel quaternion berechnen und verwenden Quaternion.Slerp den Zufall quaternion zu interpolieren und zurück.

+0

Danke für die Mühe. Also sollte ich ihnen genau das gleiche X und Y und ein anderes Z geben? – agiro

+0

Ich bearbeite meine Frage mit dem Code mit Quaternions. Es funktioniert immer noch nicht und macht sehr starke Bewegungen. – agiro

+0

Für den Rekord macht es genau das gleiche Knallen mit dem 'Slerp' – agiro

Verwandte Themen