I want my game to support unlocked framerate so the character’s movement should be updated on per-frame basis.

The problem is that the acceleration is really inconsistent. Eventually all framerates hit the maximum speed (they get closer to it every frame), but 1000 FPS reaches it almost instantly, while 15 FPS takes a long time to accelerate.
After pondering about it, it makes sense, but I wasn’t able to make the acceleration consistent…

What is the mathematical solution to this? Any tips are appreciated!

All you need to do is to take the time between the current and previous frame. In unity you can access that through Time.deltaTime.

Now you have that, simply multiply it by your movement and it’ll be smooth(as a larger delta time will mean longer between frames, and hence the actual movement is increased).

Basic example, if you want something to move 10 units every second, you’d have something like:

pos += 10.0f * Time.deltaTime;

obviously adjust as needed and covert for vectors where necessary.

vel.x += input.x;
vel.z += input.z;
These are not framerate independent lines. To make them framerate independent, you need to factor in the time between frames. What this means, though, is that you’ll also want a multiplier for the actual rate of speed gain. For example:

When you multiply by Time.deltaTime, you’re effectively changing the value of your input (i.e. inputs x and z) to a rate of X per second. As an example, your inputs x and z were updating velocity at a rate of 1 per frame, so a framerate of 60 means 60 per second.

But that’s why I added “speedMod” as an example multiplier. It takes the input of (likely up to) 1 per second and gives it a multiplier to reach an intended pace.

I have a code where I use acceleration to make gravity. To make this framerate independent, I multiply by Time.deltaTime. But since I add acceleration to velocity AND velocity to position every frame, I have to multiply by Time.deltaTime TWICE. In theory this should work, but it doesn’t for me and I don’t know why. Tell me if you want to see my code, because it’s 105 rows.