Advertisement
Guest User

thirdPersonCamera.cs

a guest
Jan 6th, 2014
1,642
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class thirdPersonCamera : MonoBehaviour
  5. {
  6.     public thirdPersonCamera instance;              // Reference to the Main Camera.
  7.     public Transform targetLookTransform;           // Transform of the camera will be looking at.
  8.     public float distance = 5f;                     // Start distance of camera.
  9.     public float distanceMin = 3f;                  // Minimum distance of camera zoom.
  10.     public float distanceMax = 10f;                 // Maximum distance of camera zoom.
  11.     public float distanceSmooth = 0.05f;            // Camera zooming smooth factor.
  12.     public float distanceCameraResumeSmooth = 1f;   // Distance at which point smoothing is resumed after occlusion handling is no longer occuring.
  13.     private float distanceCameraSmooth = 0f;        // Camera smoothing distance (after occlusion is no longer happening).
  14.     private float preOccludedDistance = 0f;        
  15.  
  16.     public float mouseXSensitivity = 5f;            // Mouse X sensitivity.
  17.     public float mouseYSensitivity = 5f;            // Mouse Y sensitivity.
  18.     public float mouseWheelSensitivity = 5f;        // Mouse wheel/scroll sensitivity.
  19.     public float xSmooth = 0.05f;                   // Smoothness factor for x position calculations.
  20.     public float ySmooth = 0.1f;                    // Smoothness factor for y position calculations.
  21.     public float yMinLimit = -40f;                 
  22.     public float yMaxLimit = 80f;                  
  23.     private float mouseX = 0f;
  24.     private float mouseY = 0f;
  25.     private float velocityX = 0f;
  26.     private float velocityY = 0f;
  27.     private float velocityZ = 0f;
  28.     private float velocityDistance = 0f;
  29.  
  30.     public float occlusionDistanceStep = 0.5f;
  31.     public int maxOcclusionChecks = 10;             // Max number of times to check for occlusion.
  32.  
  33.     private float startDistance = 0f;
  34.     private float desiredDistance = 0f;
  35.  
  36.     private Vector3 position = new Vector3(768f, 3.5f, 903f);
  37.     private Vector3 desiredPosition = new Vector3(768f, 3.5f, 903f);
  38.  
  39.     private void Awake ()
  40.     {
  41.         instance = this;
  42.     }
  43.  
  44.     void Start ()
  45.     {
  46.         distance = Mathf.Clamp (distance, distanceMin, distanceMax);    // Ensure our distance is between min and max (valid)
  47.         startDistance = distance;
  48.         Reset ();
  49.     }
  50.  
  51.     private void LateUpdate ()
  52.     {
  53.         if (targetLookTransform == null)
  54.         {
  55.             return;
  56.         }
  57.  
  58.         HandlePlayerInput ();
  59.  
  60.         int count = 0;
  61.         do
  62.         {
  63.             CalculateDesiredPosition ();
  64.             count++;
  65.         } while (CheckIfOccluded(count));
  66.  
  67.         UpdatePosition ();
  68.     }
  69.  
  70.     private void HandlePlayerInput ()
  71.     {
  72.         float deadZone = 0.01f;
  73.  
  74.         // If right mouse button is down, get mouse axis input.
  75.         if (Input.GetMouseButton (1))
  76.         {
  77.             mouseX += Input.GetAxis ("Mouse X") * mouseXSensitivity;
  78.             mouseY -= Input.GetAxis ("Mouse Y") * mouseYSensitivity;
  79.         }
  80.  
  81.         // Clamp (limit) mouse Y rotation. Uses thirdPersonCameraHelper.cs.
  82.         mouseY = thirdPersonCameraHelper.clampingAngle (mouseY, yMinLimit, yMaxLimit);
  83.  
  84.         // Clamp (limit) mouse scroll wheel.
  85.         if (Input.GetAxis ("Mouse ScrollWheel") > deadZone || Input.GetAxis ("Mouse ScrollWheel") < -deadZone)
  86.         {
  87.             desiredDistance = Mathf.Clamp (distance - Input.GetAxis("Mouse ScrollWheel") * mouseWheelSensitivity,
  88.                                            distanceMin,
  89.                                            distanceMax
  90.                                            );
  91.             preOccludedDistance = desiredDistance;
  92.             distanceCameraSmooth = distanceSmooth;
  93.         }
  94.     }
  95.  
  96.     // Smoothing.
  97.     private void CalculateDesiredPosition ()
  98.     {
  99.         // Evaluate distance.
  100.         ResetDesiredDistance ();
  101.         distance = Mathf.SmoothDamp (distance, desiredDistance, ref velocityDistance, distanceCameraSmooth);
  102.  
  103.         // Calculate desired position.
  104.         desiredPosition = CalculatePosition (mouseY, mouseX, distance);
  105.     }
  106.  
  107.     private bool CheckIfOccluded (int count)
  108.     {
  109.         bool isOccluded = false;
  110.         float nearestDistance = CheckCameraPoints (targetLookTransform.position, desiredPosition);
  111.  
  112.         if (nearestDistance != -1)
  113.         {
  114.             if (count < maxOcclusionChecks)
  115.             {
  116.                 isOccluded = true;
  117.                 distance -= occlusionDistanceStep;
  118.  
  119.                 // 0.25 is a good default value.
  120.                 if (distance < 0.25f)
  121.                 {
  122.                     distance = 0.25f;
  123.                 }
  124.             }
  125.             else
  126.             {
  127.                 distance = nearestDistance - Camera.main.nearClipPlane;
  128.             }
  129.             desiredDistance = distance;
  130.             distanceCameraSmooth = distanceCameraResumeSmooth;
  131.         }
  132.  
  133.         return isOccluded;
  134.     }
  135.  
  136.     private Vector3 CalculatePosition (float rotX, float rotY, float rotDist)
  137.     {
  138.         Vector3 direction = new Vector3 (0, 0, -distance);          // -distance because we want it to point behind our character.
  139.         Quaternion rotation = Quaternion.Euler (rotX, rotY, 0);
  140.         return targetLookTransform.position + (rotation * direction);
  141.     }
  142.  
  143.     private float CheckCameraPoints (Vector3 from, Vector3 to)
  144.     {
  145.         float nearestDistance = -1f;
  146.  
  147.         RaycastHit hitInfo;
  148.  
  149.         thirdPersonCameraHelper.ClipPlanePoints clipPlanePoints =
  150.             thirdPersonCameraHelper.ClipPlaneAtNear (to);
  151.  
  152.         // Draw the raycasts going through the near clip plane vertexes.
  153.         Debug.DrawLine (from, to + transform.forward * -camera.nearClipPlane, Color.red);
  154.         Debug.DrawLine (from, clipPlanePoints.upperLeft, Color.red);
  155.         Debug.DrawLine (from, clipPlanePoints.upperRight, Color.red);
  156.         Debug.DrawLine (from, clipPlanePoints.lowerLeft, Color.red);
  157.         Debug.DrawLine (from, clipPlanePoints.lowerRight, Color.red);
  158.         Debug.DrawLine (clipPlanePoints.upperLeft, clipPlanePoints.upperRight, Color.red);
  159.         Debug.DrawLine (clipPlanePoints.upperRight, clipPlanePoints.lowerRight, Color.red);
  160.         Debug.DrawLine (clipPlanePoints.lowerRight, clipPlanePoints.lowerLeft, Color.red);
  161.         Debug.DrawLine (clipPlanePoints.lowerLeft, clipPlanePoints.upperLeft, Color.red);
  162.  
  163.         if (Physics.Linecast(from, clipPlanePoints.upperLeft, out hitInfo) && hitInfo.collider.tag != "Player")
  164.             nearestDistance = hitInfo.distance;
  165.         if (Physics.Linecast(from, clipPlanePoints.lowerLeft, out hitInfo) && hitInfo.collider.tag != "Player")
  166.             if (hitInfo.distance < nearestDistance || nearestDistance == -1)
  167.                 nearestDistance = hitInfo.distance;
  168.         if (Physics.Linecast(from, clipPlanePoints.upperRight, out hitInfo) && hitInfo.collider.tag != "Player")
  169.             if (hitInfo.distance < nearestDistance || nearestDistance == -1)
  170.                 nearestDistance = hitInfo.distance;
  171.         if (Physics.Linecast(from, to + transform.forward * -camera.nearClipPlane, out hitInfo) && hitInfo.collider.tag != "Player")
  172.             if (hitInfo.distance < nearestDistance || nearestDistance == -1)
  173.                 nearestDistance = hitInfo.distance;
  174.  
  175.         return nearestDistance;
  176.     }
  177.  
  178.     private void ResetDesiredDistance ()
  179.     {
  180.         if (desiredDistance < preOccludedDistance)
  181.         {
  182.             Vector3 pos = CalculatePosition (mouseY, mouseX, preOccludedDistance);
  183.             float nearestDistance = CheckCameraPoints(targetLookTransform.position, pos);
  184.  
  185.             if (nearestDistance == -1 || nearestDistance > preOccludedDistance)
  186.             {
  187.                 desiredDistance = preOccludedDistance;
  188.             }
  189.         }
  190.     }
  191.  
  192.     private void UpdatePosition ()
  193.     {
  194.         float posX = Mathf.SmoothDamp (position.x, desiredPosition.x, ref velocityX, xSmooth * Time.deltaTime);
  195.         float posY = Mathf.SmoothDamp (position.y, desiredPosition.y, ref velocityY, ySmooth * Time.deltaTime);
  196.         float posZ = Mathf.SmoothDamp (position.z, desiredPosition.z, ref velocityZ, xSmooth * Time.deltaTime);
  197.  
  198.         position = new Vector3 (posX, posY, posZ);
  199.  
  200.         transform.position = position;
  201.  
  202.         transform.LookAt (targetLookTransform);
  203.     }
  204.  
  205.     public void Reset ()
  206.     {
  207.         mouseX = 0f;
  208.         mouseY = 10f;
  209.         distance = startDistance;
  210.         desiredDistance = distance;
  211.         preOccludedDistance = distance;
  212.     }
  213.  
  214.     public static void UseExistingOrCreateMainCamera ()
  215.     {
  216.         GameObject tempCamera;
  217.         GameObject targetLookAt;
  218.         thirdPersonCamera myCamera;
  219.  
  220.         if (Camera.main != null)
  221.         {
  222.             tempCamera = Camera.main.gameObject;
  223.         }
  224.         else
  225.         {
  226.             tempCamera = new GameObject("Main Camera");
  227.             tempCamera.AddComponent("Camera");
  228.             tempCamera.tag = "MainCamera";              // This is what actually makes our created camera the main camera.
  229.         }
  230.  
  231.         tempCamera.AddComponent ("thirdPersonCamera");
  232.         myCamera = tempCamera.GetComponent<thirdPersonCamera>();
  233.  
  234.         targetLookAt = GameObject.FindGameObjectWithTag ("CameraFocus");
  235.  
  236.         if (targetLookAt == null)
  237.         {
  238.             targetLookAt = new GameObject ("Player");
  239.             targetLookAt.transform.position = new Vector3(768f, 0, 900f);
  240.         }
  241.  
  242.         myCamera.targetLookTransform = targetLookAt.transform;
  243.     }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement