Following an aircraft with a camera

I’ve got a camera following an aircraft. The player can use the right mouse button to move the camera around the aircraft, and if the right mouse button is released the camera rotates back to its original position behind the aircraft. My camera script works fine except for two issues.

1, when the aircraft is banked at an odd angle the camera seems to follow world coordinates instead of local coordinates.
2, when doing a roll in the aircraft the camera seems to spiral around the rear of the aircraft instead of staying locked in a position relative to the rear of the aircraft. What I mean by this is that instead of the camera making the aircraft stay at a fixed position on the screen as I’m rolling it, the aircraft does a sort of circle around the screen due to the camera movement. Normally the aircraft would be in the center of the screen, but suddenly it’s at the top of the screen, then the right, then the bottom, then the left, etc. Using a static camera with no script on it as a child of the aircraft I get the exact camera results I want from rolling the aircraft - but I can’t do that since the player needs to be able to rotate the camera to look around.

Anyone have any suggestions on how I could fix these two issues?

//Quinn's Aerial Camera Controller v1.0

//The character or player-object must be tagged "Player"

//For target/distance
public var target : GameObject;                       //Target to follow
public var targetHeight : float = 1.7;                //Vertical offset adjustment
public var distance : float = 12;                     //Default distance of the camera from the target
public var lockToRearOfTarget : boolean = true;        //Lock camera to rear of the target
//For camera collisions
public var offsetFromWall : float = 2;                //Bring camera away from any colliding objects
public var collisionLayers : LayerMask = -1;          //What the camera will collide with
//For zooming
public var maxDistance : float = 20;                  //Maximum zoom Distance
public var minDistance : float = 0.6;                 //Minimum zoom Distance
public var zoomRate : float = 40;                     //Zoom Speed
public var zoomDampening : float = 5;                 //Auto Zoom speed (Higher = faster)
//For orbiting
public var xSpeed : float = 200;                      //Orbit speed (Left/Right)
public var ySpeed : float = 200;                      //Orbit speed (Up/Down)
//For looking up/down
public var yMinLimit : float = -90;                   //Looking up limit
public var yMaxLimit : float = 90;                    //Looking down limit
//For rotation
public var rotationDampening : float = 3;             //Auto Rotation speed (higher = faster)
//For player control
public var allowMouseInputX : boolean = true;         //Allow player to control camera angle on the x axis (Left/Right)
public var allowMouseInputY : boolean = true;         //Allow player to control camera angle on the y axis (Up/Down)
//Internal variables
private var xDeg : float = 0;                         //The camera position on the x axis
private var yDeg : float = 0;                         //The camera position on the y axis
private var zDeg : float = 0;                        //The camera position on the z axis
private var currentDistance : float;                  //The current distance of the camera from the target
private var desiredDistance : float;                  //The desired distance of the camera from the target
private var correctedDistance : float;                //Used to correct the distance of the camera from the target until desired distance is reached
private var rotateBehind : boolean = false;           //Allow or disallow the mouse to control the camera.  If false and lockToRearOfTarget is true the camera will rotate behind the target

//****************************************************************************************************//
//*******************************************START FUNCTION*******************************************//
//****************************************************************************************************//

function Start () {

    var angles : Vector3 = transform.eulerAngles;
   
    xDeg = angles.x;
    yDeg = angles.y;
    zDeg = angles.z;
   
    currentDistance = distance;
    desiredDistance = distance;
    correctedDistance = distance;
   
    //Make the rigid body not change rotation
    if (rigidbody) {
        rigidbody.freezeRotation = true;
    }
   
    //If lockToRearofTarget is set to true then rotateBehind is also true
    if (lockToRearOfTarget) {
        rotateBehind = true;
    }

}

//*****************************************************************************************************//
//*******************************************UPDATE FUNCTION*******************************************//
//*****************************************************************************************************//

function Update() {

    //If there is no target defined, search for the gameObject with the "Player" tag
    if (target == null) {
        target = GameObject.FindGameObjectWithTag("Player") as GameObject;
    }

}

//******************************************************************************************************//
//*****************************************LATE UPDATE FUNCTION*****************************************//
//******************************************************************************************************//

