Prevent camera from going through walls and meshes

I would like to prevent the camera from going through walls and meshes.
I wrote this code but it dowsn’t work properly, because when the camera detects that it has something behind, it stops and do strange stuff if I move the mouse

public class ThirdPersonCamera : MonoBehaviour {

public bool lockCursor;
public float mouseSensitivity = 10; //sensibilità
public Transform target; // il target che la telecamera deve seguire
public float distanceFromTarget = 2;
public Vector2 pitchMinMax = new Vector2(-40, 85); //il minimo ed il massimo del pitch

public float rotationSmoothTime = .12f;
Vector3 rotationSmoothVelocity;
Vector3 currentRotation;

float yaw; //rotazione asse X
float pitch; //rotazione asse Y

float distanceFromWall = 0.5f;

// Use this for initialization
void Start () 
{
	if (lockCursor) 
	{
		Cursor.lockState = CursorLockMode.Locked;
		Cursor.visible = false;
	}

}

// LateUpdate is called dopo tutti gli altri Update methods
void LateUpdate () 
{
	//raccolgo input del mouse
	yaw += Input.GetAxis ("Mouse X") * mouseSensitivity;
	pitch -= Input.GetAxis ("Mouse Y") * mouseSensitivity;
	pitch = Mathf.Clamp (pitch, pitchMinMax.x, pitchMinMax.y); //non permette al pitch di superare i due valori

	currentRotation = Vector3.SmoothDamp (currentRotation, new Vector3 (pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime); //calcola la posizione che deve assumere la telecamera con un po' di smooth

	transform.eulerAngles = currentRotation; //ruota la telecamera

	//hit per i muri telecamera
	RaycastHit hit;
	Vector3 back = transform.TransformDirection(-1 * Vector3.forward);
	Vector3 wantedPosition = Vector3.zero;
	if (Physics.Raycast (target.position, back, out hit, distanceFromTarget) && hit.transform != target)
	{
		wantedPosition = new Vector3 (hit.point.x, hit.point.y, hit.point.z + distanceFromWall);
		//wantedPosition.z = Mathf.Lerp (hit.point.y, pitch, Time.deltaTime * rotationSmoothTime);
		transform.position = Vector3.SmoothDamp(transform.position, wantedPosition, ref rotationSmoothVelocity, rotationSmoothTime, rotationSmoothTime, Time.deltaTime);
	}
	else
		transform.position = target.position - transform.forward * distanceFromTarget; //segue il target mantenendo una certa distanza
	//fine hit muri

	transform.position = target.position - transform.forward * distanceFromTarget; //segue il target mantenendo una certa distanza

}

I guess you are doing Sebastion Lagues tutorials as well.

I have just got the same thing working. Note that I am HitTesting from the center of the character and not the players position which would be at floor level.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class ThirdPersonCamera : MonoBehaviour
    {
        public bool lockCursor;
        public float mouseSensitivity = 10;
        public Transform target;
        public float dstFromTarget = 3;

        public float rotationSmoothTime = .12f;
        Vector3 rotationSmoothVelocity;
        Vector3 currentRotation;

        public float minPitch = -40;
        public float maxPitch = 85;

        float yaw;
        float pitch;

        Vector3 center = new Vector3(0f, 0.5f, 0f);
        RaycastHit hit;

        private void Start()
        {
            if (lockCursor)
            {
                Cursor.lockState = CursorLockMode.Locked;
                Cursor.visible = false;
            }
        }

        void LateUpdate()
        {
            yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
            pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
            pitch = Mathf.Clamp(pitch, minPitch, maxPitch);

            currentRotation = Vector3.SmoothDamp(currentRotation, new Vector3(pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime);
            transform.eulerAngles = currentRotation;

            Vector3 wantedCameraPosition = target.position + center - transform.forward * dstFromTarget;

            // Raycasting 
            Vector3 rayDirection = (wantedCameraPosition - (target.position + center)).normalized;

            if (Physics.Raycast(target.position + center, rayDirection, out hit, dstFromTarget)
                && hit.transform != target.parent) // ignore ray-casts that hit the user. DR
            {
                // Debug.Log(hit.transform.name  + " " + direction.ToString());
                wantedCameraPosition.x = hit.point.x;
                wantedCameraPosition.z = hit.point.z;
                //wantedPosition.y = wantedPosition.y);
            }

            transform.position = wantedCameraPosition;
        }
    }