Advertisement
Guest User

Untitled

a guest
Feb 7th, 2021
21,809
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.70 KB | None | 1 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. namespace RootMotion
  5. {
  6.  
  7.     /// <summary>
  8.     /// 3rd person camera controller.
  9.     /// </summary>
  10.     public class CameraController : MonoBehaviour
  11.     {
  12.  
  13.         // When to update the camera?
  14.         [System.Serializable]
  15.         public enum UpdateMode
  16.         {
  17.             Update,
  18.             FixedUpdate,
  19.             LateUpdate,
  20.             FixedLateUpdate
  21.         }
  22.  
  23.         public Transform target; // The target Transform to follow
  24.         public Transform rotationSpace; // If assigned, will use this Transform's rotation as the rotation space instead of the world space. Useful with spherical planets.
  25.         public UpdateMode updateMode = UpdateMode.LateUpdate; // When to update the camera?
  26.         public bool lockCursor = true; // If true, the mouse will be locked to screen center and hidden
  27.  
  28.         [Header("Position")]
  29.         public bool smoothFollow; // If > 0, camera will smoothly interpolate towards the target
  30.         public Vector3 offset = new Vector3(0, 1.5f, 0.5f); // The offset from target relative to camera rotation
  31.         public float followSpeed = 10f; // Smooth follow speed
  32.  
  33.         [Header("Rotation")]
  34.         public float rotationSensitivity = 3.5f; // The sensitivity of rotation
  35.         public float yMinLimit = -20; // Min vertical angle
  36.         public float yMaxLimit = 80; // Max vertical angle
  37.         public bool rotateAlways = true; // Always rotate to mouse?
  38.         public bool rotateOnLeftButton; // Rotate to mouse when left button is pressed?
  39.         public bool rotateOnRightButton; // Rotate to mouse when right button is pressed?
  40.         public bool rotateOnMiddleButton; // Rotate to mouse when middle button is pressed?
  41.  
  42.         [Header("Distance")]
  43.         public float distance = 10.0f; // The current distance to target
  44.         public float minDistance = 4; // The minimum distance to target
  45.         public float maxDistance = 10; // The maximum distance to target
  46.         public float zoomSpeed = 10f; // The speed of interpolating the distance
  47.         public float zoomSensitivity = 1f; // The sensitivity of mouse zoom
  48.  
  49.         [Header("Blocking")]
  50.         public LayerMask blockingLayers;
  51.         public float blockingRadius = 1f;
  52.         public float blockingSmoothTime = 0.1f;
  53.         public float blockingOriginOffset;
  54.         [Range(0f, 1f)] public float blockedOffset = 0.5f;
  55.  
  56.         public float x { get; private set; } // The current x rotation of the camera
  57.         public float y { get; private set; } // The current y rotation of the camera
  58.         public float distanceTarget { get; private set; } // Get/set distance
  59.  
  60.         private Vector3 targetDistance, position;
  61.         private Quaternion rotation = Quaternion.identity;
  62.         private Vector3 smoothPosition;
  63.         private Camera cam;
  64.         private bool fixedFrame;
  65.         private float fixedDeltaTime;
  66.         private Quaternion r = Quaternion.identity;
  67.         private Vector3 lastUp;
  68.         private float blockedDistance = 10f, blockedDistanceV;
  69.  
  70.         public void SetAngles(Quaternion rotation)
  71.         {
  72.             Vector3 euler = rotation.eulerAngles;
  73.             this.x = euler.y;
  74.             this.y = euler.x;
  75.         }
  76.  
  77.         public void SetAngles(float yaw, float pitch)
  78.         {
  79.             this.x = yaw;
  80.             this.y = pitch;
  81.         }
  82.  
  83.         // Initiate, set the params to the current transformation of the camera relative to the target
  84.         protected virtual void Awake()
  85.         {
  86.             Vector3 angles = transform.eulerAngles;
  87.             x = angles.y;
  88.             y = angles.x;
  89.  
  90.             distanceTarget = distance;
  91.             smoothPosition = transform.position;
  92.  
  93.             cam = GetComponent<Camera>();
  94.  
  95.             lastUp = rotationSpace != null ? rotationSpace.up : Vector3.up;
  96.         }
  97.  
  98.         protected virtual void Update()
  99.         {
  100.             if (updateMode == UpdateMode.Update) UpdateTransform();
  101.         }
  102.  
  103.         protected virtual void FixedUpdate()
  104.         {
  105.             fixedFrame = true;
  106.             fixedDeltaTime += Time.deltaTime;
  107.             if (updateMode == UpdateMode.FixedUpdate) UpdateTransform();
  108.         }
  109.  
  110.         protected virtual void LateUpdate()
  111.         {
  112.             UpdateInput();
  113.  
  114.             if (updateMode == UpdateMode.LateUpdate) UpdateTransform();
  115.  
  116.             if (updateMode == UpdateMode.FixedLateUpdate && fixedFrame)
  117.             {
  118.                 UpdateTransform(fixedDeltaTime);
  119.                 fixedDeltaTime = 0f;
  120.                 fixedFrame = false;
  121.             }
  122.         }
  123.  
  124.         // Read the user input
  125.         public void UpdateInput()
  126.         {
  127.             if (!cam.enabled) return;
  128.  
  129.             // Cursors
  130.             Cursor.lockState = lockCursor ? CursorLockMode.Locked : CursorLockMode.None;
  131.             Cursor.visible = lockCursor ? false : true;
  132.  
  133.             // Should we rotate the camera?
  134.             bool rotate = rotateAlways || (rotateOnLeftButton && Input.GetMouseButton(0)) || (rotateOnRightButton && Input.GetMouseButton(1)) || (rotateOnMiddleButton && Input.GetMouseButton(2));
  135.  
  136.             // delta rotation
  137.             if (rotate)
  138.             {
  139.                 x += Input.GetAxis("Mouse X") * rotationSensitivity;
  140.                 y = ClampAngle(y - Input.GetAxis("Mouse Y") * rotationSensitivity, yMinLimit, yMaxLimit);
  141.             }
  142.  
  143.             // Distance
  144.             distanceTarget = Mathf.Clamp(distanceTarget + zoomAdd, minDistance, maxDistance);
  145.         }
  146.  
  147.         // Update the camera transform
  148.         public void UpdateTransform()
  149.         {
  150.             UpdateTransform(Time.deltaTime);
  151.         }
  152.  
  153.         public void UpdateTransform(float deltaTime)
  154.         {
  155.             if (!cam.enabled) return;
  156.  
  157.             // Rotation
  158.             rotation = Quaternion.AngleAxis(x, Vector3.up) * Quaternion.AngleAxis(y, Vector3.right);
  159.  
  160.             if (rotationSpace != null)
  161.             {
  162.                 r = Quaternion.FromToRotation(lastUp, rotationSpace.up) * r;
  163.                 rotation = r * rotation;
  164.  
  165.                 lastUp = rotationSpace.up;
  166.  
  167.             }
  168.  
  169.             if (target != null)
  170.             {
  171.                 // Distance
  172.                 distance += (distanceTarget - distance) * zoomSpeed * deltaTime;
  173.  
  174.                 // Smooth follow
  175.                 if (!smoothFollow) smoothPosition = target.position;
  176.                 else smoothPosition = Vector3.Lerp(smoothPosition, target.position, deltaTime * followSpeed);
  177.  
  178.                 // Position
  179.                 Vector3 t = smoothPosition + rotation * offset;
  180.                 Vector3 f = rotation * -Vector3.forward;
  181.  
  182.                 if (blockingLayers != -1)
  183.                 {
  184.                     RaycastHit hit;
  185.                     if (Physics.SphereCast(t - f * blockingOriginOffset, blockingRadius, f, out hit, blockingOriginOffset + distanceTarget - blockingRadius, blockingLayers))
  186.                     {
  187.                         blockedDistance = Mathf.SmoothDamp(blockedDistance, hit.distance + blockingRadius * (1f - blockedOffset) - blockingOriginOffset, ref blockedDistanceV, blockingSmoothTime);
  188.                     }
  189.                     else blockedDistance = distanceTarget;
  190.  
  191.                     distance = Mathf.Min(distance, blockedDistance);
  192.                 }
  193.  
  194.                 position = t + f * distance;
  195.  
  196.                 // Translating the camera
  197.                 transform.position = position;
  198.             }
  199.  
  200.             transform.rotation = rotation;
  201.         }
  202.  
  203.         // Zoom input
  204.         private float zoomAdd
  205.         {
  206.             get
  207.             {
  208.                 float scrollAxis = Input.GetAxis("Mouse ScrollWheel");
  209.                 if (scrollAxis > 0) return -zoomSensitivity;
  210.                 if (scrollAxis < 0) return zoomSensitivity;
  211.                 return 0;
  212.             }
  213.         }
  214.  
  215.         // Clamping Euler angles
  216.         private float ClampAngle(float angle, float min, float max)
  217.         {
  218.             if (angle < -360) angle += 360;
  219.             if (angle > 360) angle -= 360;
  220.             return Mathf.Clamp(angle, min, max);
  221.         }
  222.  
  223.     }
  224. }
  225.  
  226.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement