Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Quaternion rotation in coroutine does not work properly?

Discussion in 'Scripting' started by turbosheep, Apr 8, 2015.

  1. turbosheep

    turbosheep

    Joined:
    Jul 19, 2013
    Posts:
    25
    Alright, I'm trying to make an object called 'pathblock' rotate 90 degrees clockwise every time the player presses 'E'. The player should be able to spam the button, with the block turning 360 degrees without fail.

    I want to see the rotation animation, so I am using coroutine in combination with a slerp function. The coroutine is called in update, if E is pressed.

    Code (CSharp):
    1.  
    2. //Rotates the selected pathblock by 90 degrees over a specified time. A coroutine is necessary to render each slerp() result per seperate frame
    3. IEnumerator RotatePathblock()
    4. {
    5. Debug.Log("Start rotation!");
    6. Quaternion start = Quaternion.Euler(new Vector3(pathblock.transform.rotation.x, pathblock.transform.rotation.y, pathblock.transform.rotation.z)); //Set start variable for Slerp(), the current rotation of the pathblock
    7. Quaternion end = Quaternion.Euler(new Vector3(start.x, start.y, start.z-90.0f));
    8.  
    9. Debug.Log(string.Format("Target Angle: {0}", end.eulerAngles.z));
    10.  
    11. float normalizationFactor = 1.0f / pathblockRotationTime; //We need to normalize time since slerp() works with values between 0-1; we can convert values by multiplying with this factor
    12. float timePassed = 0.0f; //Time passed since the start of the linear interpolation. Starting at 0, it increases until it reaches 1. All values are rendered.
    13.  
    14. while(timePassed < 1.0f) //While the time passes is less than 1 (the maximum of a linear interpolation)
    15. {
    16. timePassed += Time.deltaTime * normalizationFactor; //Increase the timePassed with the time passed since the last frame; the time is first normalized
    17. pathblock.transform.rotation = Quaternion.Slerp(start, end, timePassed); //Set the pathblock rotation to a new value defined by linear interpolation
    18. yield return null; //Stop the function, finish Update() and return to this while loop; this will cause all slerp() values to render, resulting in a smooth animation
    19. }
    20. }
    The first press turns the pathblock 90 degrees, as expected. The second press sets the pathblock back to its original rotation, and turns it 90 degrees again. This leads me to believe that the 'start' variable never changes, even though it should set itself to the new pathblock.transform.rotation when the function is called, getting the new rotation.

    If anyone could look at what's wrong, I'd appreciate it. Any other critique on my code, comments etc. would also be appreciated!
     
  2. renaissanceCoder1

    renaissanceCoder1

    Joined:
    Apr 8, 2015
    Posts:
    127
    If you want to "add" rotation to the current rotation of an object, you need to multiply two Quaternions together and set that equal to the transform's rotation. Hope this helps.
     
  3. turbosheep

    turbosheep

    Joined:
    Jul 19, 2013
    Posts:
    25
    My way of doing things seem to be more accurate; multiplying quaternion vectors seem to provide less accurate results?
    Regardless, the problem remains that every time I press the key the same rotation occurs; the start variable does not get re-initiated after each coroutine call.. Any ideas?
     
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Line 6 is wrong
    you are trying to construct a quaternion using quaternion.Euler(Vector3)
    But then you are accessing transform.rotation.x/y/z, which are NOT euler angles
     
    turbosheep likes this.
  5. turbosheep

    turbosheep

    Joined:
    Jul 19, 2013
    Posts:
    25
    Thank you, this was spot on. Nice catch!