Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Platforms that rotate when they reach a certain angle

Discussion in 'Scripting' started by JialeHe28, Mar 25, 2023.

  1. JialeHe28

    JialeHe28

    Joined:
    Sep 16, 2022
    Posts:
    9
    I've been trying to create rotating platforms for quite a while and my biggest issue right now is the comparison between my target rotation and current rotation.
    Code (CSharp):
    1. _Timer += Time.deltaTime;
    2.  
    3.  
    4.         if (_Timer > _setTime)
    5.  
    6.         {
    7.             _rigidbody.MoveRotation(Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, _DesiredRotation), _rotationSpeed * Time.fixedDeltaTime));
    8.  
    9.             if (CompareValue(transform.rotation.eulerAngles.z, _DesiredRotation))
    10.  
    11.             {
    12.                 _DesiredRotation = (_DesiredRotation + 90f) % 360;
    13.                 _Timer = 0;
    14.             }
    15.         }
    Compare Value is a method that I created because Mathf.Approximate was too precise when comparing the values

    Code (CSharp):
    1. private bool CompareValue(float Rotation , float DesiredRotation)
    2.     {
    3.         return Math.Abs(Rotation - DesiredRotation) < 0.001f;
    4.     }
    For some reason every so often, when the platform rotatates, the difference in value is bigger than the minimum threshold of CompareValue. I feel that increasing the minimum threshold wouldn't really resolve the problem but rather be a band-aid solution and I want to find a more definitive solution to this.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,610
    I'd avoid using euler angles, as they have a number of gotchas that make them harder to deal with them just getting the hang of using quaternions.

    In this case it'd probably be easier to just use the angle between rotations, though you'd need a rotation in the first place to do that.

    If you want to 'rotate on z axis' by 90 degrees, when you can use
    Quaternion.AngleAxis
    to make a rotation, and combine that with the object's existing rotation:
    Code (CSharp):
    1. Quaternion axisRotation = Quaternion.AngleAxis(90f, Vector3.up);
    2. _desiredRotation = axisRotation * transform.rotation; // multiply quaternions to combine them
    And then just use
    Quaternion.RotateTowards
    , and check the angle afterwards:
    Code (CSharp):
    1. float delta = _rotationSpeed * Time.deltaTime;
    2. Quaternion moveRotation = Quaternion.RotateTowards(transform.rotation, _desiredRotation, delta);
    3. _rigidbody.MoveRotation(moveRotation);
    4.  
    5. float angle = Quaternion.Angle(transform.rotation, _desiredRotation)
    6. if (angle < Mathf.epsilon)
    7. {
    8.    Quaternion axisRotation = Quaternion.AngleAxis(90f, Vector3.up);
    9.    _desiredRotation = axisRotation * _desiredRotation;
    10. }
    11.  
    Quaternion.RotateTowards won't overshoot, so comparing if it's smaller than epsilon should be good, otherwise use a slightly bigger constant value.
     
    JialeHe28 likes this.
  3. JialeHe28

    JialeHe28

    Joined:
    Sep 16, 2022
    Posts:
    9
    It works wonderfully thanks! I should have specified that my project was in 2D because the code didn't work until I changed it to Vector3.Forward rather than up but THANK YOU.
     
    spiney199 likes this.