Issue with zoom / positioning of camera?

So I’m trying to fix my camera script & my zoom works but only if I’m not holding down left click. Also, it zooms real close when holding down left click which it shouldn’t do & the camera goes in front of the player when holding left click instead of staying where it originally started. I don’t understand why it’s doing this. here’s pretty much the full code :

using UnityEngine;

public class CameraController : MonoBehaviour {

    // Calculate Zoom

    private float CalculateZoom ( ) {
        // Calculate the desired distance for `mouse wheel`
        desiredDistance -= Input.GetAxis ( "Mouse ScrollWheel" ) * Time.deltaTime * zoomRate * Mathf.Abs ( desiredDistance );
        desiredDistance = Mathf.Clamp ( desiredDistance, zoomMindistance, zoomMaxdistance );
        return desiredDistance;
    }

    void LateUpdate ( ) {

        if ( target != null ) {

            // If left mouse button is down, let the mouse
            // take over camera position

            Vector2 mouseInput = new Vector2 (
                Input.GetAxis ( "Mouse Y" ), Input.GetAxis ( "Mouse X" )
            );

            if ( invertXAxis || invertBothAxes ) { mouseInput.x *= -1.0f; }
            if ( invertYAxis || invertBothAxes ) { mouseInput.y *= -1.0f; }

            xDeg = ClampAngle (
                xDeg + mouseInput.x * sensitivityX, xMinPitch, xMaxPitch
            );

            yDeg += mouseInput.y * sensitivityY;

            Quaternion rotation = Quaternion.Slerp (
                transform.rotation, Quaternion.Euler ( xDeg, yDeg, 0.0f ),
                damper * Time.deltaTime
            );

            rotation = Quaternion.LookRotation (
                rotation * Vector3.forward
            );

            Vector3 position = target.position - ( rotation * Vector3.forward * desiredDistance + vTargetOffset );

            // Check for collision using the true target's desired registration
            // point as set by user using height

            RaycastHit collisionHit;

            Vector3 trueTargetPosition = new Vector3 ( target.position.x,  target.position.y + targetHeight, target.position.z );

            // If there was a collision, correct the camera position & calculate
            // the corrected distance

            bool isCorrected = false;

            if ( Physics.Linecast ( trueTargetPosition, position, out collisionHit, collisionLayers.value ) ) {

                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 standard limits

            currentDistance = Mathf.Clamp ( currentDistance, zoomMindistance, zoomMaxdistance );

            // Recalculate position based on the new currentDistance

            position = target.position - ( rotation * Vector3.forward * currentDistance + vTargetOffset );

            if ( activateSpringLook == true ) {

                if ( ! Input.GetMouseButton ( 0 ) && ! Input.GetMouseButtonUp ( 0 ) ) {
                    xDeg = startRotationX;
                    yDeg = startRotationY;
                }

                // Set the `position`'s transform to the `recalculated`
                // `position`

                transform.position = position;
                transform.rotation = rotation;

            }

            if ( activateSpringLook == false ) {

                // Set the `position`'s transform to the `recalculated`
                // `position`

                transform.position = position;
                transform.rotation = rotation;

            }

            float tempSidewaysMovement = Input.GetAxis ( "Horizontal" );
            float tempForwardAndBackwardsMovement = Input.GetAxis ( "Vertical" );

            if ( ! Input.GetMouseButton ( 0 ) ) {
                if ( tempSidewaysMovement >= -1.0f &&
                        tempSidewaysMovement <= 1.0f &&
                        tempForwardAndBackwardsMovement >= -1.0f &&
                        tempForwardAndBackwardsMovement <= 1.0f
                ) {
                    transform.position = target.position + Vector3.Slerp (
                        fromOffset, toOffset, damper * Time.deltaTime
                    );
                    transform.LookAt ( target );
                }
            }

            if ( activateZoom ) {

                targetForward = target.forward;
                fromOffset = transform.position - target.position;

                // Calculate `Zoom` for `camera`
                distance = CalculateZoom ( );

                toOffset = targetForward * distance;
                if ( targetHeight > 0.0f ) {
                    toOffset.y = targetHeight;
                }

            }

        }

    }

}

Any help is GREATLY appreciated!

Much thanks!

I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

I did. and all the numbers seem fine.

Can someone help? I have put most exposed code into its’ own neat little functions… Also, for some reason when trying to put camera collision into a function, the collision stopped working so i left the collision code exposed. The rest is in functions :

public class CameraController : MonoBehaviour {

    private Camera cam;
    private bool targetMsg = false;
    private bool pitchMsg = false;
    private bool progErrMsg = false;

    public Transform target;
    public float targetHeight = 1.70f;

    private Vector3 toOffset;
    private Vector3 fromOffset;
    private Vector3 targetForward;
    private float rotation;

    public bool activateZoom = false;               // Allows / disallows Camera to zoom with
                                                    // middle mouse wheel
                                                    // Defaults to true

    public bool activateSpringLook = true;          // Allows / disallows Camera to smoothly rotate / position
                                                    // back to default position / rotation
                                                    // Defaults to true

    public bool invertXAxis = false;
    public bool invertYAxis = false;

    public bool invertBothAxes = false;             // Which camera rotation mode to use
                                                    // Mode `false` :: {
                                                        // Looks `down` when moving `mouse` `up` ...
                                                        // Looks `left` when looking `right` ...
                                                    // }
                                                    // Mode `true` :: {
                                                        // Looks `up` when moving `mouse` `down` ...
                                                        // Looks `right` when looking `left` ...
                                                    // }
                                                    // Defaults to `Mode` `false`

    public LayerMask collisionLayers = -1;
    public float offsetFromWall = 0.1f;

