Basic player controller & level

This commit is contained in:
Rob Kelly 2025-02-28 15:20:52 -07:00
parent 317325c393
commit 977ca741aa
5 changed files with 234 additions and 2 deletions

View File

@ -0,0 +1,71 @@
[gd_scene load_steps=9 format=3 uid="uid://16ds4fvv72xk"]
[ext_resource type="PackedScene" uid="uid://bwe2jdmvinhqd" path="res://src/player/player.tscn" id="1_h436a"]
[sub_resource type="Environment" id="Environment_cc548"]
background_mode = 1
tonemap_mode = 3
fog_enabled = true
fog_light_color = Color(0, 0, 0, 1)
fog_density = 0.2
[sub_resource type="PlaneMesh" id="PlaneMesh_4afx3"]
size = Vector2(50, 50)
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_c8g65"]
[sub_resource type="BoxMesh" id="BoxMesh_mer5b"]
[sub_resource type="BoxShape3D" id="BoxShape3D_hx5n6"]
[sub_resource type="CylinderMesh" id="CylinderMesh_a1koa"]
top_radius = 1.0
bottom_radius = 1.0
height = 4.0
[sub_resource type="CylinderShape3D" id="CylinderShape3D_uo57d"]
height = 4.0
radius = 1.0
[node name="Sandbox" type="Node3D"]
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_cc548")
[node name="SpotLight3D" type="SpotLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 10, 0)
light_energy = 16.0
shadow_enabled = true
spot_range = 20.0
spot_angle_attenuation = 0.05
[node name="Geometry" type="Node3D" parent="."]
[node name="Floor" type="StaticBody3D" parent="Geometry"]
[node name="MeshInstance3D" type="MeshInstance3D" parent="Geometry/Floor"]
mesh = SubResource("PlaneMesh_4afx3")
skeleton = NodePath("../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Geometry/Floor"]
shape = SubResource("WorldBoundaryShape3D_c8g65")
[node name="Box" type="StaticBody3D" parent="Geometry"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0.5, 4)
[node name="MeshInstance3D" type="MeshInstance3D" parent="Geometry/Box"]
mesh = SubResource("BoxMesh_mer5b")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Geometry/Box"]
shape = SubResource("BoxShape3D_hx5n6")
[node name="Cylinder" type="StaticBody3D" parent="Geometry"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2, -2)
[node name="MeshInstance3D" type="MeshInstance3D" parent="Geometry/Cylinder"]
mesh = SubResource("CylinderMesh_a1koa")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Geometry/Cylinder"]
shape = SubResource("CylinderShape3D_uo57d")
[node name="Player" parent="." instance=ExtResource("1_h436a")]

View File

@ -11,9 +11,9 @@ config_version=5
[application] [application]
config/name="Grunk" config/name="Grunk"
config/features=PackedStringArray("4.2", "Forward Plus") run/main_scene="res://levels/sandbox/sandbox.tscn"
config/features=PackedStringArray("4.3", "Forward Plus")
run/max_fps=60 run/max_fps=60
config/icon="res://icon.svg"
[debug] [debug]
@ -25,6 +25,8 @@ gdscript/warnings/unsafe_call_argument=2
[display] [display]
window/size/viewport_width=1920
window/size/viewport_height=1080
window/stretch/mode="canvas_items" window/stretch/mode="canvas_items"
[dotnet] [dotnet]
@ -38,3 +40,53 @@ movie_writer/movie_file="demos/demo.avi"
[editor_plugins] [editor_plugins]
enabled=PackedStringArray("res://addons/format_on_save/plugin.cfg", "res://addons/gdlint_plugin/plugin.cfg") enabled=PackedStringArray("res://addons/format_on_save/plugin.cfg", "res://addons/gdlint_plugin/plugin.cfg")
[game]
config/input/mouse_sensitivity_x=0.45
config/input/mouse_sensitivity_y=0.45
config/input/invert_pitch=false
config/input/mouse_acceleration=30.0
[input]
move_forward={
"deadzone": 0.5,
"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_left={
"deadzone": 0.5,
"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_back={
"deadzone": 0.5,
"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_right={
"deadzone": 0.5,
"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)
]
}
jump={
"deadzone": 0.5,
"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,"location":0,"echo":false,"script":null)
]
}
sneak={
"deadzone": 0.5,
"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":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
sprint={
"deadzone": 0.5,
"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,"location":0,"echo":false,"script":null)
]
}
fire={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}

View File

@ -0,0 +1,34 @@
class_name CameraController extends Node3D
const PITCH_LIMIT := deg_to_rad(85.0)
@onready var _target := Vector2(rotation.x, rotation.y)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
camera_motion((event as InputEventMouseMotion).relative)
elif event is InputEventMouseButton:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func camera_motion(motion: Vector2) -> void:
var x_sensitivity: float = ProjectSettings.get_setting("game/config/input/mouse_sensitivity_x")
var y_sensitivity: float = ProjectSettings.get_setting("game/config/input/mouse_sensitivity_y")
var invert_pitch: bool = ProjectSettings.get_setting("game/config/input/invert_pitch")
_target.y -= deg_to_rad(motion.x * x_sensitivity)
_target.x = clampf(
_target.x - deg_to_rad(motion.y * y_sensitivity) * (-1 if invert_pitch else 1),
-PITCH_LIMIT,
PITCH_LIMIT
)
func _physics_process(_delta: float) -> void:
var mouse_accel: float = (
ProjectSettings.get_setting("game/config/input/mouse_acceleration") / 60.0
)
rotation.y = lerp_angle(rotation.y, _target.y, mouse_accel)
rotation.x = lerp_angle(rotation.x, _target.x, mouse_accel)

54
src/player/player.gd Normal file
View File

@ -0,0 +1,54 @@
class_name Player extends CharacterBody3D
const RUN_SPEED := 80.0
const SPRINT_SPEED := 160.0
const AIR_SPEED := 30.0
const JUMP_FORCE := 4.5
const GROUND_FRICTION := 0.3
const AIR_FRICTION := 0.03
var gravity: Vector3 = (
ProjectSettings.get_setting("physics/3d/default_gravity")
* ProjectSettings.get_setting("physics/3d/default_gravity_vector")
)
@onready var camera_pivot: Node3D = %CameraPivot
func get_speed() -> float:
if is_on_floor():
if Input.is_action_pressed("sprint"):
return SPRINT_SPEED
return RUN_SPEED
return AIR_SPEED
func get_friction() -> float:
if is_on_floor():
return GROUND_FRICTION
return AIR_FRICTION
func _physics_process(delta: float) -> void:
# Gravity
if not is_on_floor():
velocity += gravity * delta
# Input movement
var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
var direction := (
(camera_pivot.global_basis * Vector3(input_dir.x, 0, input_dir.y) * Vector3(1, 0, 1))
. normalized()
)
var movement := direction * get_speed() * delta
velocity.x += movement.x
velocity.z += movement.z
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_FORCE
# Friction
var friction := get_friction()
velocity.x = lerpf(velocity.x, 0, friction)
velocity.z = lerpf(velocity.z, 0, friction)
move_and_slide()

21
src/player/player.tscn Normal file
View File

@ -0,0 +1,21 @@
[gd_scene load_steps=4 format=3 uid="uid://bwe2jdmvinhqd"]
[ext_resource type="Script" path="res://src/player/player.gd" id="1_npueo"]
[ext_resource type="Script" path="res://src/player/camera_controller.gd" id="2_veeqv"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s7f0r"]
[node name="Player" type="CharacterBody3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
script = ExtResource("1_npueo")
[node name="CameraPivot" type="Node3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
script = ExtResource("2_veeqv")
[node name="Camera3D" type="Camera3D" parent="CameraPivot"]
current = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_s7f0r")