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; } 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 } }