Advertisement
Guest User

Untitled

a guest
Jul 20th, 2024
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.56 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6. namespace KinematicCharacterController.Examples
  7. {
  8. public class ExampleCharacterCamera : MonoBehaviour
  9. {
  10. [Header("Framing")]
  11. public Camera Camera;
  12. public Vector2 FollowPointFraming = new Vector2(0f, 0f);
  13. public float FollowingSharpness = 10000f;
  14.  
  15. [Header("Distance")]
  16. public float DefaultDistance = 6f;
  17. public float MinDistance = 0f;
  18. public float MaxDistance = 10f;
  19. public float DistanceMovementSpeed = 5f;
  20. public float DistanceMovementSharpness = 10f;
  21.  
  22. [Header("Rotation")]
  23. public bool InvertX = false;
  24. public bool InvertY = false;
  25. [Range(-90f, 90f)]
  26. public float DefaultVerticalAngle = 20f;
  27. [Range(-90f, 90f)]
  28. public float MinVerticalAngle = -90f;
  29. [Range(-90f, 90f)]
  30. public float MaxVerticalAngle = 90f;
  31. public float RotationSpeed = 1f;
  32. public float RotationSharpness = 10000f;
  33. public bool RotateWithPhysicsMover = false;
  34.  
  35. [Header("Obstruction")]
  36. public float ObstructionCheckRadius = 0.2f;
  37. public LayerMask ObstructionLayers = -1;
  38. public float ObstructionSharpness = 10000f;
  39. public List<Collider> IgnoredColliders = new List<Collider>();
  40.  
  41. public Transform Transform { get; private set; }
  42. public Transform FollowTransform { get; private set; }
  43.  
  44. public Vector3 PlanarDirection { get; set; }
  45. public float TargetDistance { get; set; }
  46.  
  47. private bool _distanceIsObstructed;
  48. private float _currentDistance;
  49. private float _targetVerticalAngle;
  50. private RaycastHit _obstructionHit;
  51. private int _obstructionCount;
  52. private RaycastHit[] _obstructions = new RaycastHit[MaxObstructions];
  53. private float _obstructionTime;
  54. private Vector3 _currentFollowPosition;
  55.  
  56. private const int MaxObstructions = 32;
  57.  
  58. void OnValidate()
  59. {
  60. DefaultDistance = Mathf.Clamp(DefaultDistance, MinDistance, MaxDistance);
  61. DefaultVerticalAngle = Mathf.Clamp(DefaultVerticalAngle, MinVerticalAngle, MaxVerticalAngle);
  62. }
  63.  
  64. void Awake()
  65. {
  66. Transform = this.transform;
  67.  
  68. _currentDistance = DefaultDistance;
  69. TargetDistance = _currentDistance;
  70.  
  71. _targetVerticalAngle = 0f;
  72.  
  73. PlanarDirection = Vector3.forward;
  74. }
  75.  
  76. // Set the transform that the camera will orbit around
  77. public void SetFollowTransform(Transform t)
  78. {
  79. FollowTransform = t;
  80. PlanarDirection = FollowTransform.forward;
  81. _currentFollowPosition = FollowTransform.position;
  82. }
  83.  
  84. public void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
  85. {
  86. if (FollowTransform)
  87. {
  88. if (InvertX)
  89. {
  90. rotationInput.x *= -1f;
  91. }
  92. if (InvertY)
  93. {
  94. rotationInput.y *= -1f;
  95. }
  96.  
  97. // Process rotation input
  98. Quaternion horizontalRotationFromInput = Quaternion.Euler(0f, rotationInput.x * RotationSpeed, 0f);
  99. Quaternion verticalRotationFromInput = Quaternion.Euler(-rotationInput.y * RotationSpeed, 0f, 0f);
  100.  
  101. // Apply horizontal rotation
  102. PlanarDirection = horizontalRotationFromInput * PlanarDirection;
  103. PlanarDirection = Vector3.ProjectOnPlane(PlanarDirection, Vector3.up).normalized;
  104. Quaternion planarRot = Quaternion.LookRotation(PlanarDirection, Vector3.up);
  105.  
  106. // Apply vertical rotation
  107. _targetVerticalAngle -= rotationInput.y * RotationSpeed;
  108. _targetVerticalAngle = Mathf.Clamp(_targetVerticalAngle, MinVerticalAngle, MaxVerticalAngle);
  109. Quaternion verticalRot = Quaternion.Euler(_targetVerticalAngle, 0, 0);
  110.  
  111. // Combine rotations and apply to camera
  112. Quaternion targetRotation = Quaternion.Slerp(Transform.rotation, planarRot * verticalRot, 1f - Mathf.Exp(-RotationSharpness * deltaTime));
  113. Transform.rotation = targetRotation;
  114. // Apply rotation
  115. Transform.rotation = targetRotation;
  116.  
  117. // Process distance input
  118. if (_distanceIsObstructed && Mathf.Abs(zoomInput) > 0f)
  119. {
  120. TargetDistance = _currentDistance;
  121. }
  122. TargetDistance += zoomInput * DistanceMovementSpeed;
  123. TargetDistance = Mathf.Clamp(TargetDistance, MinDistance, MaxDistance);
  124.  
  125. // Find the smoothed follow position
  126. _currentFollowPosition = Vector3.Lerp(_currentFollowPosition, FollowTransform.position, 1f - Mathf.Exp(-FollowingSharpness * deltaTime));
  127.  
  128. // Handle obstructions
  129. {
  130. RaycastHit closestHit = new RaycastHit();
  131. closestHit.distance = Mathf.Infinity;
  132. _obstructionCount = Physics.SphereCastNonAlloc(_currentFollowPosition, ObstructionCheckRadius, -Transform.forward, _obstructions, TargetDistance, ObstructionLayers, QueryTriggerInteraction.Ignore);
  133. for (int i = 0; i < _obstructionCount; i++)
  134. {
  135. bool isIgnored = false;
  136. for (int j = 0; j < IgnoredColliders.Count; j++)
  137. {
  138. if (IgnoredColliders[j] == _obstructions[i].collider)
  139. {
  140. isIgnored = true;
  141. break;
  142. }
  143. }
  144. for (int j = 0; j < IgnoredColliders.Count; j++)
  145. {
  146. if (IgnoredColliders[j] == _obstructions[i].collider)
  147. {
  148. isIgnored = true;
  149. break;
  150. }
  151. }
  152.  
  153. if (!isIgnored && _obstructions[i].distance < closestHit.distance && _obstructions[i].distance > 0)
  154. {
  155. closestHit = _obstructions[i];
  156. }
  157. }
  158.  
  159. // If obstructions detecter
  160. if (closestHit.distance < Mathf.Infinity)
  161. {
  162. _distanceIsObstructed = true;
  163. _currentDistance = Mathf.Lerp(_currentDistance, closestHit.distance, 1 - Mathf.Exp(-ObstructionSharpness * deltaTime));
  164. }
  165. // If no obstruction
  166. else
  167. {
  168. _distanceIsObstructed = false;
  169. _currentDistance = Mathf.Lerp(_currentDistance, TargetDistance, 1 - Mathf.Exp(-DistanceMovementSharpness * deltaTime));
  170. }
  171. }
  172.  
  173. // Find the smoothed camera orbit position
  174. Vector3 targetPosition = _currentFollowPosition - ((targetRotation * Vector3.forward) * _currentDistance);
  175.  
  176. // Handle framing
  177. targetPosition += Transform.right * FollowPointFraming.x;
  178. targetPosition += Transform.up * FollowPointFraming.y;
  179.  
  180. // Apply position
  181. Transform.position = targetPosition;
  182. }
  183. }
  184. }
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement