Clamp angle to rotate a canvas with my camera

Hi everyone !

I want to rotate a canvas with my camera when i turn my head.
I don’t want my canvas to rotate when my camera is pointing in its direction.
The canvas should rotate around me when i try to leave it’s direction. So that the canvas follow my eyes.

Here a video of what I did :

As you can see, it works most of the time. Excepted when my rotation goes from 0 to 360.

Here is my code :

[SerializeField] private Transform _Camera, _Canvas, _LeftPoint, _RightPoint, _CenterPoint;

private float _CanvasY, _CameraY, _LeftBuffer, _RightBuffer;

void Start () {
    _LeftBuffer = Vector3.Angle( ( _CenterPoint.position - _Camera.position ), ( _LeftPoint.position - _Camera.position ) );
    _RightBuffer = Vector3.Angle( ( _CenterPoint.position - _Camera.position ), ( _RightPoint.position - _Camera.position ) );
}

void Update () {
    RotateCamera ();

    _CameraY = _Camera.rotation.eulerAngles.y;

    float min = _CameraY - _RightBuffer;
    float max = _CameraY + _LeftBuffer;

    _CanvasY = Mathf.Clamp(_CanvasY, min, max);

    _Canvas.rotation = Quaternion.Euler(_Canvas.transform.eulerAngles.x, _CanvasY, _Canvas.transform.eulerAngles.z );
}

I can’t figure out was is going on…

_CenterPoint is a point at the center of my canvas, _LeftPoint and _RightPoint are on the left and right of my canvas.

Thanks for your help !

I did it this way :

[SerializeField] private Transform _Camera, _Canvas, _LeftPoint, _RightPoint, _CenterPoint;

private float _CanvasY, _CameraY, _LeftBuffer, _RightBuffer;

Quaternion _OldCameraRotation;

void Start () {
    _OldCameraRotation = _Camera.rotation;
    _LeftBuffer = Vector3.Angle( ( _CenterPoint.position - _Camera.position ), ( _LeftPoint.position - _Camera.position ) );
    _RightBuffer = Vector3.Angle( ( _CenterPoint.position - _Camera.position ), ( _RightPoint.position - _Camera.position ) );
}

void LateUpdate () {
    _CameraY += EulerAnglesBetween (_OldCameraRotation, _Camera.rotation).y;
    _OldCameraRotation = _Camera.rotation;

    float min = _CameraY - _RightBuffer;
    float max = _CameraY + _LeftBuffer;

    _CanvasY = Mathf.Clamp(_CanvasY, min, max);

    _Canvas.rotation = Quaternion.Euler(_Canvas.transform.eulerAngles.x, _CanvasY, _Canvas.transform.eulerAngles.z );
}

private Vector3 EulerAnglesBetween(Quaternion from, Quaternion to) {
    Vector3 delta = to.eulerAngles - from.eulerAngles;

    if (delta.x > 180)
        delta.x -= 360;
    else if (delta.x < -180)
        delta.x += 360;

    if (delta.y > 180)
        delta.y -= 360;
    else if (delta.y < -180)
        delta.y += 360;

    if (delta.z > 180)
        delta.z -= 360;
    else if (delta.z < -180)
        delta.z += 360;
       
    return delta;
}