using UnityEngine; public class WeaponBob : MonoBehaviour { [Header("Bob Settings")] public float bobFrequency = 10f; public float bobHorizontalAmplitude = 0.05f; public float bobVerticalAmplitude = 0.03f; [Header("Sprint Multiplier")] public float sprintBobMultiplier = 1.5f; [Header("Smoothing")] public float returnSpeed = 6f; private Vector3 originalLocalPos; private float bobTimer = 0f; private CharacterController controller; void Start() { originalLocalPos = transform.localPosition; controller = GetComponentInParent(); } void Update() { if (controller == null) return; // Check if the player is moving on the ground Vector3 horizontalVelocity = new Vector3(controller.velocity.x, 0f, controller.velocity.z); bool isMoving = horizontalVelocity.magnitude > 0.5f && controller.isGrounded; if (isMoving) { float multiplier = Input.GetKey(KeyCode.LeftShift) ? sprintBobMultiplier : 1f; bobTimer += Time.deltaTime * bobFrequency * multiplier; float bobX = Mathf.Sin(bobTimer) * bobHorizontalAmplitude * multiplier; // Abs(Sin) means the weapon bounces UP on every step (left and right) // instead of looping in a circle/figure-8 float bobY = Mathf.Abs(Mathf.Sin(bobTimer)) * bobVerticalAmplitude * multiplier; transform.localPosition = originalLocalPos + new Vector3(bobX, bobY, 0f); } else { // Don't reset bobTimer so the phase doesn't snap when you start moving again transform.localPosition = Vector3.Lerp( transform.localPosition, originalLocalPos, Time.deltaTime * returnSpeed ); } } }