|
|
using UnityEngine;
|
|
|
|
|
|
[RequireComponent(typeof(Camera))]
|
|
|
public class CameraController : MonoBehaviour
|
|
|
{
|
|
|
[Header("Target")]
|
|
|
[Tooltip("If set, camera will follow this Transform. Otherwise it will auto-find the local player.")]
|
|
|
[SerializeField] private Transform target;
|
|
|
|
|
|
[Header("Zoom Settings")]
|
|
|
[SerializeField] private float baseDistance = 6f;
|
|
|
[SerializeField] private float maxDistance = 12f;
|
|
|
[SerializeField] private float zoomSpeed = 5f;
|
|
|
|
|
|
[Header("Follow Settings")]
|
|
|
[SerializeField] private float followSmoothness = 5f;
|
|
|
[SerializeField] private Vector3 heightOffset = new Vector3(0, 3f, 0);
|
|
|
|
|
|
private Rigidbody targetRb;
|
|
|
private float currentDistance;
|
|
|
private Camera cam;
|
|
|
|
|
|
private void Start()
|
|
|
{
|
|
|
Application.targetFrameRate = 120;
|
|
|
cam = GetComponent<Camera>();
|
|
|
currentDistance = baseDistance;
|
|
|
|
|
|
if (target != null)
|
|
|
{
|
|
|
// User assigned a target in the Inspector
|
|
|
InitializeTarget();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// No target assigned, try to auto-find after a short delay
|
|
|
Invoke(nameof(FindLocalPlayer), 0.5f);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void InitializeTarget()
|
|
|
{
|
|
|
targetRb = target.GetComponent<Rigidbody>();
|
|
|
if (targetRb == null)
|
|
|
{
|
|
|
Debug.LogError("CameraController: Assigned target has no Rigidbody component.", this);
|
|
|
enabled = false;
|
|
|
return;
|
|
|
}
|
|
|
Debug.Log("CameraController: Following manually assigned target.", this);
|
|
|
}
|
|
|
|
|
|
private void FindLocalPlayer()
|
|
|
{
|
|
|
foreach (var vehicle in FindObjectsOfType<VehicleController>())
|
|
|
{
|
|
|
// VehicleController inherits NetworkBehaviour, so .Object is the NetworkObject
|
|
|
if (vehicle.Object != null && vehicle.Object.HasInputAuthority)
|
|
|
{
|
|
|
target = vehicle.FollowTarget;
|
|
|
InitializeTarget();
|
|
|
Debug.Log("CameraController: Auto-found local player to follow.", this);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Debug.LogWarning("CameraController: No local player found to follow <20> disabling.", this);
|
|
|
enabled = false;
|
|
|
}
|
|
|
|
|
|
private void LateUpdate()
|
|
|
{
|
|
|
if (target == null || targetRb == null) return;
|
|
|
|
|
|
float speed = targetRb.velocity.magnitude;
|
|
|
float targetDistance = Mathf.Lerp(baseDistance, maxDistance, speed / 30f);
|
|
|
currentDistance = Mathf.Lerp(currentDistance, targetDistance, Time.deltaTime * zoomSpeed);
|
|
|
|
|
|
Vector3 followPos = target.position
|
|
|
+ heightOffset
|
|
|
- target.forward * currentDistance;
|
|
|
|
|
|
transform.position = Vector3.Lerp(transform.position, followPos, Time.deltaTime * followSmoothness);
|
|
|
transform.LookAt(target.position + heightOffset * 0.5f);
|
|
|
}
|
|
|
}
|