How can i prevent from moving the camera view under the terrain ?

I’m using this mouseorbit script attached to a camera. The problem is when i move the camera with the mouse and rotating it so the camera is under the terrain. I want that when it get to the terrain height then stop don’t move down i mean don’t get to this view under the character maximum to be in the terrain height…

To stop on terrain height i mean something like that when it’s getting to this:

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

public class MouseOrbit : MonoBehaviour
{
    /* These variables are what tell the camera how its going to function by
      * setting the viewing target, collision layers, and other properties
      * such as distance and viewing angles */
    public Transform viewTarget;
    public LayerMask collisionLayers;
    public float distance = 6.0f;
    public float distanceSpeed = 150.0f;
    public float collisionOffset = 0.3f;
    public float minDistance = 4.0f;
    public float maxDistance = 12.0f;
    public float height = 1.5f;
    public float horizontalRotationSpeed = 250.0f;
    public float verticalRotationSpeed = 150.0f;
    public float rotationDampening = 0.75f;
    public float minVerticalAngle = -60.0f;
    public float maxVerticalAngle = 60.0f;
    public bool useRMBToAim = false;

    /* These variables are meant to store values given by the script and
     * not the user */
    private float h, v, smoothDistance;
    private Vector3 newPosition;
    private Quaternion newRotation, smoothRotation;
    private Transform cameraTransform;

    /* This is where we initialize our script */
    void Start()
    {
        Initialize();
    }

    /* This is where we set our private variables, check for null errors,
     * and anything else that needs to be called once during startup */
    void Initialize()
    {
        h = this.transform.eulerAngles.x;
        v = this.transform.eulerAngles.y;

        cameraTransform = this.transform;
        smoothDistance = distance;

        NullErrorCheck();
    }

    /* We check for null errors or warnings and notify the user to fix them */
    void NullErrorCheck()
    {
        if (!viewTarget)
        {
            Debug.LogError("Please make sure to assign a view target!");
            Debug.Break();
        }
        if (collisionLayers == 0)
        {
            Debug.LogWarning("Make sure to set the collision layers to the layers the camera should collide with!");
        }
    }

    /* This is where we do all our camera updates. This is where the camera
     * gets all of its functionality. From setting the position and rotation,
     * to adjusting the camera to avoid geometry clipping */
    void LateUpdate()
    {
        if (!viewTarget)
            return;

        /* We check for right mouse button functionality, set the rotation
         * angles, and lock the mouse cursor */
        if (!useRMBToAim)
        {
            /* Check to make sure the game isn't paused and lock the mouse cursor*/
            if (Time.timeScale > 0.0f)
                Cursor.lockState = CursorLockMode.Locked;

            h += Input.GetAxis("Mouse X") * horizontalRotationSpeed * Time.deltaTime;
            v -= Input.GetAxis("Mouse Y") * verticalRotationSpeed * Time.deltaTime;

            h = ClampAngle(h, -360.0f, 360.0f);
            v = ClampAngle(v, minVerticalAngle, maxVerticalAngle);

            newRotation = Quaternion.Euler(v, h, 0.0f);
        }
        else
        {
            if (Input.GetMouseButton(1))
            {
                /* Check to make sure the game isn't paused and lock the mouse cursor */
                if (Time.timeScale > 0.0f)
                    Cursor.lockState = CursorLockMode.Locked;

                h += Input.GetAxis("Mouse X") * horizontalRotationSpeed * Time.deltaTime;
                v -= Input.GetAxis("Mouse Y") * verticalRotationSpeed * Time.deltaTime;

                h = ClampAngle(h, -360.0f, 360.0f);
                v = ClampAngle(v, minVerticalAngle, maxVerticalAngle);

                newRotation = Quaternion.Euler(v, h, 0.0f);
            }
            else
            {
                Cursor.lockState = CursorLockMode.Confined;
            }
        }

        /* We set the distance by moving the mouse wheel and use a custom
         * growth function as the time value for linear interpolation */
        distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 10, minDistance, maxDistance);
        smoothDistance = Mathf.Lerp(smoothDistance, distance, TimeSignature(distanceSpeed));

        /*We give the rotation some smoothing for a nicer effect */
        smoothRotation = Quaternion.Slerp(smoothRotation, newRotation, TimeSignature((1 / rotationDampening) * 100.0f));

        newPosition = viewTarget.position;
        newPosition += smoothRotation * new Vector3(0.0f, height, -smoothDistance);

        /* Calls the function to adjust the camera position to avoid clipping */
        CheckSphere();

