๐ŸŽฎ Summer Coding Quest
Week 1 ยท Day 3

Make It Move

Give your player a brain and drive it around the field with the arrow keys.

โฑ About 45โ€“60 minutes
๐ŸŽฏ Today's mission Press the arrow keys and watch your box glide around the world, Raviv. This is the moment a "scene" becomes a "game" โ€” when you are in control.

What you'll learn

๐Ÿ’ก Why swap the player for a new node? Yesterday the player was a plain MeshInstance3D โ€” great for showing, useless for moving and bumping into things. Today we rebuild it as a CharacterBody3D: a node built specially for player characters that can move, collide and (tomorrow) fall and jump.

Part 1 โ€” Rebuild the player

  1. Delete the old player

    Right-click the old Player (the plain box) in the Scene panel โ†’ Delete Node(s). Don't worry, we're building a better one.
  2. Add a CharacterBody3D

    Select World โ†’ + Add Child Node โ†’ CharacterBody3D. Rename it Player. You'll notice a yellow warning triangle next to it โ€” that's normal, it just means "I need a body shape", which we add next.
  3. Give it a shape it can see (mesh)

    Select Player โ†’ Add Child Node โ†’ MeshInstance3D โ†’ give it a New BoxMesh. This is the bit you'll see on screen.
  4. Give it a shape it can feel (collision)

    Select Player again โ†’ Add Child Node โ†’ CollisionShape3D โ†’ in the Inspector set its Shape to New BoxShape3D. This invisible box is how the player physically bumps into the world. The warning triangle disappears.
  5. Lift the player up

    Select Player and set Position Y to 1 so it starts above the floor.
๐Ÿ’ก Two shapes? Really? Yes โ€” and it's worth understanding. The mesh is what you see. The collision shape is what the game feels when working out bumps. Keeping them separate is a trick real games use all the time: a monster can look incredibly detailed but have a simple box for collisions, which keeps the game fast.

Part 2 โ€” Give the player a script

  1. Attach a script to the Player

    Right-click Player โ†’ Attach Script โ†’ Create. Godot gives you a starter file made for a CharacterBody3D.
  2. Replace it with this

    Delete what's there and type this in. Take your time โ€” every line is explained just below.
    extends CharacterBody3D
    
    # How fast the player moves
    var speed = 5.0
    
    
    func _physics_process(delta):
    	# Start with no movement
    	var direction = Vector3.ZERO
    
    	# Check which arrow keys are held down
    	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
    
    	# Turn that direction into actual speed, then move
    	velocity = direction * speed
    	move_and_slide()

    The arrow keys already work in Godot out of the box โ€” they're called ui_up, ui_down, ui_left and ui_right.

  3. Run it

    Press F5 and hold the arrow keys. Your box slides around the field. ๐ŸŽ‰
โœ… You did it! You're driving a character you built and coded yourself. From here on, every lesson adds something for this player to do.

Understand it โ€” line by line

extends CharacterBody3D

Yesterday's scripts extended Node. This one belongs to a CharacterBody3D, which unlocks special powers like velocity and move_and_slide() that a plain node doesn't have.

var speed = 5.0

A var (variable) is a labelled box that stores a value. Here the box is called speed and holds the number 5. Because it's a variable, you can change movement speed for the whole game by editing this one number โ€” that's exactly why we use variables instead of scattering the number 5 everywhere.

func _physics_process(delta):

_ready (from Day 1) runs once at the start. _physics_process is different โ€” Godot runs it about 60 times every second, over and over. That constant repeating is what lets movement feel smooth and live. The delta in the brackets is "how long since the last run" โ€” we'll use it properly tomorrow.

var direction = Vector3.ZERO

A Vector3 is just three numbers bundled together โ€” an X, a Y and a Z โ€” perfect for describing a direction in 3D. Vector3.ZERO means (0, 0, 0): no movement at all. We start from "not moving" each frame, then add to it.

The four if blocks

if means "only do the next bit if something is true". Input.is_action_pressed("ui_up") asks "is the up arrow held down right now?". If yes, we nudge the direction's Z by -1 (forward). Hold two keys and you move diagonally, because both ifs run. This is how nearly all keyboard control works.

๐Ÿ’ก Why is forward "minus Z"? In Godot's 3D world, the camera looks down the negative-Z direction by default, so "into the screen" (forward) is -Z and "towards you" (back) is +Z. It feels odd at first; you'll get used to it fast.

velocity = direction * speed then move_and_slide()

Velocity means speed-with-a-direction. We take the direction (which way) and multiply by speed (how fast) to get the final velocity. Then move_and_slide() is the CharacterBody3D's built-in command that actually moves the player and slides nicely along walls instead of getting stuck. You set the velocity; Godot does the moving.

Play around โ€” level up ๐ŸŽฎ

๐ŸŸข Level 1 โ€” Easy Change var speed = 5.0 to 10.0, then to 2.0. Run each time. Feel how one number changes the whole game's pace.
๐ŸŸก Level 2 โ€” Medium Add a print(velocity) line right after move_and_slide(). Watch the Output panel as you move โ€” you'll see the numbers change live. That's a window into your game's brain (and a debugging superpower).
๐Ÿ”ด Level 3 โ€” Spicy Make a "sprint" key. Add: if Input.is_action_pressed("ui_select"): speed = 12.0 else speed = 5.0 at the top of the function. (The spacebar is ui_select.) Now you walk normally and sprint on the spacebar.
๐Ÿ”ฌ Experiment: forget to move Comment out the last line by putting a # in front: # move_and_slide(). Run it. The keys do nothing! That proves move_and_slide() is the line that actually performs the movement โ€” everything above it only decides the movement. Remove the # to fix it.

If something went wrong

"Red error mentioning 'velocity' or 'move_and_slide'." The first line must be extends CharacterBody3D (not Node). Those powers only exist on a CharacterBody3D.

"It won't run โ€” error about indentation." The lines inside the if blocks need two Tabs (one for the function, one for the if). Match the spacing in the example exactly.

"The box moves but falls through / floats oddly." That's fine for today โ€” we have no gravity yet. Tomorrow fixes it. Just make sure Player's Position Y is 1.

"Arrows don't do anything." Make sure the script is attached to the Player node (a little scroll icon shows next to it) and that you pressed Play, not just saved.

Tomorrow: gravity and jumping โ€” your player learns to fall and leap. ๐Ÿฆ˜

Previousโ† Day 2 โ€” Build a 3D world