From b342a38312eb9ee325e8d624fa28286a1b4cf1e4 Mon Sep 17 00:00:00 2001 From: Clifton Palmer Date: Tue, 6 May 2025 12:27:25 +0300 Subject: [PATCH] Added CameraHandler, InputHandler --- player/CameraHandler.gd | 61 ++++++++++++++++ player/CameraHandler.gd.uid | 1 + player/InputHandler.gd | 12 ++++ player/InputHandler.gd.uid | 1 + player/InputPacket.gd | 4 ++ player/InputPacket.gd.uid | 1 + player/player.gd | 140 +++++------------------------------- player/player.tscn | 15 ++-- 8 files changed, 109 insertions(+), 126 deletions(-) create mode 100644 player/CameraHandler.gd create mode 100644 player/CameraHandler.gd.uid create mode 100644 player/InputHandler.gd create mode 100644 player/InputHandler.gd.uid create mode 100644 player/InputPacket.gd create mode 100644 player/InputPacket.gd.uid diff --git a/player/CameraHandler.gd b/player/CameraHandler.gd new file mode 100644 index 0000000..448260f --- /dev/null +++ b/player/CameraHandler.gd @@ -0,0 +1,61 @@ +extends Node3D +class_name CameraHandler + + +enum CameraInput {MOUSE, JOYSTICK} + +@export_range(1.0, 10.0) var camera_distance := 3.0 +@export_range(0.0, 1.0) var mouse_sensitivity := 0.15 +@export_range(0.0, 1.0) var mouse_sensitivity_x := 1.0 +@export_range(0.0, 1.0) var mouse_sensitivity_y := 0.5 +@export_range(0.0, 10.0) var joystick_sensitivity_x := 4.0 +@export_range(0.0, 10.0) var joystick_sensitivity_y := 2.0 + + +var camera_input_method := CameraInput.MOUSE +var camera_input_direction := Vector2.ZERO +var player_input_direction := Vector2.ZERO + + +@onready var _input: InputHandler = %Input +@onready var _spring: SpringArm3D = $spring + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + _spring.spring_length = camera_distance + + +func _unhandled_input(event: InputEvent) -> void: + # If user clicks on the window, capture the mouse and direct the camera with it + if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED: + return + + #_camera_input_direction *= mouse_sensitivity + if event is InputEventMouseMotion: + camera_input_method = CameraInput.MOUSE + camera_input_direction = event.screen_relative * mouse_sensitivity + elif event is InputEventJoypadMotion: + # TODO: add these settings! + camera_input_method = CameraInput.JOYSTICK + camera_input_direction = _input.get_camera_input_direction() + camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + # vertical camera rotation + rotation.x += camera_input_direction.y * mouse_sensitivity_y * delta + rotation.x = clamp(rotation.x, -PI / 6, PI / 3) + + # horizontal camera rotation + rotation.y -= camera_input_direction.x * mouse_sensitivity_x * delta + + # reset mouse movement vector if mouse input + if camera_input_method == CameraInput.MOUSE: + camera_input_direction = Vector2.ZERO + + # change spring length + _spring.spring_length = lerp( + _spring.spring_length, camera_distance, delta + ) diff --git a/player/CameraHandler.gd.uid b/player/CameraHandler.gd.uid new file mode 100644 index 0000000..846a69e --- /dev/null +++ b/player/CameraHandler.gd.uid @@ -0,0 +1 @@ +uid://c5mn28v6ujngk diff --git a/player/InputHandler.gd b/player/InputHandler.gd new file mode 100644 index 0000000..35a0aee --- /dev/null +++ b/player/InputHandler.gd @@ -0,0 +1,12 @@ +extends Node +class_name InputHandler + + +func get_camera_input_direction() -> Vector2: + return Input.get_vector("camera-left", "camera-right", "camera-up", "camera-down") + + +func get_player_input() -> InputPacket: + var p: InputPacket = InputPacket.new() + p.movement_direction = Input.get_vector("player-left", "player-right", "player-forward", "player-backward") + return p diff --git a/player/InputHandler.gd.uid b/player/InputHandler.gd.uid new file mode 100644 index 0000000..713eb30 --- /dev/null +++ b/player/InputHandler.gd.uid @@ -0,0 +1 @@ +uid://bspr3vafk6wi2 diff --git a/player/InputPacket.gd b/player/InputPacket.gd new file mode 100644 index 0000000..0599e1d --- /dev/null +++ b/player/InputPacket.gd @@ -0,0 +1,4 @@ +extends Node +class_name InputPacket + +var movement_direction: Vector2 = Vector2.ZERO diff --git a/player/InputPacket.gd.uid b/player/InputPacket.gd.uid new file mode 100644 index 0000000..33ad24a --- /dev/null +++ b/player/InputPacket.gd.uid @@ -0,0 +1 @@ +uid://cxsrxduew6xnc diff --git a/player/player.gd b/player/player.gd index 11e41ac..ce43a78 100644 --- a/player/player.gd +++ b/player/player.gd @@ -8,89 +8,38 @@ class_name Player @export_group("Movement") @export var walk_speed := 8.0 @export var dash_length := 10.0 - @export var air_speed := 3.0 @export var acceleration := 30.0 @export var rotation_speed := 10.0 @export var idle_timeout := 5.0 -@export_group("Camera") -@export_range(1.0, 10.0) var camera_distance := 2.0 -@export_range(0.0, 1.0) var mouse_sensitivity := 0.15 -@export_range(0.0, 1.0) var mouse_sensitivity_x := 1.0 -@export_range(0.0, 1.0) var mouse_sensitivity_y := 0.5 -@export_range(0.0, 10.0) var joystick_sensitivity_x := 4.0 -@export_range(0.0, 10.0) var joystick_sensitivity_y := 2.0 - ###### # init ###### -@onready var _camera_pivot: Node3D = %camera_pivot +@onready var _input: InputHandler = %Input @onready var _camera: Camera3D = %camera -@onready var _camera_spring: SpringArm3D = %spring @onready var _skin: AnimatedSkin = %skin -var _last_movement_direction := rotation +var _last_movement_direction: Vector3 = rotation var _floor_normal := Vector3.ONE var _ground_slope_input := 0.0 -var _camera_input_direction := Vector2.ZERO var _idle_time: float = 0.0 var _player_speed: float = walk_speed -enum CameraInput {MOUSE, JOYSTICK} -var _camera_input_method := CameraInput.MOUSE - - -func _ready() -> void: - _camera_spring.spring_length = camera_distance - - - -####### -# input -####### - -func _unhandled_input(event: InputEvent) -> void: - # If user clicks on the window, capture the mouse and direct the camera with it - if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED: - return - - #_camera_input_direction *= mouse_sensitivity - if event is InputEventMouseMotion: - _camera_input_method = CameraInput.MOUSE - _camera_input_direction = event.screen_relative * mouse_sensitivity - elif event is InputEventJoypadMotion: - # TODO: add these settings! - _camera_input_method = CameraInput.JOYSTICK - _camera_input_direction = Input.get_vector("camera-left", "camera-right", "camera-up", "camera-down") - _camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y) - - -func _input(event: InputEvent): - if event.is_action_pressed("player-dash"): - _skin.transition_dash() - _player_dash() - elif event.is_action_pressed("player-slash"): - _skin.sword_visible() - _skin.transition_slash() - elif event.is_action_pressed("player-shoot"): - _skin.gun_visible() - _skin.transition_gunfire() - ########## # movement ########## func _physics_process(delta: float) -> void: - _process_camera(delta) - _process_player(delta) + var input_pkt := _input.get_player_input() + velocity = _get_velocity_by_input(input_pkt, delta) + move_and_slide() # Get the XZ input direction based on player's input relative to the camera -func _get_player_move_direction() -> Vector3: - var input_dir := Input.get_vector("player-left", "player-right", "player-forward", "player-backward") +func _get_player_move_direction(input_dir: Vector2) -> Vector3: var forward := _camera.global_basis.z var right := _camera.global_basis.x var move_direction := (forward * input_dir.y + right * input_dir.x).normalized() @@ -98,76 +47,23 @@ func _get_player_move_direction() -> Vector3: return move_direction -func _process_camera(delta: float) -> void: - # vertical camera rotation - _camera_pivot.rotation.x += _camera_input_direction.y * mouse_sensitivity_y * delta - _camera_pivot.rotation.x = clamp(_camera_pivot.rotation.x, -PI / 6, PI / 3) - - # horizontal camera rotation - _camera_pivot.rotation.y -= _camera_input_direction.x * mouse_sensitivity_x * delta - - # reset mouse movement vector if mouse input - if _camera_input_method == CameraInput.MOUSE: - _camera_input_direction = Vector2.ZERO - - # change spring length depending on player speed - _camera_spring.spring_length = lerp( - _camera_spring.spring_length, camera_distance + velocity.length() / 4, delta - ) - - -func _process_player_on_floor(delta: float): - var move_direction := _get_player_move_direction() - - # if we're not stuck, then it's okay to set the velocity - _floor_normal = get_floor_normal() - _ground_slope_input = (PI / 2) - velocity.angle_to(_floor_normal) - velocity = velocity.move_toward( - move_direction * (_player_speed + _ground_slope_input * _player_speed), - acceleration * delta - ) - var movement_speed := Vector3(velocity.x, 0, velocity.z).length() +func _get_velocity_by_input(input_pkt: InputPacket, delta: float) -> Vector3: + var new_velocity: Vector3 = velocity - # also, if we're moving, we're not idle - if move_direction.length() < 0.2: - if velocity == Vector3.ZERO: - _idle_time += delta - else: - _last_movement_direction = move_direction - _idle_time = 0.0 - - # if camera is unlocked, rotate whole skin to face movement direction - var skin_target_angle := Vector3.BACK.signed_angle_to(_last_movement_direction, Vector3.UP) - _skin.global_rotation.y = lerp_angle( - _skin.global_rotation.y, - skin_target_angle, - rotation_speed * delta - ) - - # lean into player momentum just a little bit - _skin.rotation.z = lerp_angle( - _skin.rotation.z, - clamp(_last_movement_direction.signed_angle_to(velocity, Vector3.UP) * movement_speed * 0.08, -PI/4, PI/ 4), - rotation_speed * delta * 0.25 - ) - - # let skin know how fast player is moving along the ground - _skin.set_walking_speed(movement_speed) - - -func _process_player(delta: float) -> void: if is_on_floor(): - _process_player_on_floor(delta) + var move_dir := _get_player_move_direction(input_pkt.movement_direction) - if _idle_time > idle_timeout: - _skin.transition_move() - else: - _skin.transition_move() + # if we're not stuck, then it's okay to set the velocity + _floor_normal = get_floor_normal() + _ground_slope_input = (PI / 2) - new_velocity.angle_to(_floor_normal) + new_velocity = new_velocity.move_toward( + move_dir * (_player_speed + _ground_slope_input * _player_speed), + acceleration * delta + ) else: - _skin.transition_falling() - velocity += get_gravity() * air_speed * delta + new_velocity += get_gravity() * air_speed * delta - move_and_slide() + return new_velocity ######### # actions diff --git a/player/player.tscn b/player/player.tscn index 5f8dc6c..4d86286 100644 --- a/player/player.tscn +++ b/player/player.tscn @@ -1,7 +1,9 @@ -[gd_scene load_steps=4 format=3 uid="uid://cchu1yltrhuk3"] +[gd_scene load_steps=6 format=3 uid="uid://cchu1yltrhuk3"] [ext_resource type="PackedScene" uid="uid://dvkx3t15l7mfb" path="res://skin/prototype_skin.tscn" id="1_4flbx"] [ext_resource type="Script" uid="uid://dcv34jq0jett0" path="res://player/player.gd" id="1_onrkg"] +[ext_resource type="Script" uid="uid://bspr3vafk6wi2" path="res://player/InputHandler.gd" id="3_g1dw6"] +[ext_resource type="Script" uid="uid://c5mn28v6ujngk" path="res://player/CameraHandler.gd" id="3_yw30f"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_sh265"] @@ -17,13 +19,18 @@ shape = SubResource("CapsuleShape3D_sh265") [node name="skin" parent="." instance=ExtResource("1_4flbx")] unique_name_in_owner = true -[node name="camera_pivot" type="Node3D" parent="."] +[node name="CameraPivot" type="Node3D" parent="."] unique_name_in_owner = true +script = ExtResource("3_yw30f") -[node name="spring" type="SpringArm3D" parent="camera_pivot"] +[node name="spring" type="SpringArm3D" parent="CameraPivot"] unique_name_in_owner = true transform = Transform3D(-1, -2.99003e-08, 8.21505e-08, 0, 0.939693, 0.34202, -8.74228e-08, 0.34202, -0.939693, 0, 1.52762, 0) spring_length = 3.0 -[node name="camera" type="Camera3D" parent="camera_pivot/spring"] +[node name="camera" type="Camera3D" parent="CameraPivot/spring"] unique_name_in_owner = true + +[node name="Input" type="Node" parent="."] +unique_name_in_owner = true +script = ExtResource("3_g1dw6") -- 2.47.2