From 6ed8ebff26df3969f646fcae467817644e7e05cf Mon Sep 17 00:00:00 2001 From: Minimata Date: Fri, 23 May 2025 16:00:20 +0200 Subject: [PATCH] gd: dash target --- player_controller/PlayerController.tscn | 27 +++++++++----- player_controller/Scripts/DashSystem.cs | 35 +++++++++++++++++++ player_controller/Scripts/DashSystem.cs.uid | 1 + player_controller/Scripts/Mouse.cs | 26 ++++++++------ player_controller/Scripts/PlayerController.cs | 35 +++++++++++++++++-- project.godot | 26 ++++++++++++++ 6 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 player_controller/Scripts/DashSystem.cs create mode 100644 player_controller/Scripts/DashSystem.cs.uid diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index 9c00a89..c9f43a9 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=23 format=3 uid="uid://bei4nhkf8lwdo"] +[gd_scene load_steps=25 format=3 uid="uid://bei4nhkf8lwdo"] [ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"] [ext_resource type="Material" uid="uid://dtq8i1ka1f2pn" path="res://player_controller/Assets/Materials/Health/CameraVignette.tres" id="2_6hee7"] @@ -9,6 +9,7 @@ [ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://player_controller/Scripts/StairsSystem.cs" id="7_bmt5a"] [ext_resource type="Script" uid="uid://dd1yrt7eiiyf4" path="res://player_controller/Scripts/CapsuleCollider.cs" id="8_lmtjd"] [ext_resource type="Script" uid="uid://bt0xv2q8iv1vn" path="res://player_controller/Scripts/Gravity.cs" id="9_lsueh"] +[ext_resource type="Script" uid="uid://dwoppk8j5fxeg" path="res://player_controller/Scripts/DashSystem.cs" id="9_qu4wy"] [ext_resource type="Script" uid="uid://g8idirw62qe0" path="res://player_controller/Scripts/Bobbing.cs" id="10_7wk1w"] [ext_resource type="Script" uid="uid://c6bx47wr7fbdm" path="res://player_controller/Scripts/Mouse.cs" id="11_huhen"] [ext_resource type="Script" uid="uid://b6k73aj5povgv" path="res://player_controller/Scripts/FieldOfView.cs" id="12_m2mxi"] @@ -26,6 +27,9 @@ shader_parameter/blur = 0.0 [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_4coqe"] +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_qu4wy"] +height = 1.5 + [sub_resource type="Animation" id="Animation_vcu7l"] length = 0.001 tracks/0/type = "bezier" @@ -114,6 +118,7 @@ _data = { script = ExtResource("1_poq2x") WalkSpeed = 10.0 SprintSpeed = 15.0 +ControllerSensitivity = 30.0 [node name="MeshInstance3D" type="MeshInstance3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) @@ -197,14 +202,20 @@ debug_shape_custom_color = Color(1, 0, 0, 1) [node name="WallInFrontCast3D" type="ShapeCast3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) -shape = SubResource("CapsuleShape3D_4coqe") -target_position = Vector3(0, 0, -2) -debug_shape_custom_color = Color(1, 0, 0, 1) +shape = SubResource("CapsuleShape3D_qu4wy") +target_position = Vector3(0, 0, -1.5) +max_results = 1 +debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1) -[node name="WallInFrontRayCast3D" type="RayCast3D" parent="."] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 1.65, 0) -enabled = false -target_position = Vector3(0, -2, 0) +[node name="DashSystem" type="Node3D" parent="."] +script = ExtResource("9_qu4wy") + +[node name="DashCast3D" type="ShapeCast3D" parent="DashSystem"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.68, 0) +shape = SubResource("CapsuleShape3D_qu4wy") +target_position = Vector3(0, 0, -20) +max_results = 1 +debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1) [node name="StairsSystem" type="Node3D" parent="."] script = ExtResource("7_bmt5a") diff --git a/player_controller/Scripts/DashSystem.cs b/player_controller/Scripts/DashSystem.cs new file mode 100644 index 0000000..cb9f60b --- /dev/null +++ b/player_controller/Scripts/DashSystem.cs @@ -0,0 +1,35 @@ +using Godot; +using RustyOptions; + +namespace PolarBears.PlayerControllerAddon; + +public partial class DashSystem: Node3D +{ + [Export(PropertyHint.Range, "0,0.2,0.01,or_greater")] + public float DashSpeed { get; set; } = 0.05f; + + private Node3D _head; + private ShapeCast3D _dashCast3D; + private Camera3D _camera; + + public void Init(Node3D head, Camera3D camera) + { + _dashCast3D = GetNode("DashCast3D"); + _head = head; + _camera = camera; + } + + public Result PrepareDash() + { + _dashCast3D.SetRotation(new Vector3( + _camera.Rotation.X, + _head.Rotation.Y, + _camera.Rotation.Z)); + + var dashLocation = _dashCast3D.IsColliding() + ? _dashCast3D.GetCollisionPoint(0) + : _dashCast3D.GetTargetPosition(); + + return Result.Ok(dashLocation); + } +} diff --git a/player_controller/Scripts/DashSystem.cs.uid b/player_controller/Scripts/DashSystem.cs.uid new file mode 100644 index 0000000..c737ad9 --- /dev/null +++ b/player_controller/Scripts/DashSystem.cs.uid @@ -0,0 +1 @@ +uid://dwoppk8j5fxeg diff --git a/player_controller/Scripts/Mouse.cs b/player_controller/Scripts/Mouse.cs index 0ba3811..95aa045 100644 --- a/player_controller/Scripts/Mouse.cs +++ b/player_controller/Scripts/Mouse.cs @@ -24,6 +24,20 @@ public partial class Mouse : Node3D _isPlayerDead = isDeadFunc; } + public void LookAround(Vector2 lookDir) + { + // Horizontal movement of head + float angleForHorizontalRotation = lookDir.X * Sensitivity; + _head.RotateY(angleForHorizontalRotation); + + // Vertical movement of head + Vector3 currentCameraRotation = _camera.Rotation; + currentCameraRotation.X += Convert.ToSingle(lookDir.Y * Sensitivity); + currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f)); + + _camera.Rotation = currentCameraRotation; + } + public override void _UnhandledInput(InputEvent @event) { if (_isPlayerDead()) @@ -33,16 +47,8 @@ public partial class Mouse : Node3D if (@event is InputEventMouseMotion eventMouseMotion) { - // Horizontal movement of head - float angleForHorizontalRotation = -eventMouseMotion.Relative.X * Sensitivity; - _head.RotateY(angleForHorizontalRotation); - - // Vertical movement of head - Vector3 currentCameraRotation = _camera.Rotation; - currentCameraRotation.X += Convert.ToSingle(-eventMouseMotion.Relative.Y * Sensitivity); - currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f)); - - _camera.Rotation = currentCameraRotation; + var lookDir = new Vector2(-eventMouseMotion.Relative.X, -eventMouseMotion.Relative.Y); + LookAround(lookDir); } } } diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index ad67f87..8bc688e 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -11,6 +11,7 @@ public partial class PlayerController : CharacterBody3D public Stamina Stamina; public StairsSystem StairsSystem; public MantleSystem MantleSystem; + public DashSystem DashSystem; public CapsuleCollider CapsuleCollider; public Gravity Gravity; public HealthSystem HealthSystem; @@ -27,8 +28,12 @@ public partial class PlayerController : CharacterBody3D [Export(PropertyHint.Range, "0,5,0.1,or_greater")] public float DoubleJumpSpeedFactor { get; set; } = 2f; + + [Export(PropertyHint.Range, "1,50,1,or_greater")] + public float ControllerSensitivity { get; set; } = 20f; private bool _canDoubleJump = true; + private bool _movementEnabled = true; private float _currentSpeed; @@ -95,6 +100,9 @@ public partial class PlayerController : CharacterBody3D MantleSystem = GetNode("MantleSystem"); MantleSystem.Init(wallInFrontCast3D, Head, mantleCast3D); + + DashSystem = GetNode("DashSystem"); + DashSystem.Init(Head, camera); CapsuleCollider = GetNode("CapsuleCollider"); @@ -121,8 +129,19 @@ public partial class PlayerController : CharacterBody3D Mouse.Init(Head, camera, HealthSystem.IsDead); } + private void DisableMovement() + { + _movementEnabled = false; + } + public void EnableMovement() + { + _movementEnabled = true; + } + public override void _PhysicsProcess(double delta) { + var dashLocation = DashSystem.PrepareDash().Unwrap(); + var mantleLocationResult = MantleSystem.CheckWallInFront(); if (isOnFloorCustom()) { @@ -143,14 +162,22 @@ public partial class PlayerController : CharacterBody3D bool isPlayerDead = HealthSystem.IsDead(); - // Handle Jumping + // Handle Jump input if (Input.IsActionJustPressed("jump") && !doesCapsuleHaveCrouchingHeight && !isPlayerDead) { if (mantleLocationResult.IsOk(out var mantleLocation)) { - Position = mantleLocation; + Tween tween = GetTree().CreateTween(); + var duration = 0.1f * mantleLocation.DistanceTo(Position); + var callback = new Callable(this, MethodName.EnableMovement); + + tween.TweenProperty(this, "position", mantleLocation, duration); + tween.TweenCallback(callback); + + DisableMovement(); + tween.Play(); } else if (isOnFloorCustom()) { @@ -170,7 +197,6 @@ public partial class PlayerController : CharacterBody3D } } - bool isHeadTouchingCeiling = IsHeadTouchingCeiling(); bool doesCapsuleHaveDefaultHeight = CapsuleCollider.IsDefaultHeight(); @@ -209,6 +235,9 @@ public partial class PlayerController : CharacterBody3D { _currentSpeed = SprintSpeed; } + + Vector2 inputLookDir = Input.GetVector("look_left", "look_right", "look_up", "look_down"); + Mouse.LookAround(-1 * ControllerSensitivity * inputLookDir); // Get the input direction Vector2 inputDir = Input.GetVector("left", "right", "up", "down"); diff --git a/project.godot b/project.godot index 0abf8b0..d45625e 100644 --- a/project.godot +++ b/project.godot @@ -24,27 +24,32 @@ project/assembly_name="Movement tests" up={ "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) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) ] } down={ "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) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) ] } 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) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) ] } 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) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) ] } jump={ "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":4194308,"key_label":0,"unicode":0,"location":0,"echo":false,"script":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":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null) ] } crouch={ @@ -57,6 +62,27 @@ sprint={ "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":45,"key_label":0,"unicode":45,"location":0,"echo":false,"script":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":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":7,"pressure":0.0,"pressed":true,"script":null) +] +} +look_right={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) +] +} +look_left={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) +] +} +look_up={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) +] +} +look_down={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) ] }