CCCPaste Login

CameraController

public class CameraController : MonoBehaviour
{
    private Camera _camera;
    private float _defaultFov;
    private float _currentFov;
    private float _currentTilt;
    [SerializeField] private float _fovChangeOnRun = 10f;
    [SerializeField] private float _fovLerpSpeed = 2f;
    [SerializeField] private float _fovLerpReturn = 10f;
    [SerializeField] private float _tiltLerpSpeed = 4f;
    [SerializeField] private float _tiltLerpReturn = 10f;
    [SerializeField] private float _tiltAmount = 1f;
    [SerializeField] float _bobSpeed = 14f;
    [SerializeField] float _bobAmount = 0.02f;

    private Vector2 _rawLookInput;
    private Vector2 _lookInputReady;

    [SerializeField] private float _horizSensitity;
    [SerializeField] private float _verticalSensitity;
    [SerializeField] private float _sensitivityMultiplierOnForwardRun = 0.6f;

    private float _xRotation;
    private float _yRotation;
    private float _maxVertLookDegree = 80;

    private void Start()
    {
        _camera = GetComponent();
        _yRotation = transform.localRotation.eulerAngles.y;
        _defaultFov = _camera.fieldOfView;
        _currentFov = _camera.fieldOfView;
        Cursor.lockState = CursorLockMode.Locked;
    }

    private void Update()
    {
        var inputManager = FirstPersonCharacter.Instance.InputManager;

        _rawLookInput = inputManager.LookInput;
        _rawLookInput.x *= _horizSensitity;
        _rawLookInput.y *= _verticalSensitity;
        _lookInputReady = _rawLookInput;

        // Vertical look
        _xRotation -= _lookInputReady.y;
        _xRotation = Mathf.Clamp(_xRotation, -_maxVertLookDegree, _maxVertLookDegree);

        // Horizontal look
        _yRotation += inputManager.RunForward
            ? _lookInputReady.x * _sensitivityMultiplierOnForwardRun
            : _lookInputReady.x;

        float tilt = 0f;
        if (inputManager.MoveOblique && inputManager.Running && inputManager.MoveInput.x > 0)
        {
            tilt = _tiltAmount;
        }
        else if (inputManager.MoveOblique && inputManager.Running && inputManager.MoveInput.x < 0)
        {
            tilt = -_tiltAmount;
        }

        float tiltLerpSpeed = inputManager.MoveSideway
            ? _tiltLerpSpeed
            : _tiltLerpReturn;

        _currentTilt = Mathf.Lerp(_currentTilt, tilt, Time.deltaTime * tiltLerpSpeed);

        float lerpSpeed = inputManager.RunForward ? _fovLerpSpeed : _fovLerpReturn;
        float targetFov = inputManager.RunForward
            ? _defaultFov - _fovChangeOnRun 
            : _defaultFov;

        _currentFov = Mathf.Lerp(_currentFov, targetFov, Time.deltaTime * lerpSpeed);
        _camera.fieldOfView = _currentFov;

        UpdateHeadBob(inputManager);

        FirstPersonCharacter.Instance.transform.localRotation = Quaternion.Euler(0f, _yRotation, 0f);
        transform.localRotation = Quaternion.Euler(_xRotation, _yRotation, _currentTilt);
    }

    private void UpdateHeadBob(PlayerInputManager inputManager)
    {
        if (inputManager.MoveInput != Vector2.zero)
        {
            float waveSlice = Mathf.Sin(Time.time * _bobSpeed);
            float totalBob = waveSlice * _bobAmount;
            transform.localPosition = new Vector3(
                transform.localPosition.x,
                FirstPersonCharacter.Instance.CamPositionTr.position.y + totalBob,
                transform.localPosition.z);
        }
    }
}