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. Dismiss Notice

Coroutine stop criterion as rotation matching

Discussion in 'Scripting' started by mehmet_ali_duran, May 4, 2021.

  1. mehmet_ali_duran

    mehmet_ali_duran

    Joined:
    Mar 2, 2020
    Posts:
    6
    I am trying to rotate my gameobject and its children to match the rotation of another object with its children by coroutine. However, when I use "==" as equality comparer for rotations, the gameobject rotates more than the reference gameobject's rotation ( at least visually, this is the case). I use Quaternion for rotations not Euler angles, but the my aim is to match the rotation as it is declared in the Transform component in the Editor. So, they will be same as rotation-wise.

    P.s: My gameobject and the reference gameobject have the same hiearchical order with children etc., only rotations are different.

    My code is as follows:


    Code (CSharp):
    1. private IEnumerator MatchRotation(int i)
    2.     {
    3.        
    4.         while (_myGameObject[i].rotation != refGameObject[i].rotation)
    5.         {
    6.             _myGameObject[i].rotation = Quaternion.RotateTowards(
    7.                 _myGameObject[i].rotation, refGameObject[i].rotation,
    8.                 _rotationSpeed * Time.deltaTime);
    9.            
    10.             yield return null;
    11.         }
    12.  
    13.         isFoldingCompleted = true;
    14.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    You cannot compare floating point (or floating point vectors like Quaternions) for equality, due to floating point imprecision.

    One approach is to track your own floating point angle of rotation:

    Notes on clamping camera rotation and NOT using .eulerAngles because of gimbal lock:

    https://forum.unity.com/threads/implement-a-limit-in-camera-movement.1100038/#post-7083097

    You still CANNOT compare for equality, but with a scalar you can compare greater-than or less-than (based on which way you know it is moving) and stop then.
     
  3. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,904
    I've found that == and != happen to work fine for MoveTowards, and probably for RotateTowards. When the movement would go past the target it's set exactly, perfectly equal. Now, quaternions are a "double-cover", so maybe you reach -270 which counts as 90 but isn't == to it. Maybe. But then it would work 1/2 the time. The other thing, if a broken == was the problem it would wiggle back-and-forth around the target rotation, never saying it was done folding (which maybe it does?)

    Could test by changing to the safer-looking
    while(Quaternion.Angle(currentSpin, targetSpin)<0.5f)
    . I suspect it merely looks different -- maybe the objects are themselves bent, etc... . Looking at Inspector values would confirm that.