using UnityEngine; namespace UnityAgent { /// /// Smooth third-person camera with collision handling. Attach to a Camera /// GameObject and assign the target transform in the inspector. /// public class ThirdPersonCamera : MonoBehaviour { [Header("Target")] public Transform target; [Header("Positioning")] public Vector3 pivotOffset = new Vector3(0f, 1.5f, 0f); public float distance = 5f; public float minDistance = 1.5f; public float maxDistance = 8f; public float height = 1.2f; [Header("Smoothing")] public float positionSmooth = 10f; public float rotationSmooth = 10f; [Header("Collision")] public LayerMask collisionMask = ~0; public float collisionRadius = 0.3f; [Header("Input")] public bool useMouseOrbit = true; public float mouseSensitivity = 3f; public float minPitch = -30f; public float maxPitch = 75f; private float _yaw; private float _pitch = 15f; private float _currentDistance; private void Start() { _currentDistance = distance; if (target != null) { Vector3 e = transform.eulerAngles; _yaw = e.y; _pitch = e.x; } Cursor.lockState = CursorLockMode.Locked; } private void LateUpdate() { if (target == null) return; if (useMouseOrbit) { _yaw += Input.GetAxis("Mouse X") * mouseSensitivity; _pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity; _pitch = Mathf.Clamp(_pitch, minPitch, maxPitch); } Quaternion rotation = Quaternion.Euler(_pitch, _yaw, 0f); Vector3 pivot = target.position + pivotOffset; // Desired camera position. Vector3 desired = pivot + rotation * new Vector3(0f, height, -distance); // Collision: shrink the distance if there's an obstacle. if (Physics.SphereCast( pivot, collisionRadius, (desired - pivot).normalized, out RaycastHit hit, distance, collisionMask, QueryTriggerInteraction.Ignore)) { _currentDistance = Mathf.Clamp(hit.distance, minDistance, distance); } else { _currentDistance = Mathf.Lerp(_currentDistance, distance, Time.deltaTime * 4f); } Vector3 finalPos = pivot + rotation * new Vector3(0f, height, -_currentDistance); transform.position = Vector3.Lerp(transform.position, finalPos, positionSmooth * Time.deltaTime); transform.rotation = Quaternion.Slerp( transform.rotation, rotation, rotationSmooth * Time.deltaTime); } } }