    public float sensitivityX = 10.0f;              // The `X` `speed` `sensitivity` of the `mouse` in which the camera
                                                    // rotates in units
    public float sensitivityY = 8.0f;               // The `Y` `speed` `sensitivity` of the `mouse` in which the camera
                                                    // rotates in units

    public float xVelocity = 200.0f;                // The `X` `speed` in which the camera rotates in units
    public float yVelocity = 200.0f;                // The `Y` `speed` in which the camera rotates in units

    public float distance = 5.0f;

    public float zoomMindistance = 0.6f;
    public float zoomMaxdistance = 20.0f;

    private float xMinPitchCap = -30.0f;            // Default cap that `xMinPitch` is allowed to
                                                    // go to
    private float xMaxPitchCap = 360.0f;            // Default cap that `xMaxPitch` is allowed to
                                                    // go to

    public float xMinPitch = -30.0f;                // The `minimum` allowed range in which to rotate the camera
                                                    // on the `X` axis

    public float xMaxPitch = 80.0f;                 // The `maximum` allowed range in which to rotate the camera
                                                    // on the `X` axis

    public float yMinYaw = -180.0f;                 // The `minimum` allowed range in which to rotate the camera
                                                    // on the `Y` axis

    public float yMaxYaw = 180.0f;                  // The `maximum` allowed range in which to rotate the camera
                                                    // on the `Y` axis

    public float zoomRate = 40.0f;
    public float zoomDampening = 5.0f;

    public float smoothTime = 1f;                   // The `time` it takes for the `camera` to `smoothly` `rotate`
                                                    // to its' new rotation
    public float rotationDampening = 3.0f;
    public float damper = 5.0f;                     // The `minimum` allowed `damper` for
                                                    // `smoothing` camera speed

    private float xDeg = 0.0f;
    private float yDeg = 0.0f;

    private float currentDistance;
    private float desiredDistance;
    private float correctedDistance;

    private float startRotationX = 0.0f;            // Default `X` rotation when mouse button is
                                                    // not held
    private float startRotationY = 0.0f;            // Default `Y` rotation when mouse button is
                                                    // not held

    private void ActivateMouseRotation ( ) {

        Vector2 mouseInput = new Vector2 (
            Input.GetAxis ( "Mouse Y" ), Input.GetAxis ( "Mouse X" )
        );

        if ( invertXAxis || invertBothAxes ) { mouseInput.x *= -1.0f; }
        if ( invertYAxis || invertBothAxes ) { mouseInput.y *= -1.0f; }

        xDeg = ClampAngle (
            xDeg + mouseInput.x * sensitivityX, xMinPitch, xMaxPitch
        );

        yDeg += mouseInput.y * sensitivityY;

    }

    private void Activate_SpringLook ( bool activateSpringLook, Vector3 position, Quaternion rotation ) {

        if ( activateSpringLook == true ) {

            if ( ! Input.GetMouseButton ( 0 ) && ! Input.GetMouseButtonUp ( 0 ) ) {
                xDeg = startRotationX;
                yDeg = startRotationY;
            }

            // Set the `position`'s transform to the `recalculated`
            // `position`

            transform.position = position;
            transform.rotation = rotation;

        }

        if ( activateSpringLook == false ) {

            // Set the `position`'s transform to the `recalculated`
            // `position`

            transform.position = position;
            transform.rotation = rotation;

        }

    }

    private void ControlCamera ( ) {

        if ( ! Input.GetMouseButton ( 0 ) ) {

            float tempSidewaysMovement = Input.GetAxis ( "Horizontal" );
            float tempForwardAndBackwardsMovement = Input.GetAxis ( "Vertical" );

            if ( tempSidewaysMovement >= -1.0f &&
                    tempSidewaysMovement <= 1.0f &&
                    tempForwardAndBackwardsMovement >= -1.0f &&
                    tempForwardAndBackwardsMovement <= 1.0f
            ) {
                transform.position = target.position + Vector3.Slerp (
                    fromOffset, toOffset, damper * Time.deltaTime
                );
                transform.LookAt ( target );
            }

        }

    }

    private float ZoomCamera ( bool activateZoom ) {

        if ( activateZoom ) {

            targetForward = target.forward;
            fromOffset = transform.position - target.position;

            // Calculate `Zoom` for `camera`
            distance = CalculateZoom ( );

            toOffset = targetForward * distance;
            if ( targetHeight > 0.0f ) {
                toOffset.y = targetHeight;
            }

        }

        return distance;

    }

    void LateUpdate ( ) {

        if ( target != null ) {

            ActivateMouseRotation ( );

            Quaternion rotation = Quaternion.Slerp (
                transform.rotation, Quaternion.Euler ( xDeg, yDeg, 0.0f ),
                damper * Time.deltaTime
            );

            rotation = Quaternion.LookRotation (
                rotation * Vector3.forward
            );

            Vector3 position = target.position - ( rotation * Vector3.forward * desiredDistance + vTargetOffset );

            // Check for collision using the true target's desired registration
            // point as set by user using height
  
            RaycastHit collisionHit;
  
            Vector3 trueTargetPosition = new Vector3 ( target.position.x,  target.position.y + targetHeight, target.position.z );

            // If there was a collision, correct the camera position & calculate
            // the corrected distance

            bool isCorrected = false;
  
            if ( Physics.Linecast ( trueTargetPosition, position, out collisionHit, collisionLayers.value ) ) {

                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 standard limits
  
            currentDistance = Mathf.Clamp ( currentDistance, zoomMindistance, zoomMaxdistance );

            // Recalculate position based on the new currentDistance
  
            position = target.position - ( rotation * Vector3.forward * currentDistance + vTargetOffset );

            Activate_SpringLook ( activateSpringLook, position, rotation );

            ControlCamera ( );
            distance = ZoomCamera ( activateZoom );

        }

    }

}