I wrote a third person controller and used part of a collision detection script that I found online. Currently it is able to move the camera in closer whenever objects are inbetween the camera and the player, but not when the terrain in inbetween the camera and the player.
Everything I use for detecting if there is an object between the player and the camera can be found in the OccludeRay method.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraScript : MonoBehaviour {
[SerializeField]private GameObject player;
[SerializeField]private float cameraRadius;
[SerializeField]private Vector3 cameraOffset;
[SerializeField]private LayerMask CamOcclusionLayers;
private Vector3 camDistance;
private Vector3 camAnchor;
private Vector3 camDesiredPosition;
private Vector3 camMask;
[HideInInspector]public float cameraAngleX=0;
[HideInInspector]public float cameraAngleY=0;
// Use this for initialization
void Start () {
camAnchor = player.transform.position - cameraOffset;
transform.position = camAnchor - new Vector3(0,0,cameraRadius);
}
// Update is called once per frame
void Update () {
updateCamera ();
}
void updateCamera()
{
cameraAngleX += Input.GetAxis("Mouse X");
cameraAngleY -= Input.GetAxis("Mouse Y");
if (cameraAngleY > 90) {
cameraAngleY = 90;
}
if (cameraAngleY< -90) {
cameraAngleY = -90;
}
camAnchor = player.transform.position - cameraOffset;
camDistance = new Vector3 (cameraRadius*Mathf.Sin(cameraAngleX*Mathf.PI/180),cameraRadius*Mathf.Sin(cameraAngleY*Mathf.PI/180), cameraRadius*Mathf.Cos(cameraAngleX*Mathf.PI/180));
camMask = camAnchor - camDistance;
camDesiredPosition = camAnchor - camDistance;
occludeRay (ref camAnchor);
transform.position = camDesiredPosition;
transform.LookAt (camAnchor);
}
void occludeRay(ref Vector3 target)
{
//declare a new raycast hit.
RaycastHit wallHit = new RaycastHit();
//linecast from your player (targetFollow) to your cameras mask (camMask) to find collisions.
if (Physics.Linecast(target, camMask, out wallHit, CamOcclusionLayers))
{
//the smooth is increased so you detect geometry collisions faster.
//smooth = 10f;
//the x and z coordinates are pushed away from the wall by hit.normal.
//the y coordinate stays the same.
camDesiredPosition = new Vector3(wallHit.point.x + wallHit.normal.x * 0.5f, camDesiredPosition.y, wallHit.point.z + wallHit.normal.z * 0.5f);
}
}
}