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

Question Door rotation limit makes the door to flicker.

Discussion in 'Scripting' started by babaliaris, Dec 29, 2020.

  1. babaliaris

    babaliaris

    Joined:
    Apr 21, 2013
    Posts:
    34
    I created a door open/close mechanism for my game, but when the rotation of the door reaches its limits the door starts flickering.

    I know that the problem is in the reset of the rotation, once it passes a certain value, but how can I smooth it out? I tried using more precision in my float value, so the delta length between the door limit and the actual rotation value to be as minimum as possible, but I still see the flickering.

    Check the following video to see what I mean by flickering:


    In the code below you should be more interested in the //-------------Rotation Limits-------------//
    section of the code (at the bottom of the function).

    Code (CSharp):
    1. private void RotateWithMouse()
    2.     {
    3.  
    4.         //Find the static coordinate system of the door.
    5.         Transform parent = m_door.parent;
    6.  
    7.         //Calculate some dot products.
    8.         float dotBetweenCameraAndStaticDoorForward      = Vector3.Dot(transform.forward.normalized, parent.forward.normalized);
    9.         float dotBetweenCameraAndDynamicDoorForward     = Vector3.Dot(transform.forward.normalized, m_door.forward.normalized);
    10.         float dotBetweenStaticDoorAndDynamicDoorForward = Vector3.Dot(parent.forward.normalized, m_door.forward.normalized);
    11.  
    12.         //Total movement contribution Variable..
    13.         float totalMovementCotribution;
    14.  
    15.         //Left look should open the door.
    16.         if (dotBetweenCameraAndStaticDoorForward > 0)
    17.         {
    18.  
    19.             //Forward movement should open the door (player is in front of the door).
    20.             if (dotBetweenCameraAndDynamicDoorForward > 0)
    21.                 totalMovementCotribution = m_LookDelta.x - m_LookDelta.y - m_MoveDelta.y;
    22.  
    23.             //Forward movement should close the door (Player is behind the door).
    24.             else
    25.                 totalMovementCotribution = m_LookDelta.x - m_LookDelta.y + m_MoveDelta.y;
    26.         }
    27.  
    28.  
    29.         //Right look should open the door (Just invert the m_LookDelta.x)
    30.         else
    31.         {
    32.  
    33.             //Forward movement should open the door (player is in front of the door).
    34.             if (dotBetweenCameraAndDynamicDoorForward > 0)
    35.                 totalMovementCotribution = -m_LookDelta.x - m_LookDelta.y - m_MoveDelta.y;
    36.  
    37.             //Forward movement should close the door (Player is behind the door).
    38.             else
    39.                 totalMovementCotribution = -m_LookDelta.x - m_LookDelta.y + m_MoveDelta.y;
    40.         }
    41.  
    42.         //Rotate the door.
    43.         m_door.Rotate(new Vector3(0, 1, 0) * Time.deltaTime * totalMovementCotribution * RotateSensitivity);
    44.  
    45.  
    46.         //-------------Rotation Limits-------------//
    47.         if (dotBetweenStaticDoorAndDynamicDoorForward <= -0.001f)
    48.             m_door.eulerAngles = new Vector3(m_door.eulerAngles.x, 270, m_door.eulerAngles.z);
    49.  
    50.         if (m_door.rotation.eulerAngles.y >= 0.001f && m_door.rotation.eulerAngles.y <= 80.0f)
    51.             m_door.eulerAngles = new Vector3(m_door.eulerAngles.x, 0, m_door.eulerAngles.z);
    52.         //-------------Rotation Limits-------------//
    53.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Generally do not ever read from eulerAngles. The reason is they are not reliable and are only available for human reading in the editor, for the most part.

    Instead keep a single float, the angle which the door is open. If 0 is closed and 90 is open, then set up your prefabs so that you have a single Transform object that you drive the local rotation of, like so:

    Code (csharp):
    1. public Transform TheDoorHinge;
    2. float currentDoorAngle;  // angle it is now
    3. float desiredDoorAngle;  // angle we want it to be
    When the door is toggled, ONLY set the desiredDoorAngle.

    Every frame in Update(), use Mathf.MoveTowards() to move the currentDoorAngle towards desiredDoorAngle.

    And then when you set the rotation:

    Code (csharp):
    1. TheDoorHinge.localRotation = Quaternion.Euler( 0, currentDoorAngle, 0);
    This is by far the simplest way to move a single scalar value smoothly. I wrote more about it here:

    Smoothing movement between discrete values:

    https://forum.unity.com/threads/beginner-need-help-with-smoothdamp.988959/#post-6430100

    The code: https://pastebin.com/ePnwWqnM
     
    babaliaris likes this.
  3. babaliaris

    babaliaris

    Joined:
    Apr 21, 2013
    Posts:
    34
    It works thanks!
     
    Kurt-Dekker likes this.