├── LICENSE ├── Materials ├── Blue.tres ├── Green.tres ├── Pink.tres └── Red.tres ├── Scenes └── World.tscn ├── Scripts └── Player.gd ├── icon.svg ├── icon.svg.import └── project.godot /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 LegionGames 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Materials/Blue.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://p2nkjd3ge3qm"] 2 | 3 | [resource] 4 | albedo_color = Color(0.168627, 0.2, 1, 1) 5 | -------------------------------------------------------------------------------- /Materials/Green.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://b4s0xnt1f6lia"] 2 | 3 | [resource] 4 | albedo_color = Color(0.27451, 0.384314, 0.184314, 1) 5 | metallic_specular = 0.0 6 | -------------------------------------------------------------------------------- /Materials/Pink.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://bi1h4xe7msjwi"] 2 | 3 | [resource] 4 | albedo_color = Color(1, 0.717647, 0.752941, 1) 5 | metallic_specular = 0.0 6 | -------------------------------------------------------------------------------- /Materials/Red.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://b122sws3pt7w7"] 2 | 3 | [resource] 4 | albedo_color = Color(1, 0.317647, 0.219608, 1) 5 | -------------------------------------------------------------------------------- /Scenes/World.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=11 format=3 uid="uid://db2h3t17k37pe"] 2 | 3 | [ext_resource type="Script" path="res://Scripts/Player.gd" id="1_1d73w"] 4 | [ext_resource type="Material" uid="uid://b4s0xnt1f6lia" path="res://Materials/Green.tres" id="1_o5nrg"] 5 | [ext_resource type="Material" uid="uid://bi1h4xe7msjwi" path="res://Materials/Pink.tres" id="3_irgfk"] 6 | [ext_resource type="Material" uid="uid://b122sws3pt7w7" path="res://Materials/Red.tres" id="4_nuwel"] 7 | [ext_resource type="Material" uid="uid://p2nkjd3ge3qm" path="res://Materials/Blue.tres" id="5_te4rd"] 8 | 9 | [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_5lq0h"] 10 | sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) 11 | ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) 12 | 13 | [sub_resource type="Sky" id="Sky_f6bkd"] 14 | sky_material = SubResource("ProceduralSkyMaterial_5lq0h") 15 | 16 | [sub_resource type="Environment" id="Environment_g2h84"] 17 | background_mode = 2 18 | sky = SubResource("Sky_f6bkd") 19 | tonemap_mode = 2 20 | glow_enabled = true 21 | 22 | [sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"] 23 | 24 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_wydro"] 25 | 26 | [node name="World" type="Node3D"] 27 | 28 | [node name="Map" type="Node3D" parent="."] 29 | 30 | [node name="CSGBox3D2" type="CSGBox3D" parent="Map"] 31 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -29.5653) 32 | material_override = ExtResource("3_irgfk") 33 | use_collision = true 34 | size = Vector3(52.4636, 5.83948, 1) 35 | 36 | [node name="CSGBox3D3" type="CSGBox3D" parent="Map"] 37 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 29.3824) 38 | use_collision = true 39 | size = Vector3(52.4636, 5.83948, 1) 40 | material = ExtResource("3_irgfk") 41 | 42 | [node name="CSGBox3D4" type="CSGBox3D" parent="Map"] 43 | transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -26, 0, 0.382374) 44 | material_override = ExtResource("3_irgfk") 45 | use_collision = true 46 | size = Vector3(60, 5.83948, 1) 47 | 48 | [node name="CSGBox3D5" type="CSGBox3D" parent="Map"] 49 | transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 26, 0, 0.382374) 50 | material_override = ExtResource("3_irgfk") 51 | use_collision = true 52 | size = Vector3(60, 5.83948, 1) 53 | 54 | [node name="CSGBox3D6" type="CSGBox3D" parent="Map"] 55 | transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 12, -2, 0.382374) 56 | material_override = ExtResource("4_nuwel") 57 | use_collision = true 58 | size = Vector3(4, 5.83948, 4) 59 | 60 | [node name="CSGBox3D7" type="CSGBox3D" parent="Map"] 61 | transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 12, 0, -5.61763) 62 | material_override = ExtResource("5_te4rd") 63 | use_collision = true 64 | size = Vector3(4, 5.83948, 4) 65 | 66 | [node name="CSGBox3D8" type="CSGBox3D" parent="Map"] 67 | transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 12, 0, -12.6176) 68 | material_override = ExtResource("4_nuwel") 69 | use_collision = true 70 | size = Vector3(4, 8, 4) 71 | 72 | [node name="CSGBox3D" type="CSGBox3D" parent="Map"] 73 | material_override = ExtResource("1_o5nrg") 74 | use_collision = true 75 | size = Vector3(52.2363, 0.002, 59.575) 76 | 77 | [node name="WorldEnvironment" type="WorldEnvironment" parent="Map"] 78 | environment = SubResource("Environment_g2h84") 79 | 80 | [node name="DirectionalLight3D" type="DirectionalLight3D" parent="Map"] 81 | transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) 82 | shadow_enabled = true 83 | 84 | [node name="Player" type="CharacterBody3D" parent="."] 85 | script = ExtResource("1_1d73w") 86 | 87 | [node name="MeshInstance3D" type="MeshInstance3D" parent="Player"] 88 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) 89 | mesh = SubResource("CapsuleMesh_xc2g5") 90 | 91 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Player"] 92 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) 93 | shape = SubResource("CapsuleShape3D_wydro") 94 | 95 | [node name="Head" type="Node3D" parent="Player"] 96 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.67939, 0) 97 | 98 | [node name="Camera3D" type="Camera3D" parent="Player/Head"] 99 | -------------------------------------------------------------------------------- /Scripts/Player.gd: -------------------------------------------------------------------------------- 1 | extends CharacterBody3D 2 | 3 | var speed 4 | const WALK_SPEED = 5.0 5 | const SPRINT_SPEED = 8.0 6 | const JUMP_VELOCITY = 4.8 7 | const SENSITIVITY = 0.004 8 | 9 | #bob variables 10 | const BOB_FREQ = 2.4 11 | const BOB_AMP = 0.08 12 | var t_bob = 0.0 13 | 14 | #fov variables 15 | const BASE_FOV = 75.0 16 | const FOV_CHANGE = 1.5 17 | 18 | # Get the gravity from the project settings to be synced with RigidBody nodes. 19 | var gravity = 9.8 20 | 21 | @onready var head = $Head 22 | @onready var camera = $Head/Camera3D 23 | 24 | 25 | func _ready(): 26 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 27 | 28 | 29 | func _unhandled_input(event): 30 | if event is InputEventMouseMotion: 31 | head.rotate_y(-event.relative.x * SENSITIVITY) 32 | camera.rotate_x(-event.relative.y * SENSITIVITY) 33 | camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(60)) 34 | 35 | 36 | func _physics_process(delta): 37 | # Add the gravity. 38 | if not is_on_floor(): 39 | velocity.y -= gravity * delta 40 | 41 | # Handle Jump. 42 | if Input.is_action_just_pressed("jump") and is_on_floor(): 43 | velocity.y = JUMP_VELOCITY 44 | 45 | # Handle Sprint. 46 | if Input.is_action_pressed("sprint"): 47 | speed = SPRINT_SPEED 48 | else: 49 | speed = WALK_SPEED 50 | 51 | # Get the input direction and handle the movement/deceleration. 52 | var input_dir = Input.get_vector("left", "right", "up", "down") 53 | var direction = (head.transform.basis * transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() 54 | if is_on_floor(): 55 | if direction: 56 | velocity.x = direction.x * speed 57 | velocity.z = direction.z * speed 58 | else: 59 | velocity.x = lerp(velocity.x, direction.x * speed, delta * 7.0) 60 | velocity.z = lerp(velocity.z, direction.z * speed, delta * 7.0) 61 | else: 62 | velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0) 63 | velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0) 64 | 65 | # Head bob 66 | t_bob += delta * velocity.length() * float(is_on_floor()) 67 | camera.transform.origin = _headbob(t_bob) 68 | 69 | # FOV 70 | var velocity_clamped = clamp(velocity.length(), 0.5, SPRINT_SPEED * 2) 71 | var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped 72 | camera.fov = lerp(camera.fov, target_fov, delta * 8.0) 73 | 74 | move_and_slide() 75 | 76 | 77 | func _headbob(time) -> Vector3: 78 | var pos = Vector3.ZERO 79 | pos.y = sin(time * BOB_FREQ) * BOB_AMP 80 | pos.x = cos(time * BOB_FREQ / 2) * BOB_AMP 81 | return pos 82 | -------------------------------------------------------------------------------- /icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dxhmood0fkku1" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="10-first Person Controller" 14 | run/main_scene="res://Scenes/World.tscn" 15 | config/features=PackedStringArray("4.0", "Forward Plus") 16 | config/icon="res://icon.svg" 17 | 18 | [display] 19 | 20 | window/size/viewport_width=1920 21 | window/size/viewport_height=1080 22 | window/size/mode=3 23 | 24 | [input] 25 | 26 | up={ 27 | "deadzone": 0.5, 28 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) 29 | ] 30 | } 31 | down={ 32 | "deadzone": 0.5, 33 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) 34 | ] 35 | } 36 | left={ 37 | "deadzone": 0.5, 38 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) 39 | ] 40 | } 41 | right={ 42 | "deadzone": 0.5, 43 | "events": [null, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) 44 | ] 45 | } 46 | jump={ 47 | "deadzone": 0.5, 48 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"echo":false,"script":null) 49 | ] 50 | } 51 | sprint={ 52 | "deadzone": 0.5, 53 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"echo":false,"script":null) 54 | ] 55 | } 56 | 57 | [physics] 58 | 59 | common/physics_ticks_per_second=144 60 | 61 | [rendering] 62 | 63 | anti_aliasing/quality/msaa_2d=2 64 | anti_aliasing/quality/msaa_3d=2 65 | anti_aliasing/quality/screen_space_aa=1 66 | textures/canvas_textures/default_texture_filter=0 67 | --------------------------------------------------------------------------------