Files
PGiZ3/Assets/Code/Gameplay/Camera/CameraController.cs
T
2026-02-24 10:33:33 +03:00

103 lines
3.3 KiB
C#

using Code.DI;
using Code.Input;
using UnityEngine;
namespace Code.Gameplay.Camera
{
public class CameraController : MonoBehaviour
{
[SerializeField] private float rotationSpeed = 0.3f;
[SerializeField] private float rotationSharpness = 50f;
[SerializeField] private float followSharpness = 50f;
[SerializeField] private float minVerticalAngle = -60f;
[SerializeField] private float maxVerticalAngle = 60f;
[SerializeField] private float defaultVerticalAngle;
[SerializeField] private Transform followTransform;
private UnityEngine.Camera _camera;
private Vector3 _currentFollowPosition;
private Vector3 _planarDirection;
private float _targetVerticalAngle;
private IInputService _inputService;
private void Awake()
{
_camera = GetComponent<UnityEngine.Camera>();
if (!_camera)
{
enabled = false;
return;
}
Initialize();
}
private void Start()
{
_inputService = FindFirstObjectByType<DIContainer>().Resolve<IInputService>();
}
private void Initialize()
{
_targetVerticalAngle = Mathf.Clamp(defaultVerticalAngle, minVerticalAngle, maxVerticalAngle);
_planarDirection = followTransform != null ? followTransform.forward : Vector3.forward;
_currentFollowPosition = followTransform != null ? followTransform.position : Vector3.zero;
}
private void LateUpdate()
{
if (followTransform)
{
UpdateCamera(Time.deltaTime, GetLookInput());
}
}
private void UpdateCamera(float deltaTime, Vector3 lookInput)
{
HandleRotation(deltaTime, lookInput);
HandlePosition(deltaTime);
}
private void HandleRotation(float deltaTime, Vector3 lookInput)
{
var horizontalRotation = Quaternion.Euler(Vector3.up * (lookInput.x * rotationSpeed));
_planarDirection = horizontalRotation * _planarDirection;
var planarRotation = Quaternion.LookRotation(_planarDirection, followTransform.up);
_targetVerticalAngle -= lookInput.y * rotationSpeed;
_targetVerticalAngle = Mathf.Clamp(_targetVerticalAngle, minVerticalAngle, maxVerticalAngle);
var verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0);
var targetRotation = planarRotation * verticalRotation;
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, deltaTime * rotationSharpness);
}
private void HandlePosition(float deltaTime)
{
_currentFollowPosition = Vector3.Lerp(
_currentFollowPosition,
followTransform.position,
1f - Mathf.Exp(-followSharpness * deltaTime)
);
transform.position = _currentFollowPosition;
}
private Vector3 GetLookInput()
{
return _inputService.LookInput;
}
public Quaternion GetCameraRotation()
{
return transform.rotation;
}
public Vector3 GetPlanarDirection()
{
return _planarDirection;
}
}
}