        smoothRotation.eulerAngles = new Vector3(smoothRotation.eulerAngles.x, smoothRotation.eulerAngles.y, 0.0f);

        cameraTransform.position = newPosition;
        cameraTransform.rotation = smoothRotation;
    }

    /* This is where the camera checks for a collsion hit within a specified radius,
     * and then moves the camera above the location it hit with an offset value */
    void CheckSphere()
    {
        /* Add height to our spherecast origin */
        Vector3 tmpVect = viewTarget.position;
        tmpVect.y += height;

        RaycastHit hit;

        /* Get the direction from the camera position to the origin */
        Vector3 dir = (newPosition - tmpVect).normalized;

        /* Check a radius for collision hits and then set the new position for
         * the camera */
        if (Physics.SphereCast(tmpVect, 0.3f, dir, out hit, distance, collisionLayers))
        {
            newPosition = hit.point + (hit.normal * collisionOffset);
        }
    }

    /* Keeps the angles values within their specificed minimum and maximum
     * inputs while at the same time putting the values back to 0 if they
     * go outside of the 360 degree range */
    private float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;

        if (angle > 360)
            angle -= 360;

        return Mathf.Clamp(angle, min, max);
    }

    /* This is our custom logistic growth time signature with speed as input */
    private float TimeSignature(float speed)
    {
        return 1.0f / (1.0f + 80.0f * Mathf.Exp(-speed * 0.02f));
    }
}

It looks like the script i grabbed already handles terrain collision… i just need to make sure to set the collision layers on it to include the terrain. But not sure how to do it.

What i tried:

I added now a new layer in the inspector called it Terrain. Then in the hierarchy on the Terrain i change it’s layer to terrain. Also in the script i selected Terrain. But it’s still not working.

public Transform Player;
public Transform Camera;
public float adjustBy;

void Update(){


Vector3 Adjustment = new Vector3(0 , adjustBy , 0);
if(Camera.position.y < Player.position.y){
Camera.position = Camera.Position + Adjustment;
}
}

Here the idea is to make it so that Whenever Camera Tries to go below feet level of player , the position of camera should get adjusted by some value

Hello @haimmoshe !
I have a solution that I made a time ago with help of Unity community
Just attach this script to your camera and set which layers ‘should be protected from camera collision’

using UnityEngine;
using System.Collections;

[AddComponentMenu("Camera-Control/Mouse Orbit with zoom")]
public class MouseOrbitImproved : MonoBehaviour
{
    public Transform target;

	public float targetHeight = 1.7f; 
    public float distance = 5.0f;
	public float offsetFromWall = 0.1f;
    public float xSpeed = 120.0f;
    public float ySpeed = 120.0f;

    public float yMinLimit = -20f;
    public float yMaxLimit = 80f;

	public int zoomRate = 40; 
	public float zoomDampening = 5.0f; 

    public float distanceMin = .5f;
    public float distanceMax = 15f;

    private Rigidbody rigidbody;
	public LayerMask collisionLayers = -1;

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

    float x = 0.0f;
    float y = 0.0f;

    // Use this for initialization
    void Start()
    {
        Vector3 angles = transform.eulerAngles;
        x = angles.y;
        y = angles.x;

        rigidbody = GetComponent<Rigidbody>();

        // Make the rigid body not change rotation
        if (rigidbody != null)
        {
            rigidbody.freezeRotation = true;
        }

        if (target == null)
            FindPlayer();
    }

    void FindPlayer()
    {
        CharacterController controller = FindObjectOfType<CharacterController>();
        if (controller)
        {
            target = controller.gameObject.transform;
        }
    }

    void LateUpdate()
    {
		Vector3 vTargetOffset;
        if (target)
        {
            x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
            y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

            y = ClampAngle(y, yMinLimit, yMaxLimit);

            Quaternion rotation = Quaternion.Euler(y, x, 0);

			// calculate distance 
			desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs (desiredDistance); 
			desiredDistance = Mathf.Clamp (desiredDistance, distanceMin, distanceMax); 
			correctedDistance = desiredDistance; 

			// calculate camera position
			vTargetOffset = new Vector3 (0, -targetHeight, 0);
			Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset); 


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

			bool isCorrected = false; 
			if (Physics.Linecast (trueTargetPosition, position, out collisionHit, collisionLayers.value)) 
			{ 
				// calculate and remove clipping
				correctedDistance = Vector3.Distance (trueTargetPosition, collisionHit.point) - offsetFromWall; 
				isCorrected = true;
			}

			currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp (currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance; 


			currentDistance = Mathf.Clamp (currentDistance, distanceMin, distanceMax); 

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

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

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

Happy developing ^^