using UnityEngine; using System.Collections; public class MainCameraBehavior : MonoBehaviour { public Transform targetTransform; public float y = 2.5f; // store the height value since it will never change public float offsetZ = -2.2f; //////////////////////////////////////////// public float smooth = 1.5f; // The relative speed at which the camera will catch up. private Vector3 relCameraPos; // The relative position of the camera from the targetTransform. private float relCameraPosMag; // The distance of the camera from the targetTransform. private Vector3 newPos; // The position the camera is trying to reach. void Awake() { // Setting the relative position as the initial relative position of the camera in the scene. relCameraPos = transform.position - targetTransform.position; relCameraPosMag = relCameraPos.magnitude - 0.5f; } void FixedUpdate() { // The standard position of the camera is the relative position of the camera from the targetTransform. Vector3 standardPos = targetTransform.position + relCameraPos; // The abovePos is directly above the targetTransform at the same distance as the standard position. Vector3 abovePos = targetTransform.position + Vector3.up * relCameraPosMag; // An array of 5 points to check if the camera can see the targetTransform. Vector3[] checkPoints = new Vector3[5]; // The first is the standard position of the camera. checkPoints[0] = standardPos; // The next three are 25%, 50% and 75% of the distance between the standard position and abovePos. checkPoints[1] = Vector3.Lerp(standardPos, abovePos, 0.25f); checkPoints[2] = Vector3.Lerp(standardPos, abovePos, 0.5f); checkPoints[3] = Vector3.Lerp(standardPos, abovePos, 0.75f); // The last is the abovePos. checkPoints[4] = abovePos; // Run through the check points... for (int i = 0; i < checkPoints.Length; i++) { // ... if the camera can see the targetTransform... if (ViewingPosCheck(checkPoints[i])) // ... break from the loop. break; } // Lerp the camera's position between it's current position and it's new position. transform.position = Vector3.Lerp(transform.position, newPos, smooth * Time.deltaTime); // Make sure the camera is looking at the targetTransform. SmoothLookAt(); } bool ViewingPosCheck(Vector3 checkPos) { RaycastHit hit; // If a raycast from the check position to the targetTransform hits something... if (Physics.Raycast(checkPos, targetTransform.position - checkPos, out hit, relCameraPosMag)) // ... if it is not the targetTransform... if (hit.transform != targetTransform) // This position isn't appropriate. return false; // If we haven't hit anything or we've hit the targetTransform, this is an appropriate position. newPos = checkPos; return true; } void SmoothLookAt() { // Create a vector from the camera towards the targetTransform. Vector3 reltargetTransformPosition = targetTransform.position - transform.position; // Create a rotation based on the relative position of the targetTransform being the forward vector. Quaternion lookAtRotation = Quaternion.LookRotation(reltargetTransformPosition, Vector3.up); // Lerp the camera's rotation between it's current rotation and the rotation that looks at the targetTransform. transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, smooth * Time.deltaTime); } }