The question is answered, right answer was accepted
Movement smoothing stopped working.
Context: I'm in the very early stage of making a simple local 3D fighting game. I used the movement code from Brackey's Third Person Movement tutorial and it worked fine. I implemented a character state machine by following a state machine tutorial by IHeartGameDev, which is also working great.
I want most (if not all) actions, including movement, to be performed on a locked game logic framerate/lockstep which I've implemented by simply abstracting time into intervals/blocks called "cframes", which I've set to run 60 times per second (still inside Update). Basically I run game logic every 1/60th of a second inside Update.
I collect all player inputs in an InputManager script that adds inputs to an input buffer. Each character state pulls only inputs that belong to the current cframe and deals with them accordingly. Movement used to be performed directly from player input inside Update, but now is performed at the beginning of each cframe. All inputs are still collected inside Update.
So far everything looks good, but after migrating the character movement code into the character's walking state (and slightly adjusting the code to work with the new setup), the movement is now jittery. By adjusting my cframe-rate (default is 60) to very low and high values, I discovered the movement is not interpolating(?) or smoothing at all- it's just snapping the player to the new position each cframe. This is a bit surprising to me because the only thing I changed in the movement logic is
character.controller.Move(moveDir.normalized character.speed Time.deltaTime);
to
character.controller.Move(moveDir.normalized * character.speed * character.timestepManager.timeSinceLastCframe);
which I think is correct. (timestepManager is just the code that abstracts time into cframes).
I don't think the issue is with the input mangement system, or with the state machine. I still collect input in Update, but only act on it each cframe.
What I'm asking is:
What could have caused the movement to become jittery aftering moving the movement code from its previous home in an arbitrary Update script to its new home in the character states, running each cframe?
How can I approach fixing this? I've looked around and found a lead: Implementing a movement smoothing system using Lerp or MoveTowards where I keep track of the current position and lerp to a projection of the new position. However, I'm not sure if this addresses the problem or not.
It's not letting me attach code files to this post, but I may be able to share them some other way if needed. I would appreciate any guidance or pointers. Thanks.
Answer by DinkleDorph · Apr 20 at 11:53 PM
For anyone who stumbles here in the future, here's what happened: Character movement happens instantly (movement does not happen "smoothly over time"), so when I put my movement code into my 60fps "lockstep", the movement was only happening each lockstep frame, making it jittery.
.
My solution was to put the movement code back into Update so it happens every render frame, then only allow movement to start and end in lockstep (movement always continues between lockstep frames). This way the movement is smooth and my movement still adheres to my lockstep game rules. As a bonus, I created a separate player model that follows the position of my player object and interpolated its position to the player object to get extra smooth motion on screen.