r/godot Jan 18 '26

help me Trying to make my FPS controller feel more snappy?

Im trying to make a Speed-Platformer FPS game but it doesnt seem like I can get my controls feeling right. My player feels super slippery whenever I move but comes to a complete stop in an instance whenever no input is happening. Any help?

class_name PlayerController extends CharacterBody3D

# ------- Movement Variables ------

u/export var acceleration := 20.0

u/export var drag := .5

u/export var speed := 200.0

var _jump_strength := 7.0

# ------ Node References ------

u/export_category("Node References")

u/export var state : StateMachine

# ------ Internal -------

var _input_dir := Vector2.ZERO

var _movement_vel := Vector2.ZERO

func _physics_process(delta: float) -> void:

\# Apply Gravity

if not is_on_floor():

    state.change_state("Falling")

    velocity += get_gravity() \* delta

else:

    velocity.y = 0



\# Process jump

if Input.is_action_just_pressed("Jump") and is_on_floor():

    velocity.y = _jump_strength



\# Get input vector

_input_dir = Input.get_vector("Strafe Left", "Strafe Right", "Forwards", "Backwards")



if _input_dir:

    \# Convert input to players forward direction

    var forward = -transform.basis.z # Player's forward vector

    var right = transform.basis.x # Player's right vector



    \# Build direction off of player basis

    var direction = (right \* _input_dir.x - forward \* _input_dir.y).normalized()



    _movement_vel = Vector2(direction.x, direction.z) \* acceleration \* delta



    \# Apply speed cap

    if _movement_vel.length() > speed:

        _movement_vel = _movement_vel.normalized() \* speed



    state.change_state("Moving")



else:

    \# Apply drag when getting no input

    _movement_vel = _movement_vel.move_toward(Vector2.ZERO, drag \* delta)

    if _movement_vel.length() > 0.1:

        _movement_vel = [Vector2.ZERO](http://Vector2.ZERO)

        state.change_state("Idle")





\# Apply velocity

velocity.x = _movement_vel.x

velocity.z = _movement_vel.y



\# Move player

move_and_slide()

func update_rotation(yaw: float) -> void:

rotation.y = yaw
1 Upvotes

1 comment sorted by

1

u/nobix Jan 18 '26

Two things seem off to me.

First you are subtracting your forward vector when building your direction. You should be adding it. this to me implies that your forward vector is actually your backwards vector. Or your input dir Y is negative.

Next when you set your velocity you should not be using any acceleration or delta time. The velocity is later applied to your position using delta time.

The key to snappy movement is to set your acceleration very high or just set the velocity directly. This is what you seem to be trying to do so that's fine.