CharacterController Impulse Effect that is Framerate independent

tldr: How do I make a impulse force that diminishes over time and is framerate independent.

Greetings Everyone!

I’ve been trying to create a dash ability with an impulse effect that is similar to Rigidbody.AddForce(force, ForceMode.Impulse);

where the force starts strong and keeps getting weaker with time.

I’ve managed to create a good method using SmoothDamp, I also tried using Lerp.
But both methods gets unexpected results on low fps where the Player travels more than wanted.

here’s the implementation I had.
this function is called every update until the context.DashTime ends.

Using SmoothDamp:

private void StartDash() {
       startTime = Time.time;
       dashSpeed = context.MaxDashSpeed;
}

private void HandleDashing() {
        context.Controller.Move(dashDirection.normalized * dashSpeed * Time.deltaTime);

        // Impulse Effect
        Debug.Log(dashSpeed);
        float t = (Time.time - startTime) / context.DashTime;
        dashSpeed = Mathf.SmoothStep(dashSpeed, context.MinDashSpeed, t);
}

Using Lerp:

private void StartDash() {
       cuurentTime = 0;
       dashSpeed = context.MaxDashSpeed;
}

private void HandleDashing() {
        context.Controller.Move(dashDirection.normalized * dashSpeed * Time.deltaTime);

        // Impulse Effect
        Debug.Log(dashSpeed);
       
        currentTime += Time.deltaTime;
        if (currentTime > context.DashTime) {
            currentTime = context.DashTime;
        }

        float t = currentTime / context.DashTime;
        dashSpeed = Mathf.Lerp(dashSpeed, context.MinDashSpeed, t);
}

the easy way is to do it in fixedupdate where physics goes :slight_smile:

but even easier is to do it in a coroutine and keep waiting for fixedupate in there to increment
and don’t forget to cache your waitforfixedupdate at start!

I’m not using any physics or Rigidbody though?
also I’m using Time.deltaTime but it’s still inconsistent when frames change.

How do I do this coroutine method?

Moving my Dashing Function to FixedUpdate did the trick!!
But I kinda don’t get it, did we use the FixedUpdate to make the Impulse simulation accurate or to make the movement consistent?

because I had a similar problem where jumping wasn’t consistent as well but I managed to fix it by adding Time.deltaTime to the gravity acceleration.

So I’m wondering how is these two problems not similar. They’re both related to a force that changes over time.

i personally just recommend using fixed for anything that is moving or uses physics… i’ve just had inconsistent results in update with deltatime though for the most part it’s fine

i’d say you used it to make the movement consistent as it’s there to be a frame rate independent flow for your code

If you need rock-solid reliable consitency then always use fixed time steps and absolutely do not simply do it in Update() and multiply by delta time. This will always lead to inconsistent results for a couple of reasons. The first mostly just has to do with math and integration with variable steps. The second is that delta time isn’t a magic time machine that can predict the time it will take for your current frame. It’s telling you the time the last one took.

The de-facto required reading on the subject for the last two decades.

Thanks for the explanation