//Only Move camera after everything else has been updated
function LateUpdate () {

    //Don't do anything if target is not defined
    if (target == null) {
        return;
    }
  
    var vTargetOffset : Vector3;
              
    //If the right mouse button is down, let the mouse govern camera position
    if (GUIUtility.hotControl == 0) {
   
        if (Input.GetMouseButton(1)) {
       
            //Check to see if mouse input is allowed on the axis
            if (allowMouseInputX) {
                xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02;
            }
            else {
                RotateBehindTarget();
            }
            if (allowMouseInputY) {
                yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02;
            }
            //Interrupt rotating behind if mouse wants to control rotation
            if (!lockToRearOfTarget) {
                rotateBehind = false;
            }
       
        }
       
        //Otherwise, ease behind the target if any of the directional keys are pressed
        else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0 || rotateBehind) {
            RotateBehindTarget();
        }
   
    }
   
    //yDeg = ClampAngle (yDeg, yMinLimit, yMaxLimit);
    //Set camera rotation
    var rotation : Quaternion = Quaternion.Euler (yDeg, xDeg, zDeg);
    //Calculate the desired distance
    desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs (desiredDistance);
    desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
    correctedDistance = desiredDistance;
    //Calculate desired camera position
    vTargetOffset = new Vector3 (0, -targetHeight, 0);
    var position : Vector3 = target.transform.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset);
    //Check for collision using the true target's desired registration point as set by user using height
    var collisionHit : RaycastHit;
    var trueTargetPosition : Vector3 = new Vector3 (target.transform.position.x, target.transform.position.y + targetHeight, target.transform.position.z);
    //If there was a collision, correct the camera position and calculate the corrected distance
    var isCorrected : boolean = false;
    if (Physics.Linecast (trueTargetPosition, position, collisionHit, collisionLayers)) {
        //Calculate the distance from the original estimated position to the collision location,
        //subtracting out a safety "offset" distance from the object we hit.  The offset will help
        //keep the camera from being right on top of the surface we hit, which usually shows up as
        //the surface geometry getting partially clipped by the camera's front clipping plane.
        correctedDistance = Vector3.Distance (trueTargetPosition, collisionHit.point) - offsetFromWall;
        isCorrected = true;
    }
    //For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
    currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp (currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
    //Keep within limits
    currentDistance = Mathf.Clamp (currentDistance, minDistance, maxDistance);
    //Recalculate position based on the new currentDistance
    position = target.transform.position - (rotation * Vector3.forward * currentDistance + vTargetOffset);
  
    //Finally set rotation and position of camera
    transform.rotation = rotation;
    transform.position = position;

}

//*****************************************************************************************************//
//************************************ROTATE BEHIND TARGET FUNCTION************************************//
//*****************************************************************************************************//

function RotateBehindTarget() {

    //Rotate on the Y axis
    var targetRotationAngle : float = target.transform.eulerAngles.y;
    var currentRotationAngle : float = transform.eulerAngles.y;
   
    xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
   
    //Stop rotating behind if not completed
    if (targetRotationAngle == currentRotationAngle) {
        if (!lockToRearOfTarget)
            rotateBehind = false;
    }
    else {
        rotateBehind = true;
    }
   
    //Rotate on the X axis
    var targetRotationAngleX : float = target.transform.eulerAngles.x;
    var currentRotationAngleX : float = transform.eulerAngles.x;
   
    yDeg = Mathf.LerpAngle (currentRotationAngleX, targetRotationAngleX, rotationDampening * Time.deltaTime);
   
    //Stop rotating behind if not completed
    if (targetRotationAngleX == currentRotationAngleX) {
        if (!lockToRearOfTarget)
            rotateBehind = false;
    }
    else {
        rotateBehind = true;
    }
   
    //Rotate on the Z axis
    var targetRotationAngleZ : float = target.transform.eulerAngles.z;
    var currentRotationAngleZ : float = transform.eulerAngles.z;
   
    zDeg = Mathf.LerpAngle (currentRotationAngleZ, targetRotationAngleZ, rotationDampening * Time.deltaTime);
   
    //Stop rotating behind if not completed
    if (targetRotationAngleZ == currentRotationAngleZ) {
        if (!lockToRearOfTarget)
            rotateBehind = false;
    }
    else {
        rotateBehind = true;
    }

}

//******************************************************************************************************//
//*****************************************CLAMP ANGLE FUNCTION*****************************************//
//******************************************************************************************************//

function ClampAngle(angle:float, min:float, max:float) {

    if (angle < -360) {
        angle += 360;
    }
    if (angle > 360) {
        angle -= 360;
    }
   
    return Mathf.Clamp (angle, min, max);

}

I would create a script that simply places a transform, postion, at the positon of the aircraft. Then in that transform, place the camera, and adjust its position appropriately. Now, the camera, nested in its parent, will follow the plane, ignoring any spin. If you want to rotate the camera around the plane, simply apply rotation to the parent.

Unity did something like this in the sample assets beta.
Maybe looking at that could help you out.