Movement questions

Godot Version

4.8?

Question

I am learning and I am loving Godot and I was doing the 'your first 3d game" tutorial and I was wondering how would I make a really in depth movement code? I like the one I got but I don’t like not being able to sprint and maybe to add more movement to the character like a double jump. If there are links to this solution please I am welcome to all help.

func _ready():
    print("You are the best!")

There’s not a whole lot to go off from this question. If you need people to help you, you have to make it easy to for them to do so like including exactly what your code looks like or using the appropriate hyper links. I don’t wish to parse through a tutorial to be able to help you, having your code here would just be simpler. Ultimately for this question it really really depends, and a lot of it is simply your choice.

Anyway — most movement tutorials keep things like speed and gravity as variables for this very purpose. It’s theoretically as simple as dialing that up when a certain trigger happens. For example, sprint is triggered by using Ctrl in minecraft, Shift in roblox, then theres double pressing w in minecraft, and there’s also the more conditional stuff like if you drink a potion, or if you get a powerup, etcetc. You weren’t very specific so I don’t know which you’d want. The key to the former two would be adding things to your project’s Input Map, and like a rudimentary system for the double tab would be like counting the times it was pressed and starting a timer (via a setter) that subtracts 1, to which if the timer hits to count like if you’re pressing it fast enough. (a very basic implementation below since I couldn’t find an easy up to date tutorial on setters and getters)

extends CharacterBody3D


var w_press_counter: int = 0:
 set(value): # calls when variable is modified to something
  $Timer.start()
  w_press_counter = value


func _physics_process(_delta:float) -> void:

 if Input.is_action_just_pressed(“w“):

  w_press_counter += 1

 if w_press_counter >= 2:
   pass #insert sprint code

func _on_timer_timeout() -> void: #this is a signal you need to connect from a timer node
 w_press_counter -= 1

the syntax might be wrong since I wrote it out from memory but the point was moreso to show setters and getters in case that was the implementation you want (if you’re confused about the -> void and : int stuff then I suggest looking into static typing (highly highly recommend)). And again this assumes you have a timer node as a child and you have the w key registered in your input map as “w”

I suggest you look into player state machines. I haven’t gotten into implementing state machines as of yet — since I wasn’t directed into it before I already built the bad habit of not using them — so i cant really recommend you any particular tutorials with the approval that I know they’re for sure good. Queble is one of my favorite Godot channels, but his implementation was kind of confusing. Gwizz seems to have made a great tutorial and I know he’s generally reliable. Just find anything something that works for you. This concept specifically is especially important to incorporate for you as you develop more advanced movement mechanics, it will help your code be neat and readable as you expand and add even more and complex states. Right now it will probably feel really extreaneous but, you will be doing yourself a favor, and I promise you that… :smiling_face_with_tear:

Okay so super emphasizing this: look into input maps, and state machines, then you should be all dandy

Hey I apologize for the lack of clarity in my post. I will do better to add more context. It was a tutorial from the GDQuest for starting your own 3d game. It taught how to make a 3d first person arena shooter. In the script he doesn’t add the ability to sprint and I went and tried to add ways to sprint from other tutorials onto his script and it wasn’t working. So the question was more of a terribly asked general how do you guys. But here is the script from the tutorial. I’m sorry I don’t know how to add the code box…

extends CharacterBody3D

var speed = 5.5

func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event):
if event is InputEventMouseMotion:
rotation_degrees.y -= event.relative.x * 0.2
%Camera3D.rotation_degrees.x -= event.relative.y * 0.2
%Camera3D.rotation_degrees.x = clamp(
%Camera3D.rotation_degrees.x, -90.0, 85.0
)
elif event.is_action_pressed(“ui_cancel”):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

func _physics_process(delta):

var input_direction_2D = Input.get_vector(
"move_left", "move_right", "move_forward", "move_back"
)

var input_direction_3D = Vector3(
	input_direction_2D.x, 0.0, input_direction_2D.y
)
var direction = transform.basis * input_direction_3D

velocity.x = direction.x * speed
velocity.z = direction.z * speed

velocity.y -= 20.0 * delta
if Input.is_action_just_pressed("jump") and is_on_floor():
	velocity.y = 12.0
elif Input.is_action_just_released("jump") and velocity.y > 0.0:
	velocity.y = 0.0



move_and_slide()

if Input.is_action_pressed("shoot") and %Timer.is_stopped():
	shoot_bullet()

func shoot_bullet():
const BULLET_3D = preload(“res://bullet_3d.tscn”)
var new_bullet = BULLET_3D.instantiate()
%Marker3D.add_child(new_bullet)
%AudioStreamPlayer.play()

new_bullet.global_transform = %Marker3D.global_transform

%Timer.start()

Thank you for the clarification! And it’s not a big deal no worries :]

Yeahhh so, my advice doesn’t change a whole lot. Do you see the line of code where it says

velocity.x = direction.x * speed
velocity.y = direction.z * speed

This is the very basis of your movement. That speed variable lives inside your code and is free for you to use and modify. Currently it’s value is 5.5 var speed = 5.5, and you can experiment by seeing what happens when you dial up the number to say, something like 15 or 2 or 10000 if you’re feeling wacky. (var speed = 15 #experiment by replacing this number)

You basically just want a conditional statement to check if you’re sprinting, and if so, increase that speed variable. There’s a difference between toggling and holding it, but it still largely relies on setting your project’s Input Map, so for a very simplistic example of adding a “hold to sprint” system would be tracking when a key is pressed and let go. And actually looking at your code, it’s a very very similar concept to your jumping logic, here’s how to do that:

if Input.is_action_just_pressed("sprint"):
 speed = 10 #sprint speed, adjust to your liking
elif Input.is_action_just_released("sprint"):
 speed = 5.5 #this is your default speed

(the example assumes you have an input mapped key linked to your ctrl key, and titled sprint, check the hyper link on Input Maps on how to do that)

Now that’s SPECIFICALLY for hold to sprint, this doesn’t toggle it, and you might find it a good exercise to figure out how to toggle it as it isn’t too many extra steps. I do recommend though that instead of having your sprint speed and walking speed values direcly set in the code, you have them as constants at the top of your script like this:

extends CharacterBody3D

const walking_speed := 5.5
const sprinting_speed := 10.0

var speed := walking_speed

## yada yada code

func _physics_process(delta):
 #yada yada code im discluding for readability

 if Input.is_action_just_pressed("sprint"):
  speed = sprinting_speed
 elif Input.is_action_just_released("sprint"):
  speed = walking_speed

I recommend this because you can easily change and access these values throughout your code without having to reread or remember it. Like if you had a crouching feature that slowed your speed, its the difference between

“hmm, what’s the walking speed? let me find the code… oh its set to 5.5 during instantiation var speed = 5.5”

versus

“lets set it back using the walking_speed constant”)

and maybe later if you don’t like the walking speed being 5.5, instead of finding every time you used it, you could just change that one variable directly

Also I don’t want to overwhelm you but I recommend you use := when assigning variables. It just makes it known to the editor that it’s a float value which is useful for debugging and performance. You can learn more by looking at the Static Typing page (it also opens up autocompleting options too which makes it easier to code)

Hope that helps! Let me know if you have any more issues