Door rotation limit makes the door to flicker.

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).

private void RotateWithMouse()
    {

        //Find the static coordinate system of the door.
        Transform parent = m_door.parent;

        //Calculate some dot products.
        float dotBetweenCameraAndStaticDoorForward      = Vector3.Dot(transform.forward.normalized, parent.forward.normalized);
        float dotBetweenCameraAndDynamicDoorForward     = Vector3.Dot(transform.forward.normalized, m_door.forward.normalized);
        float dotBetweenStaticDoorAndDynamicDoorForward = Vector3.Dot(parent.forward.normalized, m_door.forward.normalized);

        //Total movement contribution Variable..
        float totalMovementCotribution;

        //Left look should open the door.
        if (dotBetweenCameraAndStaticDoorForward > 0)
        {

            //Forward movement should open the door (player is in front of the door).
            if (dotBetweenCameraAndDynamicDoorForward > 0)
                totalMovementCotribution = m_LookDelta.x - m_LookDelta.y - m_MoveDelta.y;

            //Forward movement should close the door (Player is behind the door).
            else
                totalMovementCotribution = m_LookDelta.x - m_LookDelta.y + m_MoveDelta.y;
        }


        //Right look should open the door (Just invert the m_LookDelta.x)
        else
        {

            //Forward movement should open the door (player is in front of the door).
            if (dotBetweenCameraAndDynamicDoorForward > 0)
                totalMovementCotribution = -m_LookDelta.x - m_LookDelta.y - m_MoveDelta.y;

            //Forward movement should close the door (Player is behind the door).
            else
                totalMovementCotribution = -m_LookDelta.x - m_LookDelta.y + m_MoveDelta.y;
        }

        //Rotate the door.
        m_door.Rotate(new Vector3(0, 1, 0) * Time.deltaTime * totalMovementCotribution * RotateSensitivity);


        //-------------Rotation Limits-------------//
        if (dotBetweenStaticDoorAndDynamicDoorForward <= -0.001f)
            m_door.eulerAngles = new Vector3(m_door.eulerAngles.x, 270, m_door.eulerAngles.z);

        if (m_door.rotation.eulerAngles.y >= 0.001f && m_door.rotation.eulerAngles.y <= 80.0f)
            m_door.eulerAngles = new Vector3(m_door.eulerAngles.x, 0, m_door.eulerAngles.z);
        //-------------Rotation Limits-------------//
    }

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:

public Transform TheDoorHinge;
float currentDoorAngle;  // angle it is now
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:

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:

The code: Smooth movement - Pastebin.com

1 Like

It works thanks!

1 Like