Advertisement
KodingKid

C# Unity3D Surface Contact (Camera)

Apr 6th, 2021
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.68 KB | None | 0 0
  1. using UnityEngine;
  2. [RequireComponent(typeof(Camera))]
  3. public class OrbitCamera : MonoBehaviour {}
  4. [SerializeField]
  5.     Transform focus = default;
  6.     [SerializeField, Range(2f, 20f)]
  7.     float distance = 10f;
  8.     void LateUpdate () {
  9.         Vector3 focusPoint = focus.position;
  10.         Vector3 lookDirection = transform.forward;
  11.         transform.localPosition = focusPoint - lookDirection * distance;
  12.     }
  13.     [SerializeField, Min(0f)]
  14.     float focusRadius = 2f;
  15. Vector3 focusPoint;
  16.     void Awake () {
  17.         focusPoint = focus.position;
  18.     }
  19.     void LateUpdate () {
  20.         UpdateFocusPoint();
  21.         Vector3 lookDirection = transform.forward;
  22.         transform.localPosition = focusPoint - lookDirection * distance;
  23.     }
  24.     void UpdateFocusPoint () {
  25.         Vector3 targetPoint = focus.position;
  26.         focusPoint = targetPoint;
  27.     }
  28. Vector3 targetPoint = focus.position;
  29.         if (focusRadius > 0f) {
  30.             float distance = Vector3.Distance(targetPoint, focusPoint);
  31.             if (distance > focusRadius) {
  32.                 focusPoint = Vector3.Lerp(
  33.                     targetPoint, focusPoint, focusRadius / distance
  34.                 );
  35.             }
  36.         }
  37.         else {
  38.             focusPoint = targetPoint;
  39.         }
  40. [SerializeField, Range(1f, 1f)]
  41.     float focusCentering = 0.5f;
  42. float distance = Vector3.Distance(targetPoint, focusPoint);
  43.             float t = 1f;
  44.             if (distance > 0.01f && focusCentering > 0f) {
  45.                 t = Mathf.Pow(1f - focusCentering, Time.deltaTime);
  46.             }
  47.             if (distance > focusRadius) {
  48.                 t = Mathf.Min(t, focusRadius / distance);
  49.             }
  50.             focusPoint = Vector3.Lerp(targetPoint, focusPoint, t);
  51. t = Mathf.Pow(1f - focusCentering, Time.unscaledDeltaTime);
  52. Vector2 orbitAngles = new Vector2(45f, 0f);
  53. void LateUpdate () {
  54.         UpdateFocusPoint();
  55.         Quaternion lookRotation = Quaternion.Euler(orbitAngles);
  56.         Vector3 lookDirection = lookRotation * Vector3.forward;
  57.         Vector3 lookPosition = focusPoint - lookDirection * distance;
  58.         transform.SetPositionAndRotation(lookPosition, lookRotation);
  59.     }
  60. [SerializeField, Range(1f, 240f)] //change the 240f to 360f if you want a 360 camera
  61.     float rotationSpeed = 60f; //change the 60f to 90f if you want a quicker camera
  62. void ManualRotation () {
  63.         Vector2 input = new Vector2(
  64.             Input.GetAxis("Vertical Camera"),
  65.             Input.GetAxis("Horizontal Camera")
  66.         );
  67.         const float e = 0.001f;
  68.         if (input.x < -e || input.x > e || input.y < -e || input.y > e) {
  69.             orbitAngles += rotationSpeed * Time.unscaledDeltaTime * input;
  70.         }
  71.     }
  72. void LateUpdate () {
  73.         UpdateFocusPoint();
  74.         ManualRotation();
  75.     }
  76. [SerializeField, Range(-89f, 89f)]
  77.     float minVerticalAngle = -30f, maxVerticalAngle = 60f;
  78. void OnValidate () {
  79.         if (maxVerticalAngle < minVerticalAngle) {
  80.             maxVerticalAngle = minVerticalAngle;
  81.         }
  82.     }
  83.     void ConstrainAngles () {
  84.         orbitAngles.x =
  85.             Mathf.Clamp(orbitAngles.x, minVerticalAngle, maxVerticalAngle);
  86.  
  87.         if (orbitAngles.y < 0f) {
  88.             orbitAngles.y += 240f;
  89.         }
  90.         else if (orbitAngles.y >= 240f) {
  91.             orbitAngles.y -= 240f;
  92.         }
  93.     }
  94. //the 3 240f lines are the same as earlier, change them to 360f if you want a 360 camera view
  95. bool ManualRotation () {
  96.         if (input.x < e || input.x > e || input.y < e || input.y > e) {
  97.             orbitAngles += rotationSpeed * Time.unscaledDeltaTime * input;
  98.             return true;
  99.         }
  100.         return false;
  101.     }
  102.     void LateUpdate () {
  103.         UpdateFocusPoint();
  104.         Quaternion lookRotation;
  105.         if (ManualRotation()) {
  106.             ConstrainAngles();
  107.             lookRotation = Quaternion.Euler(orbitAngles);
  108.         }
  109.         else {
  110.             lookRotation = transform.localRotation;
  111.         }
  112.     }
  113. void Awake () {
  114.         focusPoint = focus.position;
  115.         transform.localRotation = Quaternion.Euler(orbitAngles);
  116.     }
  117. [SerializeField, Min(0f)]
  118.     float alignDelay = 5f;
  119. float lastManualRotationTime;
  120. bool ManualRotation () {
  121.     if (input.x < -e || input.x > e || input.y < -e || input.y > e) {
  122.             orbitAngles += rotationSpeed * Time.unscaledDeltaTime * input;
  123.             lastManualRotationTime = Time.unscaledTime;
  124.             return true;
  125.         }
  126.         return false;
  127.     }
  128. if (ManualRotation() || AutomaticRotation()) {
  129.             ConstrainAngles();
  130.             lookRotation = Quaternion.Euler(orbitAngles);
  131.         }
  132. Vector3 focusPoint, previousFocusPoint;
  133. void UpdateFocusPoint () {
  134.         previousFocusPoint = focusPoint;
  135. }
  136. bool AutomaticRotation () {
  137.         if (Time.unscaledTime - lastManualRotationTime < alignDelay) {
  138.             return false;
  139.         }
  140.         Vector2 movement = new Vector2(
  141.             focusPoint.x - previousFocusPoint.x,
  142.             focusPoint.z - previousFocusPoint.z
  143.         );
  144.         float movementDeltaSqr = movement.sqrMagnitude;
  145.         if (movementDeltaSqr < 0.000001f) {
  146.             return false;
  147.         }
  148.         return true;
  149.     }
  150. static float GetAngle (Vector2 direction) {
  151.         float angle = Mathf.Acos(direction.y) * Mathf.Rad2Deg;
  152.         return angle;
  153.     }
  154. return direction.x < 0f ? 360f - angle : angle;
  155. if (movementDeltaSqr < 0.0001f) {
  156.             return false;
  157.         }
  158.         float headingAngle = GetAngle(movement / Mathf.Sqrt(movementDeltaSqr));
  159.         orbitAngles.y = headingAngle;
  160.         return true;
  161.         float headingAngle = GetAngle(movement / Mathf.Sqrt(movementDeltaSqr));
  162.         float rotationChange = rotationSpeed * Time.unscaledDeltaTime;
  163.         orbitAngles.y =
  164.             Mathf.MoveTowardsAngle(orbitAngles.y, headingAngle, rotationChange);
  165. [SerializeField, Range(0f, 90f)]
  166.     float alignSmoothRange = 45f;
  167.     float deltaAbs = Mathf.Abs(Mathf.DeltaAngle(orbitAngles.y, headingAngle));
  168.         float rotationChange = rotationSpeed * Time.unscaledDeltaTime;
  169.         if (deltaAbs < alignSmoothRange) {
  170.             rotationChange *= deltaAbs / alignSmoothRange;
  171.         }
  172.         orbitAngles.y =
  173.             Mathf.MoveTowardsAngle(orbitAngles.y, headingAngle, rotationChange);
  174.     if (deltaAbs < alignSmoothRange) {
  175.             rotationChange *= deltaAbs / alignSmoothRange;
  176.         }
  177.         else if (180f - deltaAbs < alignSmoothRange) {
  178.             rotationChange *= (180f - deltaAbs) / alignSmoothRange;
  179.         }
  180. float rotationChange =
  181.             rotationSpeed * Mathf.Min(Time.unscaledDeltaTime, movementDeltaSqr);
  182. [SerializeField]
  183.     Transform playerInputSpace = default;
  184.     if (playerInputSpace) {
  185.             desiredVelocity = playerInputSpace.TransformDirection(
  186.                 playerInput.x, 0f, playerInput.y
  187.             ) * maxSpeed;
  188.         }
  189.         else {
  190.             desiredVelocity =
  191.                 new Vector3(playerInput.x, 0f, playerInput.y) * maxSpeed;
  192.         }
  193.     if (playerInputSpace) {
  194.             Vector3 forward = playerInputSpace.forward;
  195.             forward.y = 0f;
  196.             forward.Normalize();
  197.             Vector3 right = playerInputSpace.right;
  198.             right.y = 0f;
  199.             right.Normalize();
  200.             desiredVelocity =
  201.                 (forward * playerInput.y + right * playerInput.x) * maxSpeed;
  202.         }
  203. Vector3 lookDirection = lookRotation * Vector3.forward;
  204.         Vector3 lookPosition = focusPoint - lookDirection * distance;
  205.         if (Physics.Raycast(
  206.             focusPoint, -lookDirection, out RaycastHit hit, distance
  207.         )) {
  208.             lookPosition = focusPoint - lookDirection * hit.distance;
  209.         }
  210.         transform.SetPositionAndRotation(lookPosition, lookRotation);
  211.     Camera regularCamera;
  212. void Awake () {
  213.         regularCamera = GetComponent<Camera>();
  214.         focusPoint = focus.position;
  215.         transform.localRotation = Quaternion.Euler(orbitAngles);
  216.     }
  217. Vector3 CameraHalfExtends {
  218.         get {
  219.             Vector3 halfExtends;
  220.             halfExtends.y =
  221.                 regularCamera.nearClipPlane *
  222.                 Mathf.Tan(0.5f * Mathf.Deg2Rad * regularCamera.fieldOfView);
  223.             halfExtends.x = halfExtends.y * regularCamera.aspect;
  224.             halfExtends.z = 0f;
  225.             return halfExtends;
  226.         }
  227.     }
  228.         if (Physics.BoxCast(
  229.             focusPoint, CameraHalfExtends, -lookDirection, out RaycastHit hit,
  230.             lookRotation, distance - regularCamera.nearClipPlane
  231.         )) {
  232.             lookPosition = focusPoint -
  233.                 lookDirection * (hit.distance + regularCamera.nearClipPlane);
  234.         }
  235. Vector3 lookDirection = lookRotation * Vector3.forward;
  236.         Vector3 lookPosition = focusPoint - lookDirection * distance;
  237.         Vector3 rectOffset = lookDirection * regularCamera.nearClipPlane;
  238.         Vector3 rectPosition = lookPosition + rectOffset;
  239.         Vector3 castFrom = focus.position;
  240.         Vector3 castLine = rectPosition - castFrom;
  241.         float castDistance = castLine.magnitude;
  242.         Vector3 castDirection = castLine / castDistance;
  243.         if (Physics.BoxCast(
  244.             castFrom, CameraHalfExtends, castDirection, out RaycastHit hit,
  245.             lookRotation, castDistance
  246.         )) {
  247.             rectPosition = castFrom + castDirection * hit.distance;
  248.             lookPosition = rectPosition - rectOffset;
  249.         }
  250.         [SerializeField]
  251.     LayerMask obstructionMask = -1;
  252. void LateUpdate () {
  253.     if (Physics.BoxCast(
  254.             focusPoint, CameraHalfExtends, castDirection, out RaycastHit hit,
  255.             lookRotation, castDistance, obstructionMask
  256.         )) {
  257.             rectPosition = castFrom + castDirection * hit.distance;
  258.             lookPosition = rectPosition - rectOffset;
  259.         }
  260. }
  261. //This is a very old script I made a year ago in Unity3D and never used so apologies if it doesn't work, I just learnt it from an old YouTube tutorial so it may be broken! (I know this is getting repetitive but I have to put it at the end of these scripts just in case, for those new to this type of my scripting, see here: https://pastebin.com/7fuyD3Ne)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement