diff --git a/src/logic-scenes/player_controller/player_controller.gd b/src/logic-scenes/player_controller/player_controller.gd new file mode 100644 index 0000000..09f21ec --- /dev/null +++ b/src/logic-scenes/player_controller/player_controller.gd @@ -0,0 +1,127 @@ +extends RigidBody3D + +@export var active: bool = true : set = set_active +@export_range (0, 10) var max_speed: float = 3 +@export_range (0, 10) var max_acceleration: float = 5 +@export_range (0, 20) var damp: float = 10 +@export_range (0.1, 1) var mouse_jerk:float = 0.5 +@export_range (10, 100) var gamepad_response = 50 +@export_range (50, 500) var mouse_jerk_rejection = 200 +@export var max_angle:float = 75 + +@export var camera_jitter_speed:float = 3 +@export var angular_jitter:Vector3 = Vector3(0.1, 0, 0.05) +@export var angular_jitter_speed:Vector3 = Vector3(2, 1, 1) +@export var location_jitter:Vector3 = Vector3(0.1, 0.1, 0.1) +@export var location_jitter_speed:Vector3 = Vector3(3, 0.3, 1) + +var loc_noise_spot: Vector3 = Vector3.ZERO +var rot_noise_spot: Vector3 = Vector3.ZERO + +var rotation_speed: Vector2 = Vector2.ZERO +var current_mouse_rotation: Vector2 = Vector2.ZERO +var mouse_sensitivity: Vector2 = Vector2(3, 3) +var noise: Noise = FastNoiseLite.new() +var crouched:bool = false + +@onready var yaw:Node3D = $Yaw +@onready var pitch:Node3D = $Yaw/Pitch +@onready var mount:Node3D = $Yaw/Pitch/Mount +@onready var camera:Camera3D = $Yaw/Pitch/Mount/Camera3D + + +func set_active(activate): + if !is_inside_tree(): return + if activate: + camera.make_current() + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + sleeping = active + +func _ready(): + + if active: + set_active(active) + + +func _physics_process(delta:float): + _handle_movement(delta) + _handle_rotation(delta) + _handle_jitter(delta) + +func _handle_movement(delta:float): + var input:Vector2 = Vector2(Input.get_action_strength("player_right") - Input.get_action_strength("player_left"), + Input.get_action_strength("player_backwards")*0.8 - Input.get_action_strength("player_forwards")) + + if input.length()>1: + input = input.normalized() + + var direction: Vector3 = Vector3(input.x, 0, input.y) + + direction = yaw.global_transform.basis.x * direction.x + transform.basis.y * direction.y + yaw.global_transform.basis.z * direction.z + + if linear_velocity.length() > (linear_velocity + (direction*max_speed - linear_velocity)).length(): + direction = Vector3.ZERO + else: + direction *= (direction*max_speed - linear_velocity).length()*max_acceleration + + linear_damp = damp * max(0.5, 1 - input.length()) + + apply_central_impulse(direction*delta) + +func _handle_rotation(delta:float): + var smoothness = 60/Engine.get_frames_per_second() + + var input_speed = Vector2( Input.get_action_strength("look_right")-Input.get_action_strength("look_left"), Input.get_action_strength("look_down")-Input.get_action_strength("look_up")) * gamepad_response + + if current_mouse_rotation.length()>0: + input_speed = current_mouse_rotation + current_mouse_rotation = Vector2.ZERO + + rotation_speed = rotation_speed * (1-mouse_jerk*smoothness) + input_speed * mouse_jerk * smoothness + + if rotation_speed.y > 0 and pitch.rotation_degrees.x < 0: + rotation_speed.y *= 1-pow(pitch.rotation_degrees.x/-max_angle, 4) + elif rotation_speed.y < 0 and pitch.rotation_degrees.x > 0 : + rotation_speed.y *= 1-pow(pitch.rotation_degrees.x/max_angle, 4) + + yaw.rotate_y(deg_to_rad(-rotation_speed.x * delta * mouse_sensitivity.x)) + pitch.rotate_x(deg_to_rad(-rotation_speed.y * delta * mouse_sensitivity.y)) + +func _handle_jitter(delta): + loc_noise_spot += Vector3(delta * camera_jitter_speed * location_jitter_speed) + rot_noise_spot += Vector3(delta * camera_jitter_speed * angular_jitter_speed) + pitch.position = Vector3( + noise.get_noise_1d(loc_noise_spot.x), + noise.get_noise_1d(loc_noise_spot.y), + noise.get_noise_1d(loc_noise_spot.z) + ) * location_jitter + + mount.rotation = Vector3( + noise.get_noise_1d(rot_noise_spot.x), + noise.get_noise_1d(rot_noise_spot.y), + noise.get_noise_1d(rot_noise_spot.z) + ) * angular_jitter + + +func _handle_mouse_input(event:InputEventMouseMotion): + if event.relative.length() < mouse_jerk_rejection: + current_mouse_rotation = event.relative + +func _unhandled_input(event:InputEvent): + if active: + if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + _handle_mouse_input(event) + + +func _on_bed_enter(body): + if not crouched: + $PlayerAnimationPlayer.queue("crouch") + max_speed *= .5 + crouched = true + +func _on_bed_exited(body): + if crouched: + crouched = false + $PlayerAnimationPlayer.queue("stand_up") + await $PlayerAnimationPlayer.animation_finished + max_speed *= 2 diff --git a/src/logic-scenes/player_controller/player_controller.tscn b/src/logic-scenes/player_controller/player_controller.tscn new file mode 100644 index 0000000..6a2cdd6 --- /dev/null +++ b/src/logic-scenes/player_controller/player_controller.tscn @@ -0,0 +1,131 @@ +[gd_scene load_steps=8 format=3 uid="uid://mkccbig41bqb"] + +[ext_resource type="Script" path="res://logic-scenes/player_controller/player_controller.gd" id="1_0b4mi"] + +[sub_resource type="PhysicsMaterial" id="10"] +friction = 0.0 + +[sub_resource type="SphereShape3D" id="8"] +radius = 0.307047 + +[sub_resource type="Animation" id="11"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Yaw:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1.22534, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Yaw/Pitch/Mount/Camera3D:rotation_degrees") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="12"] +resource_name = "crouch" +length = 3.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Yaw:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1.2, 1.9, 2.6), +"transitions": PackedFloat32Array(1.36604, 1, 1, 1), +"update": 0, +"values": [Vector3(0, 1.22534, 0), Vector3(0, 0.5, 0), Vector3(0, 0.27, 0), Vector3(0, 0.327816, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Yaw/Pitch/Mount/Camera3D:rotation_degrees") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.6, 1.6, 2.4, 3), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-30, 0, -10), Vector3(-20, 0, 3), Vector3(0, 0, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="14"] +resource_name = "stand_up" +length = 3.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Yaw:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.9, 1.7, 3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Vector3(0, 0.327816, 0), Vector3(0, 0.331, 0), Vector3(0, 1.3, 0), Vector3(0, 1.22534, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Yaw/Pitch/Mount/Camera3D:rotation_degrees") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.6, 1.3, 2.2, 3), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-4.79133, 3.17287, -3.71499), Vector3(24.594, -3.154, -4.794), Vector3(0.103793, -1.69217, -1.78899), Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_xbx3w"] +_data = { +"RESET": SubResource("11"), +"crouch": SubResource("12"), +"stand_up": SubResource("14") +} + +[node name="PlayerController" type="RigidBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.26517, 1.19209e-07, 1.70185) +collision_layer = 3 +axis_lock_angular_x = true +axis_lock_angular_y = true +axis_lock_angular_z = true +physics_material_override = SubResource("10") +can_sleep = false +script = ExtResource("1_0b4mi") + +[node name="Yaw" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.22534, 0) + +[node name="Pitch" type="Node3D" parent="Yaw"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.256493, 0) + +[node name="Mount" type="Node3D" parent="Yaw/Pitch"] + +[node name="Camera3D" type="Camera3D" parent="Yaw/Pitch/Mount"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.202, 0.157) +current = true + +[node name="PlayerCollision" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.322255, 0) +shape = SubResource("8") + +[node name="PlayerAnimationPlayer" type="AnimationPlayer" parent="."] +autoplay = "RESET" +libraries = { +"": SubResource("AnimationLibrary_xbx3w") +}