Platforms that rotate when they reach a certain angle

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.

_Timer += Time.deltaTime;


        if (_Timer > _setTime)

        {
            _rigidbody.MoveRotation(Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, _DesiredRotation), _rotationSpeed * Time.fixedDeltaTime));

            if (CompareValue(transform.rotation.eulerAngles.z, _DesiredRotation))

            {
                _DesiredRotation = (_DesiredRotation + 90f) % 360;
                _Timer = 0;
            }
        }

Compare Value is a method that I created because Mathf.Approximate was too precise when comparing the values

private bool CompareValue(float Rotation , float DesiredRotation)
    {
        return Math.Abs(Rotation - DesiredRotation) < 0.001f;
    }

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.

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:

Quaternion axisRotation = Quaternion.AngleAxis(90f, Vector3.up);
_desiredRotation = axisRotation * transform.rotation; // multiply quaternions to combine them

And then just use Quaternion.RotateTowards, and check the angle afterwards:

float delta = _rotationSpeed * Time.deltaTime;
Quaternion moveRotation = Quaternion.RotateTowards(transform.rotation, _desiredRotation, delta);
_rigidbody.MoveRotation(moveRotation);

float angle = Quaternion.Angle(transform.rotation, _desiredRotation)
if (angle < Mathf.epsilon)
{
   Quaternion axisRotation = Quaternion.AngleAxis(90f, Vector3.up);
   _desiredRotation = axisRotation * _desiredRotation;
}

Quaternion.RotateTowards won’t overshoot, so comparing if it’s smaller than epsilon should be good, otherwise use a slightly bigger constant value.

1 Like

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.

1 Like