- Home /
Framerate independent Movement
In my project I have Unity's CharacterController. This is the code that made it move. It's working great when using fixed timestep.
vel.x *= friction;
vel.z *= friction;
vel.x += input.x;
vel.z += input.z;
cc.Move (vel);
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!
Answer by phil_me_up · Feb 26, 2016 at 01:11 AM
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.
This achieves consistent change in position, but what I ask is a consistent change in velocity and ultimately the position.
Answer by Eno-Khaon · Feb 26, 2016 at 01:11 AM
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:
vel.x += input.x * speedMod * Time.deltaTime;
vel.z += input.z * speedMod * Time.deltaTime;
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 tried this but didn't get consistent results.
Also shouldn't the amount of friction also be based on the delta time?
Your answer
Follow this Question
Related Questions
Strange Character Controller Behavior Caused by Simulated Gravity and Ground Check 0 Answers
How can I make my FPS player move towards the direction it is facing 1 Answer
Continuously rotate a gameobject on 1 axis perpendicularly to another gameobject's normal? 1 Answer