Make your player fall properly, land on the ground, and leap into the air.
โฑ About 45โ60 minutesdelta makes it smoothis_on_floor()Right now the ground is only something you can see, not something you can stand on. The player would fall straight through it. Let's give it a real surface.
extends CharacterBody3D var speed = 5.0 var jump_force = 8.0 var gravity = 20.0 func _physics_process(delta): # 1. Pull the player down when they're in the air if not is_on_floor(): velocity.y -= gravity * delta # 2. Jump, but only when standing on the ground if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = jump_force # 3. Left / right / forward / back (same as yesterday) var direction = Vector3.ZERO if Input.is_action_pressed("ui_up"): direction.z -= 1 if Input.is_action_pressed("ui_down"): direction.z += 1 if Input.is_action_pressed("ui_left"): direction.x -= 1 if Input.is_action_pressed("ui_right"): direction.x += 1 velocity.x = direction.x * speed velocity.z = direction.z * speed move_and_slide()
jump_force is how hard the player launches upward; gravity is how
hard they get pulled down. Both are just numbers you can tweak. Keeping them at the top, named
clearly, means you can balance the feel of your game without hunting through the code.
if not is_on_floor(): velocity.y -= gravity * deltais_on_floor() is a built-in question that answers true or false: "am I standing
on something solid?". not flips it, so this reads "if I'm NOT on the floor,
pull me down". We lower velocity.y (the up/down part of velocity) a little
every frame, so the player falls faster and faster โ exactly like real gravity.
delta is the tiny slice of time since the last frame. Multiplying by it means the
player falls the same real-world speed whether the game runs at 30 or 240 frames a
second. Without * delta, your game would feel different on different computers.
Rule of thumb: anything that should happen "per second" gets multiplied by delta.
is_action_just_pressed("ui_accept")Notice it's just_pressed, not is_pressed. "Just pressed" is true for a single frame โ the exact moment you tap the key. That's perfect for jumping: you want one jump per press. If we used "is pressed" (held), the player would rocket upward as long as you held the key. Try it as the experiment below and you'll see why this matters.
We also check and is_on_floor() so you can only jump from the ground โ no
mid-air double jumps (yet!).
velocity.x and velocity.z separately?Yesterday we set the whole velocity at once. We can't do that today, because gravity
is busy controlling velocity.y. So we only touch the left/right part
(.x) and forward/back part (.z), and leave .y for
gravity and jumping to manage. Three numbers, three different jobs.
gravity to 5.0.
Then make it feel heavy: try 40.0. Find a gravity you like.
jump_force up to 15.0 for a super-jump. Combine a low gravity
with a high jump force โ what kind of game would that feel like?
var jumps_left = 2. When you jump, do
jumps_left -= 1 and allow jumping while jumps_left > 0 (instead of
only is_on_floor()). Reset jumps_left = 2 whenever
is_on_floor() is true. Trickier โ give it a go!
is_action_just_pressed to is_action_pressed for the jump.
Run it and hold Space โ you fly straight up forever! Now you can see the difference
between "just pressed" (one tap) and "pressed" (held). Change it back when you're done laughing.
"The player falls through the floor." The ground has no collision. Go back to Part 1: select Ground โ Mesh menu โ Create Trimesh Static Body.
"I can't jump." You can only jump while on the floor. Make sure you've landed
first. Also check the jump line uses ui_accept (Space/Enter).
"The player sinks slowly into the ground." Make sure your Player has a CollisionShape3D with a BoxShape3D (from Day 3) and its Position Y is 1 at the start.
"Jump only works sometimes." That's the single-frame timing of
just_pressed โ tap the key deliberately rather than feathering it. It's working
correctly.
Tomorrow: a camera that follows you around, plus we pull all of Week 1 together into a little arena. ๐๏ธ