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

Calculate new rotation for an object along two axis

Discussion in 'Scripting' started by omatase, Jun 9, 2016.

  1. omatase

    omatase

    Joined:
    Jul 31, 2014
    Posts:
    159
    I have a cube that I want to rotate. I want to randomly calculate a new rotation for the cube and slerp to the new rotation. I want to be able to rotate it around the y and x axis but I don't want it to rotate around the z axis.

    Here is the code I tried to use for this purpose but it seems to rotate along only the z axis even though my "newRotation" vector3 has a z value that never changes. I'm sure this is just something about Quaternion rotation that I don't understand, please help! :)

    Code (CSharp):
    1. private void slowMove()
    2. {
    3.     // if we're in our origin rotation, then pick a new random rotation
    4.     // x +/- 90 degrees, y +/- 90 degrees and z +/- 90 degrees from our
    5.     // current rotation
    6.     float rotationVariance = 90;
    7.  
    8.     var newRotation = new Vector3(_originalRotation.x + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.y + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.z);
    9.  
    10.     _toRotation = Quaternion.FromToRotation(_originalRotation.eulerAngles, newRotation);
    11.  
    12.     //UnityEngine.Random.rotation;
    13. }
    14.  
    15. void Update()
    16. {
    17.     if (_toRotation != null)
    18.     {
    19.         // slowly move to our new rotation over time
    20.         transform.rotation = Quaternion.Slerp(transform.rotation, _toRotation.Value, Mathf.Clamp01(Time.deltaTime * 10));
    21.  
    22.         // until the difference in angle between our current rotation and
    23.         // our destination rotation is < 1
    24.         if (Quaternion.Angle(transform.rotation, _toRotation.Value) < 1)
    25.         {
    26.             _toRotation = null;
    27.         }
    28.     }
    29. }
    Here's an ani gif showing the rotation. Each time it rotates again it's after I have clicked it.

    https://gyazo.com/1f943b1cc1089084a4c402031d638722

    As you can see it's only rotating on the z axis for some reason even though the z value should not be changing.
     
  2. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Change your _toRotation to a Vector3 and set it to the new rotation vector. Use Vector3.RotateTowards(or Vector3.Slerp) instead of Quaternion.Slerp and then update transform.rotation with Quaternion.Euler.
     
    Last edited: Jun 9, 2016
  3. omatase

    omatase

    Joined:
    Jul 31, 2014
    Posts:
    159
    BOOM! That worked, thanks! My final code if anyone is interested.

    Code (CSharp):
    1. private void slowMove()
    2. {
    3.     // if we're in our origin rotation, then pick a new random rotation
    4.     // x +/- ? degrees and y +/- ? degrees from our current rotation
    5.     float rotationVariance = 45;
    6.  
    7.     _toRotation = Quaternion.Euler(_originalRotation.x + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.y + UnityEngine.Random.Range(rotationVariance * -1, rotationVariance), _originalRotation.z);
    8. }
    9.  
    10. void Update()
    11. {
    12.     if (_toRotation != null)
    13.     {
    14.         // slowly move to our new rotation over time
    15.         transform.rotation = Quaternion.Slerp(transform.rotation, _toRotation.Value, Mathf.Clamp01(Time.deltaTime * 10));
    16.  
    17.         // until the difference in angle between our current rotation and
    18.         // our destination rotation is < 1
    19.         if (Quaternion.Angle(transform.rotation, _toRotation.Value) < 1)
    20.         {
    21.             _toRotation = null;
    22.         }
    23.     }
    24. }
     
  4. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    I updated my reply with Vector3 methods that might be slightly faster than the Quaternion functions.
     
    Last edited: Jun 9, 2016