Problem with my leaning script

I have a code that tilts my camera left or right when you hold q or e. Here’s the script…

 #pragma strict
var leanAngle : float = 35.0;
var leanSpeed : float = 5.0;
var leanBackSpeed : float = 6.0;
function Update ()
{
     if (Input.GetKey("q")) {
        LeanLeft();
     }
    
     else if (Input.GetKey("e")) {
        LeanRight();
     }
    
     else
     {
         LeanBack();
     }
}
function LeanLeft()
{
     // current Z-rotation
     var currAngle : float = transform.rotation.eulerAngles.z;
     //var rot : Quaternion = transform.rotation;
    
     // target Z-rotation
     var targetAngle : float = leanAngle;
    
     if ( currAngle > 180.0 )
     {
         //targetAngle = 0.0 - leanAngle;
         currAngle = 360 - currAngle;
     }
    
     //lerp value from current to target
     var angle : float = Mathf.Lerp( currAngle, targetAngle, leanSpeed * Time.deltaTime );
    
     //Debug.Log ( "Left : currAngle " + currAngle + " : targetAngle " + targetAngle + " : angle " + angle );
    
     // rotate char
     var rotAngle : Quaternion = Quaternion.Euler( transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, angle );
     transform.rotation = rotAngle;
}
function LeanRight()
{
     // current Z-rotation
     var currAngle : float = transform.rotation.eulerAngles.z;
    
     // target Z-rotation
     var targetAngle : float = leanAngle - 360.0;
    
     if ( currAngle > 180.0 )
     {
         targetAngle = 360.0 - leanAngle;
     }
    
     //lerp value from current to target
     var angle : float = Mathf.Lerp( currAngle, targetAngle, leanSpeed * Time.deltaTime );
    
     //Debug.Log ( "Right : currAngle " + currAngle + " : targetAngle " + targetAngle + " : angle " + angle );
    
     // rotate char
     var rotAngle : Quaternion = Quaternion.Euler( transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, angle );
     transform.rotation = rotAngle;
    
}
function LeanBack()
{
     // current Z-rotation
     var currAngle : float = transform.rotation.eulerAngles.z;
    
     // target Z-rotation
     var targetAngle : float = 0.0;
    
     if ( currAngle > 180.0 )
     {
         targetAngle = 360.0;
     }
    
     //lerp value from current to target
     var angle : float = Mathf.Lerp( currAngle, targetAngle, leanBackSpeed * Time.deltaTime );
    
     //Debug.Log ( "Center : currAngle " + currAngle + " : targetAngle " + targetAngle + " : angle " + angle );
    
     var rotAngle : Quaternion = Quaternion.Euler( transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, angle );
     transform.rotation = rotAngle;
}

But for some reason, after leaning left and then leaning right, the camera really just jumps to the right. I could I fix this?

Using Euler angles this way is begging for trouble. Converting a quaternion to Euler angles, in particular, is troublesome. As an exercise, create two GameObjects. Set one to (0,0,90), and the other to (-180,180,-90). See how they’re exactly the same? Now, put yourself in the shoes of the Quaternion class. You know that this Quaternion represents this particular rotation (e.g. what you can see in the Scene View), but you don’t know what numbers the user typed into the inspector. When asked to give your Euler value, which one would you give? What makes one any better than the other? There are probably a near-infinite number of sets of identical rotations given by different Euler angles.

So in line 41, when you say transform.rotation.eulerAngles.x, that value cannot be relied upon unless you confirm what y and z are as well. In our example, it could be 0 or -180 and both are 100% valid.

Use the other methods of rotation instead. For example,

transform.rotation = transform.rotation * Quaternion.AngleAxis(angleDiff, transform.forward);

If you really want to use Euler angles (which is fair enough), do what the Unity editor does: Track your rotation’s Euler angles as a Vector3 and just completely overwrite transform.rotation every frame.