This is an old revision of the document!
For our regular monthly tutorial nights, we're basing our teaching on the wonderful series by AJ's Learning Lab, Godot FPS Tutorial - Learn Godot by making Wolfenstein 3D.
He has made the assets he uses freely available (please consider donating) here: https://ajslearninglab.itch.io/boganstein-3d-learn-godot-4-with-wolfenstein-3d/
All the code we use is available on AJ's Learning Lab github - https://github.com/AJsLearningLab/GodotFPS
Goal: Learn about Godot, create a world/room (floor and walls)
extends CanvasLayer var ammo = 0 var current_weapon = "knife" func _ready(): $AnimatedSprite2D.animation_finished.connect(_on_AnimatedSprite2D_animation_finished) func _process(delta): if Input.is_action_just_pressed("ui_select"): if current_weapon == "knife": $AnimatedSprite2D.play("stab") elif current_weapon == "gun": if ammo > 0: $AnimatedSprite2D.play("shoot") ammo -= 1 func _on_AnimatedSprite2D_animation_finished(): if current_weapon == "knife": $AnimatedSprite2D.play("knife_idle") elif current_weapon == "gun": $AnimatedSprite2D.play("gun_idle")
extends CharacterBody3D @onready var player : CharacterBody3D = get_tree().get_first_node_in_group("player") const SPEED = 5.0 var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") # Get the gravity from the project settings to be synced with RigidBody nodes. var dead = false var is_attacking = false var attack_range = 5 func _ready(): add_to_group("enemy") func _physics_process(delta): if dead or is_attacking: # Check if the enemy is dead or attacking return if player == null: return var dir = player.global_position - global_position dir.y = 0.0 dir = dir.normalized() velocity = dir * SPEED # Add the gravity. if not is_on_floor(): velocity.y -= gravity * delta move_and_slide() attack() func attack(): var dist_to_player = global_position.distance_to(player.global_position) if dist_to_player > attack_range: return else: is_attacking = true # Set the attacking flag $AnimatedSprite3D.play("shoot") await $AnimatedSprite3D.animation_finished # Wait for the animation to finish is_attacking = false # Reset the attacking flag func die(): dead = true # Corrected variable scope $AnimatedSprite3D.play("die") $CollisionShape3D.disabled = true