Table of Contents

  1. Overview
  2. Installing Godot and creating a new project
  3. Create new "World" Scene
  4. Creating Player Node
  5. Add lighting
  6. Input Mapping
  7. Scripting the Player Node
  8. Making it better
  9. FINISH

Finished Project

Soly Image Caption

Download Godot

Click Here to Dowload Godot

Run the correct Godot

Run the exe

Create a new project

New Project 1

New Project 2

Create a new 3D Scene

New World 1

Create a new floor, Add Static Body and Mesh

New World 2

Assign Mesh to plane mesh and increase the size

New World 3

New World 4

Adding a Collider to the mesh

New World 5

New World 6

New World 7

Run the program with F5 and assign world as the main Scene

Create a new Scene

Create Player 1

Add CharacterBody3D Node as main Node to the Scene

Create Player 2

Give the CharacterBody3D a Capsule Mesh and Collision Shape

Create Player 3

Assign a Capsule shae to the collider

Create Player 4

Add a Camera Node

Create Player 5

Link it to the World Scene

Create Player 6

Add WorldEnviorment and DirectionLight3D to the world Scene

Enviorment lighting 1

Create a new Enviorment

Enviorment lighting 2

Enviorment lighting 3

In DirectionLight3D Node enable shadows and adjust the rotation transform

Enviorment lighting 4

Add new acrions to input map

Input Mapping 1

Attach a new Script to the Player Scene

Input Mapping 2

Change the default Inputs to the new inputs we made in Input Mapping actions

Adjust line 14 and 19 to our needs (Inside func _input())

    # Handle jump.
	if Input.is_action_just_pressed("player_jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("player_left", "player_right", "player_forward", "player_back")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

Add _ready function to lock mouse on start

The function call will be called by the game engine on ready

func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

Create new var ‘MOUSE_SENSETIVITY' at top and add _process function and wait for pause input to toggle mouse when pause button is pressed

# Top of the Script
extends CharacterBody3D


const SPEED = 5.0
const JUMP_VELOCITY = 4.5
const MOUSE_SENSETIVITY = 0.1 	#ADDED CODE

...
...
...

func _process(delta: float) -> void:
	if Input.is_action_just_pressed("pause"):
		if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
			Input.mouse_mode =Input.MOUSE_MODE_VISIBLE
		else:
			Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

Add _input function and get Mouse Inputs to get look direction

func _input(event: InputEvent) -> void:
	if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
		if event is InputEventMouseMotion:
			rotation_degrees.x -= event.relative.y * MOUSE_SENSETIVITY
			rotation_degrees.y -= event.relative.x * MOUSE_SENSETIVITY
			rotation_degrees.x = clamp(rotation_degrees.x, -90.0, 90.0)

We finished the most basic player Controller

You may notice that it feels bad and not fun to use. The reason for this is because there is not inertia in the controller right, main cause of this, is that the default Godot CharacterBody3D is a little scuffed.

    var input_dir := Input.get_vector("player_left", "player_right", "player_forward", "player_back")
    var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	
    # START OF NEW CODE

    if is_on_floor():	# ADDED IF STATEMENT FOR AIR CONTROLS
		if direction:
			velocity.x = direction.x * SPEED
			velocity.z = direction.z * SPEED
		else:
			# CHANGED CODE HERE FOR ACTUAL WORKING SLOWING (because godot template was scuffed) (ADDED CODE)
			velocity.x = lerp(velocity.x, direction.x * SPEED, delta * 4.0)
			velocity.z = lerp(velocity.z, direction.z * SPEED, delta * 4.0)
	# ADDED CODE
    else:	
		velocity.x = lerp(velocity.x, direction.x * SPEED, delta * 3.0)
		velocity.z = lerp(velocity.z, direction.z * SPEED, delta * 3.0)


    # END OF NEW CODE STUFF
	move_and_slide()

Jump buffering (adjust the jump input)

From: Input.is_action_just_pressed("player_jump")
To: Input.is_action_pressed("player_jump")

	# Handle jump.
	if Input.is_action_pressed("player_jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY

✅ Now you have a very basic Godot Player Controller
✅ Next workshop we will make a primitive First Person Shooter using this controller
✅ Please make sure to check-in

Soly Image Caption

Thanks for participating in this codelab!
And to our newcomers this seal is Solly. He is our current unofficial club mascot.
His lore is that he works for a AAA game company. As such, by logical implicit stance (A.K.A Modus Ponens)

p -> q, p ∴ q
let p = AAA company S̶l̶a̶v̶e employee
let q = Depression and basement dweller

To help Solly cope from this depression we require funding from USF and the only way we can request for funding is by proving we are an impactful club.
One proof of being an impactful club is club attendance/participation, so please don't forget to check in on BullsConnect.