File size: 2,909 Bytes
6cae93f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | using UnityEngine;
namespace UnityAgent
{
/// <summary>
/// Smooth third-person camera with collision handling. Attach to a Camera
/// GameObject and assign the target transform in the inspector.
/// </summary>
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);
}
}
}
|