Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Quaternion Angles messed up

Discussion in 'Scripting' started by asd234w4r5, May 18, 2018.

  1. asd234w4r5

    asd234w4r5

    Joined:
    Oct 4, 2012
    Posts:
    614
    Hello everyone!

    I am trying to rotate an object around its X-Axis and make it stop at certain points. So lets say, there is a sentence with 5 words, these 5 words get wrapped around this capsule and you can later select them. My code for the rotation is here, while the important part is the last one where the angle gets calculated by the "steps"

    Code (CSharp):
    1.  
    2. float steps = 360 / Bandit_Game.gameBandit.answerArray.Length;
    3. //The answers are the split up text, like 5 words
    4.  
    5. private void Update()
    6.     {
    7.         RaycastHit hit;
    8.         Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    9.  
    10.         if (Physics.Raycast(ray, out hit))
    11.         {
    12.             if (hit.collider.GetComponent<CapsuleCollider>().transform.IsChildOf(transform))
    13.             {
    14.                 cardSelected = true;
    15.             }else{
    16.                 cardSelected = false;
    17.             }
    18.         }
    19.  
    20.         if (Input.GetMouseButtonDown(0) && cardSelected)
    21.         {
    22.             differenceX = 0.0f;
    23.         }
    24.         else if (Input.GetMouseButton(0) && cardSelected)
    25.         {
    26.             differenceX = Mathf.Abs(lastX - Input.GetAxis("Mouse Y"));
    27.  
    28.             if (lastX > Input.GetAxis("Mouse Y"))
    29.             {
    30.                 direction = -1;
    31.                 transform.Rotate(Vector3.right, -differenceX);
    32.             }
    33.  
    34.             if (lastX < Input.GetAxis("Mouse Y"))
    35.             {
    36.                 direction = 1;
    37.                 transform.Rotate(Vector3.right, differenceX);
    38.             }
    39.  
    40.             lastX = -Input.GetAxis("Mouse Y");
    41.         }
    42.         else
    43.         {
    44.             if (differenceX > 0.5f)
    45.             {
    46.                 differenceX -= 0.1f;
    47.                 transform.Rotate(Vector3.right, differenceX * direction);
    48.             }
    49.             else if (differenceX < -0.5f)
    50.             {
    51.                 differenceX += 0.1f;
    52.                 transform.Rotate(Vector3.right, differenceX * direction);
    53.             }
    54.             else
    55.             {
    56.                 float vecX = Mathf.Round(transform.eulerAngles.x / steps) * steps;
    57.  
    58.                 transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(new Vector3(vecX, transform.eulerAngles.y, transform.eulerAngles.z)), Time.deltaTime * 50f);
    59.             }
    60.         }
    61.  
    62.         Debug.Log(transform.rotation.x);
    63.     }
    What is happening now: I have 5 * 72 degree steps, which work on the Quaternion between 0 and 1, but as soon as I turn the rotation over 180 degrees, it will start to like "mirror" the positions and it stops between those points instead. I hope you understand, what I mean, otherwise just ask and I get more in detail.

    At least, what I wanted to achieve and couldn't figure out is
    • Calculate the steps (360 / words)
    • Generate the words around the capsule with their right rotation (this is working)
    • Snap the rotation to the nearest "step" calculated in the first bullet

    I hope, you can help me, figure it out. I was trying to work in quaternion world only, but this is unreliable, going through eulerAngles didn't do the trick neither for now.

    Thank you!
     
  2. asd234w4r5

    asd234w4r5

    Joined:
    Oct 4, 2012
    Posts:
    614
    Anyone?
     
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,715
    Maybe this is helpful?
    Code (csharp):
    1. public class Test1 : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     int steps = 0;
    5.     float stepval = 0f;
    6.     [SerializeField]
    7.     float rotval = 0;
    8.     [SerializeField]
    9.     int currentStep = 0;
    10.     [SerializeField]
    11.     float dragRotationSpeed = 5;
    12.  
    13.     void Start()
    14.     {
    15.         stepval = 360 / steps;
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         float mouserot = Input.GetAxis("Mouse Y") * Time.deltaTime * dragRotationSpeed;
    21.         rotval += mouserot;
    22.  
    23.         while(rotval > 1)
    24.         {
    25.             currentStep++;
    26.             if (currentStep >= steps) currentStep = 0;
    27.             rotval -= 1;
    28.         }
    29.         while(rotval < 0)
    30.         {
    31.             currentStep--;
    32.             if (currentStep < 0) currentStep = steps - 1;
    33.             rotval++;
    34.         }
    35.  
    36.         // safely ignore the z with '90'
    37.         transform.rotation = Quaternion.Euler(currentStep * stepval, 0, 90);
    38.     }
    39. }
     
  4. asd234w4r5

    asd234w4r5

    Joined:
    Oct 4, 2012
    Posts:
    614
    I'll give it a try tomorrow! Thank you for sharing your own script :) I'll let you know if it did work!
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,715
    Sure, say I drag the mouse up the screen, it keeps adding to the rotation value, and when it's greater than 1 it increases the value of 'current step', which is then used to calculate current step * step value for your rotation.

    When you get around to trying it, let me know if I understood it correctly. :)
     
  6. asd234w4r5

    asd234w4r5

    Joined:
    Oct 4, 2012
    Posts:
    614
    hey there @methos5k , did not forget to check your script and it helped me well in some steps :) Thanks again. Here is the script of my manager for that single game:

    Code (CSharp):
    1. private void Update()
    2.     {
    3.         RaycastHit hit;
    4.         Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    5.  
    6.         if (Input.GetMouseButton(0))
    7.         {
    8.             if (Physics.Raycast(ray, out hit))
    9.             {
    10.                 if (hit.collider.GetComponent<Bandit_Card>())
    11.                 {
    12.                     hitBanditCard = hit.collider.GetComponent<Bandit_Card>();
    13.  
    14.                     float mouserot = Input.GetAxis("Mouse Y") * Time.deltaTime * 5f;
    15.                     differenceY += mouserot;
    16.                 }
    17.             }
    18.         }
    19.  
    20.         if(Input.GetMouseButtonUp(0))
    21.         {
    22.             while (differenceY > 1)
    23.             {
    24.                 hitBanditCard.currentStep++;
    25.                 //if (hitBanditCard.currentStep >= hitBanditCard.steps) hitBanditCard.currentStep = 0;
    26.                 differenceY--;
    27.             }
    28.             while (differenceY < 0)
    29.             {
    30.                 hitBanditCard.currentStep--;
    31.                 //if (hitBanditCard.currentStep < 0) hitBanditCard.currentStep = hitBanditCard.steps - 1;
    32.                 differenceY++;
    33.             }
    34.  
    35.             if (Physics.Raycast(ray, out hit))
    36.             {
    37.                 if (hit.collider.GetComponent<Bandit_Check>())
    38.                 {
    39.                     CheckCardMatch();
    40.                 }
    41.             }
    42.         }
    43.     }
    And then I just let the thing rotate around the current rotation with this script
    Code (CSharp):
    1. private void Update()
    2.     {
    3.         if(!randomRotationOn)
    4.             rotatorObject.localRotation = Quaternion.Slerp(rotatorObject.localRotation, Quaternion.Euler(currentStep * steps, 0, 0), Time.deltaTime * 15f);
    5.  
    6.         currentRotation = Quaternion.Angle(rotatorObject.localRotation, correctRotation);
    7.     }
    8.  
    9.     public IEnumerator RotateRandomly()
    10.     {
    11.         currentStep = Mathf.Floor(Random.Range(0, 360) / steps);
    12.         randomRotation = Quaternion.Euler(currentStep * steps, 0, 0);
    13.  
    14.         float timeWaiting = 5f;
    15.         while (timeWaiting > 0)
    16.         {
    17.             rotatorObject.Rotate(Vector3.right, 10f * timeWaiting);
    18.             timeWaiting -= 0.1f;
    19.             yield return rotatorObject.localRotation;
    20.         }
    21.  
    22.         while (Quaternion.Angle(rotatorObject.localRotation, randomRotation) > 5f)
    23.         {
    24.             rotatorObject.localRotation = Quaternion.Slerp(rotatorObject.localRotation, randomRotation, Time.deltaTime * 2f);
    25.             yield return rotatorObject.localRotation;
    26.         }
    27.         randomRotationOn = false;
    28.     }