inconsistency in results with code calculating the distance traveled to integral of the function tha

so I have functions here y = (t/8)^2 where y is the speed and I move the object by this acceleration along the x axis just like here in the code (attachment one) and for time = 2, the object moved 28 units that is, for the integral I calculated, the result should theoretically be the same, but it is not (calculations in the second appendix) I think I have a bad understanding of how the program performs calculations in the update method or I’ve messed something up, so I’m asking an experienced person to correct me, thank you.

public class Movement : MonoBehaviour
{
   [SerializeField] private float time = 0f;
   [SerializeField] private float distanceTraveled;
   [SerializeField] private bool Toggle = true;
   // Start is called before the first frame update
   void Start()
   {
     
   }

   // Update is called once per frame
   void Update()
   {
       if (!Toggle) return;
       time += Time.DeltaTime;

       float function = Mathf.Pow(time/8f,2);

       distanceTraveled += function;

       transform.Translate(
           new Vector3(
               function, 0f ,0f
           )
       );

       if (time >= 2) Toggle = false;
   }
}

calculations

i’ve tried changing update to fixedUpdate, and i ran out of any further ideas.

EDIT (IMPORTANT) ok guys, I added distanceTraveled += function * Time.deltaTime, and now it works, but can someone explain to me why??? after all, the function is evaluated for a variable that is independent of frames, so theoretically there should be no difference???

I see three things that will contribute to your error term:

  1. You’re always going to have inconsistency when you are discretely integrating a continuous function (numerical integration).

  2. You’re doing Rectangular Rule but failing to use the midpoint between two samples, also introducing error.

  3. Not only that but in this case you’re using Update() and Time.deltaTime, which may vary each frame.

public class Movement : MonoBehaviour
{
    [SerializeField] private float time = 0f;
    [SerializeField] private float distanceTraveled;
    [SerializeField] private bool Toggle = true;

    Vector3 startPosition;
    // Start is called before the first frame update
    void Start()
    {
        transform.position=Vector3.zero;
        transform.rotation=Quaternion.identity;
    }
   
    // Update is called once per frame
    void Update()
    {
        if (!Toggle) return;
        time += Time.deltaTime;
   
        float function = Mathf.Pow(time/8f,2);
   
        distanceTraveled += function;
   
        transform.Translate(
            new Vector3(
                function, 0f ,0f
            )
        );
   
        if (time >= 2) Toggle = false;
    }
}