using Unity.Cinemachine; using UnityEngine; using UnityEngine.InputSystem; public class HeadBobbing : MonoBehaviour { [Header("References")] [SerializeField] private InputHolder inputHolder; [SerializeField] private PlayerMovement playerMovement; [SerializeField] private CinemachineCamera vCam; [Space] [Header("Noise Profiles")] [SerializeField] private NoiseSettings headbob_Idle; [SerializeField] private NoiseSettings headbob_Walking; [SerializeField] private NoiseSettings headbob_Sprinting; [SerializeField] private NoiseSettings headbob_IdleCrouch; [SerializeField] private float fadeSpeed; [SerializeField] private float idleAmplitude = 0.1f; [SerializeField] private float idleFrequency = 0.5f; [SerializeField] private float walkAmplitude = 0.6f; [SerializeField] private float walkFrequency = 1.5f; [SerializeField] private float sprintAmplitude = 1.1f; [SerializeField] private float sprintFrequency = 2.2f; [SerializeField] private float crouchAmplitude = 0.05f; [SerializeField] private float crouchFrequency = 0.4f; private CinemachineBasicMultiChannelPerlin noise; private Vector2 moveInput; private HeadBobState currentState; private float targetAmplitude; private float targetFrequency; private enum HeadBobState { Idle, Walk, Sprint, IdleCrouch } private void Awake() { noise = vCam.GetComponent<CinemachineBasicMultiChannelPerlin>(); targetAmplitude = noise.AmplitudeGain; targetFrequency = noise.FrequencyGain; } private void Update() { ReadInput(); UpdateHeadBobState(); noise.AmplitudeGain = Mathf.MoveTowards(noise.AmplitudeGain, targetAmplitude, Time.deltaTime * fadeSpeed); noise.FrequencyGain = Mathf.MoveTowards(noise.FrequencyGain, targetFrequency, Time.deltaTime * fadeSpeed); } private void UpdateHeadBobState() { bool isMoving = moveInput.sqrMagnitude > 0.01f; bool isSprinting = inputHolder.runAction.action.IsPressed(); if (!isMoving) { if (playerMovement.isCrouching) SetState(HeadBobState.IdleCrouch); else SetState(HeadBobState.Idle); } else { if (isSprinting) SetState(HeadBobState.Sprint); else SetState(HeadBobState.Walk); } } private void SetState(HeadBobState newState) { if (currentState == newState) return; currentState = newState; switch (newState) { case HeadBobState.Idle: noise.NoiseProfile = headbob_Idle; targetAmplitude = idleAmplitude; targetFrequency = idleFrequency; break; case HeadBobState.Walk: noise.NoiseProfile = headbob_Walking; targetAmplitude = walkAmplitude; targetFrequency = walkFrequency; break; case HeadBobState.Sprint: noise.NoiseProfile = headbob_Sprinting; targetAmplitude = sprintAmplitude; targetFrequency = sprintFrequency; break; case HeadBobState.IdleCrouch: noise.NoiseProfile = headbob_IdleCrouch; targetAmplitude = crouchAmplitude; targetFrequency = crouchFrequency; break; } } private void ReadInput() { moveInput = inputHolder.moveAction.action.ReadValue<Vector2>(); } }