From 20027bed4b3466f9ee4df507459f1164c448c968 Mon Sep 17 00:00:00 2001 From: Rijad Zuzo Date: Wed, 17 Jun 2026 19:39:38 +0200 Subject: [PATCH] feat: setup initial repo and smallest working scene --- .editorconfig | 4 ++ .gitattributes | 7 ++++ .gitignore | 44 ++++++++++++++++++++ icon.svg | 1 + icon.svg.import | 43 +++++++++++++++++++ project.godot | 39 +++++++++++++++++ scenes/main.tscn | 74 +++++++++++++++++++++++++++++++++ scenes/player/camera_rig.gd | 58 ++++++++++++++++++++++++++ scenes/player/camera_rig.gd.uid | 1 + scenes/player/player.gd | 37 +++++++++++++++++ scenes/player/player.gd.uid | 1 + 11 files changed, 309 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 project.godot create mode 100644 scenes/main.tscn create mode 100644 scenes/player/camera_rig.gd create mode 100644 scenes/player/camera_rig.gd.uid create mode 100644 scenes/player/player.gd create mode 100644 scenes/player/player.gd.uid diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d8cb126 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf +*.gd text eol=lf +*.tscn text eol=lf +*.tres text eol=lf +*.shader text eol=lf +*.gdshader text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..060626c --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +# Godot import cache +.import/ + +# Godot editor generated files +.godot/ + +# Export templates and builds +/export/ +/exports/ +/build/ +/builds/ + +# Mono / C# +.mono/ +data_*/ +mono_crash.* + +# Visual Studio / Rider +.vs/ +.idea/ +*.csproj +*.sln +*.user +*.DotSettings.user + +# macOS +.DS_Store + +# Linux +.directory + +# Windows +Thumbs.db +desktop.ini + +# Logs +*.log + +# Temporary files +*.tmp +*.bak + +# Godot crash reports +crash_handler* diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..eede4ee --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvx06gdtgk2fp" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..f471b42 --- /dev/null +++ b/project.godot @@ -0,0 +1,39 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="the-steward" +run/main_scene="uid://rs3hv73svbpa" +config/features=PackedStringArray("4.5", "Forward Plus") +config/icon="res://icon.svg" + +[input] + +move_forward={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +move_backward={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +move_left={ +"deadzone": 0.2, +"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,"location":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.2, +"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":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} diff --git a/scenes/main.tscn b/scenes/main.tscn new file mode 100644 index 0000000..f7252ba --- /dev/null +++ b/scenes/main.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=9 format=3 uid="uid://rs3hv73svbpa"] + +[ext_resource type="Script" uid="uid://4mg67crlim53" path="res://scenes/player/player.gd" id="1_o5qli"] +[ext_resource type="Script" uid="uid://ii8ai801jur2" path="res://scenes/player/camera_rig.gd" id="2_0wfyh"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o5qli"] +albedo_color = Color(0.16862746, 0.52156866, 0.30588236, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_sgp6g"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_o5qli"] +radius = 0.4 +height = 1.7 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_sgp6g"] + +[sub_resource type="BoxMesh" id="BoxMesh_0wfyh"] + +[sub_resource type="Environment" id="Environment_o5qli"] +background_mode = 1 +background_color = Color(0.46428233, 0.7990817, 0.98692364, 1) +ambient_light_source = 2 +ambient_light_color = Color(1, 1, 1, 1) +ambient_light_energy = 0.5 + +[node name="Main" type="Node3D"] + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.8660254, -0.43301272, 0.24999999, 0, 0.49999997, 0.86602545, -0.5, -0.75, 0.43301266, 0, 0, 0) +light_energy = 2.0 + +[node name="World" type="Node3D" parent="."] + +[node name="Ground" type="MeshInstance3D" parent="World"] +transform = Transform3D(30, 0, 0, 0, 0.1, 0, 0, 0, 30, 0, -0.05, 0) +material_override = SubResource("StandardMaterial3D_o5qli") +mesh = SubResource("BoxMesh_sgp6g") + +[node name="Player" type="CharacterBody3D" parent="." node_paths=PackedStringArray("camera_rig")] +script = ExtResource("1_o5qli") +camera_rig = NodePath("../CameraRig") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Player"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0) +shape = SubResource("CapsuleShape3D_o5qli") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Player"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0) +mesh = SubResource("CapsuleMesh_sgp6g") + +[node name="FaceMarker" type="MeshInstance3D" parent="Player"] +transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.4, 0, 1.2, 0.6266626) +mesh = SubResource("BoxMesh_0wfyh") + +[node name="CameraRig" type="Node3D" parent="." node_paths=PackedStringArray("target")] +transform = Transform3D(1, 0, 0, 0, 0.57357645, 0.81915206, 0, -0.81915206, 0.57357645, 0, 10, 8) +script = ExtResource("2_0wfyh") +target = NodePath("../Player") +follow_speed = 8.0 +deadzone_right = 2.0 +deadzone_forward = 2.0 + +[node name="Camera3D" type="Camera3D" parent="CameraRig"] +current = true +fov = 65.0 + +[node name="SimulationManager" type="Node" parent="."] + +[node name="WorldViewManager" type="Node" parent="."] + +[node name="EventBus" type="Node" parent="."] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_o5qli") diff --git a/scenes/player/camera_rig.gd b/scenes/player/camera_rig.gd new file mode 100644 index 0000000..22f8edf --- /dev/null +++ b/scenes/player/camera_rig.gd @@ -0,0 +1,58 @@ +extends Node3D + +@export var target: Node3D +@export var follow_offset := Vector3(0, 10, 8) +@export var follow_speed := 12.0 +@export var mouse_sensitivity := 0.002 + +@export var deadzone_right := 3.0 +@export var deadzone_forward := 3.0 + +var yaw := 0.0 +var focus_position := Vector3.ZERO + +func _ready() -> void: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + if target: + focus_position = target.global_position + global_position = focus_position + follow_offset + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventMouseMotion: + yaw -= event.relative.x * mouse_sensitivity + + if event.is_action_pressed("ui_cancel"): + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + + +func _process(delta: float) -> void: + if target == null: + return + + rotation = Vector3(deg_to_rad(-55), yaw, 0) + + var target_pos := target.global_position + var diff := target_pos - focus_position + + # Camera-relative horizontal axes + var cam_right := Vector3.RIGHT.rotated(Vector3.UP, yaw).normalized() + var cam_forward := Vector3.FORWARD.rotated(Vector3.UP, yaw).normalized() + + var diff_right := diff.dot(cam_right) + var diff_forward := diff.dot(cam_forward) + + if abs(diff_right) > deadzone_right: + focus_position += cam_right * (diff_right - sign(diff_right) * deadzone_right) + + if abs(diff_forward) > deadzone_forward: + focus_position += cam_forward * (diff_forward - sign(diff_forward) * deadzone_forward) + + var rotated_offset := follow_offset.rotated(Vector3.UP, yaw) + var desired_position := focus_position + rotated_offset + + global_position = global_position.lerp( + desired_position, + 1.0 - exp(-follow_speed * delta) + ) diff --git a/scenes/player/camera_rig.gd.uid b/scenes/player/camera_rig.gd.uid new file mode 100644 index 0000000..d81eb8c --- /dev/null +++ b/scenes/player/camera_rig.gd.uid @@ -0,0 +1 @@ +uid://ii8ai801jur2 diff --git a/scenes/player/player.gd b/scenes/player/player.gd new file mode 100644 index 0000000..c403eb9 --- /dev/null +++ b/scenes/player/player.gd @@ -0,0 +1,37 @@ +extends CharacterBody3D + +@export var move_speed := 7.0 +@export var acceleration := 18.0 +@export var rotation_speed := 12.0 +@export var camera_rig: Node3D + +func _physics_process(delta: float) -> void: + var input := Input.get_vector( + "move_left", + "move_right", + "move_forward", + "move_backward" + ) + + var forward := -camera_rig.global_transform.basis.z + var right := camera_rig.global_transform.basis.x + + forward.y = 0 + right.y = 0 + + forward = forward.normalized() + right = right.normalized() + + var direction := (right * input.x + forward * -input.y).normalized() + + var target_velocity := direction * move_speed + + velocity.x = move_toward(velocity.x, target_velocity.x, acceleration * delta) + velocity.z = move_toward(velocity.z, target_velocity.z, acceleration * delta) + velocity.y = 0.0 + + move_and_slide() + + if direction.length() > 0.01: + var target_angle := atan2(direction.x, direction.z) + rotation.y = lerp_angle(rotation.y, target_angle, rotation_speed * delta) diff --git a/scenes/player/player.gd.uid b/scenes/player/player.gd.uid new file mode 100644 index 0000000..047bf7f --- /dev/null +++ b/scenes/player/player.gd.uid @@ -0,0 +1 @@ +uid://4mg67crlim53