void LateUpdate()
    {
        Vector3 characterOffset = followXForm.position + height_offset; //distance from char follow transform + some height

        //determine cam state
        if (Input.GetAxis("Target") > 0.01)
        {
            camState = CamStates.TARGET;
        }
        else
        {
            camState = CamStates.BEHIND;
        }

        switch (camState)
        {
        //case CamStates.BEHIND:
        //    calc dir from camera to player, kill y and normalize to give a valid direction with unit magnitude
        //    lookDir = characterOffset - this.transform.position;
        //    lookDir.y = 0; //kill y val
        //    lookDir.Normalize();

        //    targetPosition = characterOffset - lookDir * distanceAway;
        //    break;

        case CamStates.BEHIND:

            if (char_logic.speed > char_logic.LocomotionThreshold && char_logic.isInLocomotion() && !char_logic.isInPivot())
            {
                //http://chortle.ccsu.edu/vectorlessons/vch09/vch09_6.html the range of the dot product of 2 unit vector is between 0 and 1
                lookDir = Vector3.Lerp(followXForm.right * (horizontal == 0 ? 0 : -Mathf.Sign(horizontal)), followXForm.forward * (vertical == 0 ? 0 : Mathf.Sign(vertical)), Mathf.Abs(Vector3.Dot(this.transform.forward, followXForm.forward)));

                // Calculate direction from camera to player, kill Y, and normalize to give a valid direction with unit magnitude
                curr_lookDir   = Vector3.Normalize(characterOffset - this.transform.position);
                curr_lookDir.y = 0;

                // Damping makes it so we don't update targetPosition while pivoting; camera shouldn't rotate around player
                curr_lookDir = Vector3.SmoothDamp(curr_lookDir, lookDir, ref lookDirVelocity, lookDirDampTime);
            }

            targetPosition = characterOffset + followXForm.up * distanceUp - Vector3.Normalize(curr_lookDir) * distanceAway;

            break;


        case CamStates.TARGET:

            //calc dir from camera to player, kill y and normalize to give a valid direction with unit magnitude
            lookDir   = followXForm.forward;
            lookDir.y = 0;     //kill y val
            lookDir.Normalize();

            targetPosition = characterOffset - lookDir * distanceAway;

            break;
        }

        //do regardless of state
        //compensateForWalls(characterOffset, ref targetPosition);
        smoothPosition(transform.position, targetPosition);//smooth
        //make sure cam faces character
        transform.LookAt(followXForm);
    }