Files
PIM_8/Assets/_Scripts/CameraController.cs
T

127 lines
3.5 KiB
C#
Raw Normal View History

2026-06-04 15:45:39 +03:00
using System.Collections;
using UnityEngine;
public class CameraController : MonoBehaviour
{
[Header("Follow")]
public Transform target;
public Vector3 followOffset = new Vector3(0f, 1.7f, -3.5f);
public float followSmooth = 10f;
public float rotationSmooth = 12f;
[Header("Fixed Camera")]
public float transitionTime = 1.1f;
public DepthOfFieldController depthOfFieldController;
public bool IsInFixedMode { get; private set; }
private float pitch;
private Coroutine fixedCameraRoutine;
private void Start()
{
SnapToFollowPosition();
}
private void LateUpdate()
{
if (IsInFixedMode || target == null)
{
return;
}
// Normal mode: keep the rig behind the player and match the player's yaw plus camera pitch.
Vector3 desiredPosition = GetFollowPosition();
Quaternion desiredRotation = GetFollowRotation();
transform.position = Vector3.Lerp(transform.position, desiredPosition, followSmooth * Time.deltaTime);
transform.rotation = Quaternion.Slerp(transform.rotation, desiredRotation, rotationSmooth * Time.deltaTime);
}
public void SetPitch(float newPitch)
{
pitch = newPitch;
}
public void SetFixedCamera(Transform point, float duration)
{
if (point == null)
{
return;
}
if (fixedCameraRoutine != null)
{
StopCoroutine(fixedCameraRoutine);
}
fixedCameraRoutine = StartCoroutine(FixedCameraRoutine(point, duration));
}
private IEnumerator FixedCameraRoutine(Transform point, float duration)
{
IsInFixedMode = true;
depthOfFieldController?.EnableFocus(point);
// Attention mode: move to the authored point, hold the shot, then return control to the player.
yield return MoveCamera(transform.position, transform.rotation, point.position, point.rotation, transitionTime);
yield return new WaitForSeconds(duration);
yield return MoveCamera(transform.position, transform.rotation, GetFollowPosition(), GetFollowRotation(), transitionTime);
depthOfFieldController?.DisableFocus();
IsInFixedMode = false;
fixedCameraRoutine = null;
}
private IEnumerator MoveCamera(Vector3 startPosition, Quaternion startRotation, Vector3 endPosition, Quaternion endRotation, float time)
{
float timer = 0f;
while (timer < time)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / time);
transform.position = Vector3.Lerp(startPosition, endPosition, t);
transform.rotation = Quaternion.Slerp(startRotation, endRotation, t);
yield return null;
}
transform.position = endPosition;
transform.rotation = endRotation;
}
private Vector3 GetFollowPosition()
{
if (target == null)
{
return transform.position;
}
Quaternion yawRotation = Quaternion.Euler(0f, target.eulerAngles.y, 0f);
return target.position + yawRotation * followOffset;
}
private Quaternion GetFollowRotation()
{
if (target == null)
{
return transform.rotation;
}
return Quaternion.Euler(pitch, target.eulerAngles.y, 0f);
}
private void SnapToFollowPosition()
{
if (target == null)
{
return;
}
transform.position = GetFollowPosition();
transform.rotation = GetFollowRotation();
}
}