How can I optimize this code? [Solved]

I started out with 80 fps, now I dropped to about 70 - 75. So I need help optimizing this script, I also checked the profiler, and it seems to be coming from the raycast bit.

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class CameraRig : MonoBehaviour
{
    public Transform target;
    public bool autoTargetPlayer;
    public LayerMask wallLayers;

    public enum Shoulder
    {
        Right, Left
    }
    public Shoulder shoulder;

    [System.Serializable]
    public class CameraSettings
    {
        [Header("-Positioning-")]
        public Vector3 camPositionOffsetLeft;
        public Vector3 camPositionOffsetRight;

        [Header("-Camera Options-")]
        public float mouseXSensitivity = 5.0f;
        public float mouseYSensitivity = 5.0f;
        public float minAngle = -30.0f;
        public float maxAngle = 70.0f;
        public float rotationSpeed = 5.0f;
        public float maxCheckDist = 0.1f;

        [Header("-Zoom-")]
        public float fieldOfView = 70.0f;
        public float zoomFieldOfView = 30.0f;
        public float zoomSpeed = 3.0f;

        [Header("-Visual Options-")]
        public float hideMeshWhenDistance = 0.5f;
    }
    [SerializeField]
    public CameraSettings cameraSettings;

    [System.Serializable]
    public class InputSettings
    {
        public string verticalAxis = "Mouse X";
        public string horizontalAxis = "Mouse Y";
        public string aimButton = "Fire2";
        public string switchShoulderButton = "Fire4";
    }
    [SerializeField]
    public InputSettings input;

    [System.Serializable]
    public class MovementSettings
    {
        public float movementLerpSpeed = 5.0f;
    }
    [SerializeField]
    public MovementSettings movement;

	public Transform pivot { get; protected set; }
	public Camera mainCamera { get; protected set; }
    float newX = 0.0f;
    float newY = 0.0f;

    // Use this for initialization
    void Start()
    {
        mainCamera = Camera.main;
        pivot = transform.GetChild(0);
    }

    // Update is called once per frame
    void Update()
    {
        if (target)
        {
            if (Application.isPlaying)
            {
                RotateCamera();
                CheckWall();
                CheckMeshRenderer();
                Zoom(Input.GetButton(input.aimButton));

                if (Input.GetButtonDown(input.switchShoulderButton))
                {
                    SwitchShoulders();
                }
            }
        }
    }

    void LateUpdate()
    {
        if (!target)
        {
            TargetPlayer();
        }
        else
        {
            Vector3 targetPostion = target.position;
            Quaternion targetRotation = target.rotation;

            FollowTarget(targetPostion, targetRotation);
        }
    }

    //Finds the plater gameObject and sets it as target
    void TargetPlayer()
    {
        if (autoTargetPlayer)
        {
            GameObject player = GameObject.FindGameObjectWithTag("Player");

            if (player)
            {
                Transform playerT = player.transform;
                target = playerT;
            }
        }
    }

    //Following the target with Time.deltaTime smoothly
    void FollowTarget(Vector3 targetPosition, Quaternion targetRotation)
    {
        if (!Application.isPlaying)
        {
            transform.position = targetPosition;
            transform.rotation = targetRotation;
        }
        else
        {
            //Vector3 newPos = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * movement.movementLerpSpeed);
			transform.position = target.position;
        }
    }

    //Rotates the camera with input
    void RotateCamera()
    {
        if (!pivot)
            return;

        newX += cameraSettings.mouseXSensitivity * Input.GetAxis(input.verticalAxis);
        newY += cameraSettings.mouseYSensitivity * Input.GetAxis(input.horizontalAxis);

        Vector3 eulerAngleAxis = new Vector3();
        eulerAngleAxis.x = newY;
        eulerAngleAxis.y = newX;

        newX = Mathf.Repeat(newX, 360);
        newY = Mathf.Clamp(newY, cameraSettings.minAngle, cameraSettings.maxAngle);

        Quaternion newRotation = Quaternion.Slerp(pivot.localRotation, Quaternion.Euler(eulerAngleAxis), Time.deltaTime * cameraSettings.rotationSpeed);

        pivot.localRotation = newRotation;
    }

    //Checks the wall and moves the camera up if we hit
    void CheckWall()
    {
        if (!pivot || !mainCamera)
            return;

        RaycastHit hit;

        Transform mainCamT = mainCamera.transform;
        Vector3 mainCamPos = mainCamT.position;
        Vector3 pivotPos = pivot.position;

        Vector3 start = pivotPos;
        Vector3 dir = mainCamPos - pivotPos;

        float dist = Mathf.Abs(shoulder == Shoulder.Left ? cameraSettings.camPositionOffsetLeft.z : cameraSettings.camPositionOffsetRight.z);

        if(Physics.SphereCast(start, cameraSettings.maxCheckDist, dir, out hit, dist, wallLayers))
        {
            MoveCamUp(hit, pivotPos, dir, mainCamT);
        }
        else
        {
            switch (shoulder)
            {
                case Shoulder.Left:
                    PostionCamera(cameraSettings.camPositionOffsetLeft);
                    break;
                case Shoulder.Right:
                    PostionCamera(cameraSettings.camPositionOffsetRight);
                    break;
            }
        }
    }

    //This moves the camera forward when we hit a wall
    void MoveCamUp(RaycastHit hit, Vector3 pivotPos, Vector3 dir, Transform cameraT)
    {
        float hitDist = hit.distance;
        Vector3 sphereCastCenter = pivotPos + (dir.normalized * hitDist);
        cameraT.position = sphereCastCenter;
    }

    //Postions the cameras localPosition to a given location
    void PostionCamera(Vector3 cameraPos)
    {
        if (!mainCamera)
            return;

        Transform mainCamT = mainCamera.transform;
        Vector3 mainCamPos = mainCamT.localPosition;
        Vector3 newPos = Vector3.Lerp(mainCamPos, cameraPos, Time.deltaTime * movement.movementLerpSpeed);
        mainCamT.localPosition = newPos;
    }

    //Hides the mesh targets mesh renderers when too close
    void CheckMeshRenderer()
    {
        if (!mainCamera || !target)
            return;

        SkinnedMeshRenderer[] meshes = target.GetComponentsInChildren<SkinnedMeshRenderer>();
        Transform mainCamT = mainCamera.transform;
        Vector3 mainCamPos = mainCamT.position;
        Vector3 targetPos = target.position;
        float dist = Vector3.Distance(mainCamPos, (targetPos + target.up));

        if(meshes.Length > 0)
        {
            for(int i = 0; i < meshes.Length; i++)
            {
                if(dist <= cameraSettings.hideMeshWhenDistance)
                {
                    meshes*.enabled = false;*

}
else
{
meshes*.enabled = true;*
}
}
}
}

//Zooms the camera in and out
void Zoom(bool isZooming)
{
if (!mainCamera)
return;

if (isZooming)
{
float newFieldOfView = Mathf.Lerp(mainCamera.fieldOfView, cameraSettings.zoomFieldOfView, Time.deltaTime * cameraSettings.zoomSpeed);
mainCamera.fieldOfView = newFieldOfView;
}
else
{
float originalFieldOfView = Mathf.Lerp(mainCamera.fieldOfView, cameraSettings.fieldOfView, Time.deltaTime * cameraSettings.zoomSpeed);
mainCamera.fieldOfView = originalFieldOfView;
}
}

//Switches the cameras shoulder view
public void SwitchShoulders()
{
switch (shoulder)
{
case Shoulder.Left:
shoulder = Shoulder.Right;
break;
case Shoulder.Right:
shoulder = Shoulder.Left;
break;
}
}
}

Collision detection is expensive, I’m afraid. That said, there are a few ways to mitigate the cost, in order of complexity…

  1. Do the ray cast in FixedUpdate instead of Update, otherwise you’re testing the same physics state multiple times.
  2. Use a ray cast instead of a sphere cast. Will allow the near clip plane to chop through nearby objects, but costs less CPU.
  3. Temporal optimisation. Do the sphere cast every X frames instead of every single frame, and cache the results. This will introduce a small lag. You could set it to test every frame while the player is adjusting the camera and drop to coarser testing the rest of the time.
  4. Don’t ray cast. You could add a trigger sphere to the camera, and use collision callbacks to react to geometry that overlaps with it. This will be done as part of the physics simulation and will cost a LOT less CPU.