First of, lets not use W or hard coded keys for input.
The proper way is to configure the input settings as an Axis.
The axis will constantly send values of between -1 and 1. Every tick.
They in fact work as an alternate for tick.
Now.
When a non axis key is mapped to an axis, the value is always just a plain 1 or -1.
You can use this to just automatically scale out the input over time with a lerp.
Ei: save the axis value as axis_previousFrame and check against it.
If this frame is 1 and the axis_previousFrame is 0, either the controller got pushed hard or a keyboard is in use.
So instead of using the axis value as is, first set a bool to flag you are running this variation.
Then modify the input to check that bool and perform a different branch than the one storing axis_previousFrame.
In the new branch, at the end of which you will test axis_previousFrame and branch again you will use a lerp to increment the axis value however you like intil it has reached 1. You store the result again (re-use) axis_previousFrame.
At rhe end of the process you simply toggle off the acceleration boolean that runs the extra 2 branches off.
All branch pins will likely need to be connected to the input as usually you always want input to happen at the end of it all.
Now for slowing down you can add another branch variation where you check if the current value is 0 and the previous value is 1.
You could/can re-work this logic a few times to make it conditional instead of fixed, but as you are learning it is probably better to go long-form.
Re-writing, optimization comes in once you mastered the initial idea.
There are a couple of nodes that could help and you can always floor or ceil the input to make controllers and keyboards initially behave identical.
Last but not least.
If you do not need this replicated, the easiest way to do it is to change animations and drive the speed of the motion from the animation with an animation curve.
Essentially, once “slow down” starts to play, it takes over the rate of movement.
You can consider this Root Motion without Root Motion. In fact, its literally done by taking an animation that moves (probably forward?) and storing the position of the root over the frames as a curve, prior to removing the motion of the root itself.
It is perhaps a bit more complex to grasp, create. And setup, but it has the benefit of letting you fine-tune movement as you would any animation.
It also usually produces perfect, no-foot sliding movement when used properly… which really should be a must for anyone aming at AAA parity since 2010…
ps: it doesnt even matter what speed you were at if you go this way. You can take that into account and use the animation curve to scale it down prior to actually using the animation itself (give it 10 frames of so extra to go from current speed to animation required speed).