using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class CustomSmoothFollow : MonoBehaviour
|
|
{
|
|
public Transform target;
|
|
public float distance = -200.0f;
|
|
public float height = 200.0f;
|
|
public float altDistance = -100.0f;
|
|
public float altHeight = 250.0f;
|
|
public Vector3 damping;
|
|
public string layerToMask = "CameraObstruct";
|
|
private int layerMask;
|
|
[Range (0,360)]
|
|
public float offsetAngle = 90;
|
|
|
|
// Use this for initialization
|
|
void Start()
|
|
{
|
|
layerMask = LayerMask.NameToLayer(layerToMask);
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void LateUpdate()
|
|
{
|
|
// Early out if we don't have a target
|
|
if (!target)
|
|
return;
|
|
|
|
// Calculate the current and wanted height / XZ pos
|
|
float wantedHeight = target.position.y + height;
|
|
float wantedDistance = target.position.z + distance;
|
|
float wantedSide = target.position.x;
|
|
|
|
bool isBlocked = false;
|
|
Vector3 wantedPos = new Vector3(wantedSide, wantedHeight, wantedDistance);
|
|
|
|
wantedPos = RotatePointAroundPivot(wantedPos, target.transform.position, offsetAngle);
|
|
|
|
|
|
RaycastHit hitInfo;
|
|
if (Physics.Raycast(wantedPos, target.position-wantedPos, out hitInfo, (target.position-wantedPos).magnitude * 2f))
|
|
{
|
|
// Debug.LogWarning (hitInfo.collider.name + " -- " + hitInfo.collider.gameObject.layer + " -- " + layerMask);
|
|
if (hitInfo.collider.gameObject.layer == layerMask)
|
|
isBlocked = true;
|
|
}
|
|
|
|
if (isBlocked)
|
|
{
|
|
wantedPos.y = target.position.y + altHeight;
|
|
wantedPos.z = target.position.z + altDistance;
|
|
wantedPos.x = target.position.x;
|
|
wantedPos = RotatePointAroundPivot(wantedPos, target.transform.position, offsetAngle);
|
|
}
|
|
|
|
float currentHeight = transform.position.y;
|
|
float currentDistance = transform.position.z;
|
|
float currentSide = transform.position.x;
|
|
|
|
|
|
|
|
// Damp the height
|
|
currentHeight = Mathf.Lerp(currentHeight, wantedPos.y, damping.y * Time.deltaTime);
|
|
currentDistance = Mathf.Lerp(currentDistance, wantedPos.z, damping.z * Time.deltaTime);
|
|
currentSide = Mathf.Lerp(currentSide, wantedPos.x, damping.x * Time.deltaTime);
|
|
|
|
// Set the position of the camera on the x-z plane to:
|
|
// distance meters behind the target
|
|
transform.position = target.position;
|
|
|
|
|
|
|
|
// Set the height of the camera
|
|
transform.position = new Vector3(currentSide, currentHeight, currentDistance);
|
|
|
|
// Always look at the target
|
|
Vector3 lookTarget = target.position;
|
|
lookTarget.z = transform.position.z;
|
|
transform.LookAt(lookTarget);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
private Vector3 RotatePointAroundPivot(Vector3 point,Vector3 pivot,float angles ) {
|
|
Vector3 dir = point - pivot; // get point direction relative to pivot
|
|
dir = Quaternion.Euler(angles * Vector3.up) * dir; // rotate it
|
|
point = dir + pivot; // calculate rotated point
|
|
return point; // return it
|
|
}
|
|
}
|