using UnityEngine;

[System.Serializable]

public class SimpleSpring

{

[HideInInspector]

public float currentPosition; // Current position of the spring

[HideInInspector]

public float currentVelocity; // Current velocity

[HideInInspector]

public float targetPosition; // Desired rest position

[Tooltip("How fast the spring moves toward the target (Hz)")]

public float frequency; // Frequency in Hertz — higher = snappier

[Tooltip("How much the spring resists overshoot (1 = critically damped)")]

[Range(0f, 2f)]

public float dampingRatio; // 1 = no overshoot, <1 = bouncy, >1 = sluggish

public SimpleSpring(float startPosition = 0f, float frequency = 2f, float dampingRatio = 0.5f)

{

this.currentPosition = startPosition;

this.targetPosition = startPosition;

this.frequency = frequency;

this.dampingRatio = dampingRatio;

this.currentVelocity = 0f;

}

public void Simulate(float deltaTime)

{

// Convert intuitive params to physical constants

float k = Mathf.Pow(2f * Mathf.PI * frequency, 2f); // stiffness

float c = 2f * dampingRatio * Mathf.Sqrt(k); // damping coefficient

// Classic semi-implicit Euler integration

float acceleration = -k * (currentPosition - targetPosition) - c * currentVelocity;

currentVelocity += acceleration * deltaTime;

currentPosition += currentVelocity * deltaTime;

}

}