refacto: moved systems from player controller physics process to their own signal based systems
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=26 format=3 uid="uid://bei4nhkf8lwdo"]
|
[gd_scene load_steps=28 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="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"]
|
||||||
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/walk_mode/base_mode.tres" id="3_cresl"]
|
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/walk_mode/base_mode.tres" id="3_cresl"]
|
||||||
@ -14,12 +14,14 @@
|
|||||||
[ext_resource type="Resource" uid="uid://7wm8ywvujwf" path="res://systems/inputs/walk_mode/aim_cancel.tres" id="9_5p2qc"]
|
[ext_resource type="Resource" uid="uid://7wm8ywvujwf" path="res://systems/inputs/walk_mode/aim_cancel.tres" id="9_5p2qc"]
|
||||||
[ext_resource type="Script" uid="uid://bt0xv2q8iv1vn" path="res://player_controller/Scripts/Gravity.cs" id="9_lsueh"]
|
[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://dwoppk8j5fxeg" path="res://player_controller/Scripts/DashSystem.cs" id="9_qu4wy"]
|
||||||
|
[ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://systems/inputs/walk_mode/jump.tres" id="10_4u7i3"]
|
||||||
[ext_resource type="Script" uid="uid://g8idirw62qe0" path="res://player_controller/Scripts/Bobbing.cs" id="10_7wk1w"]
|
[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="PackedScene" uid="uid://0ysqmqphq6mq" path="res://systems/head/head_system.tscn" id="11_rxwoh"]
|
[ext_resource type="PackedScene" uid="uid://0ysqmqphq6mq" path="res://systems/head/head_system.tscn" id="11_rxwoh"]
|
||||||
[ext_resource type="Script" uid="uid://b6k73aj5povgv" path="res://player_controller/Scripts/FieldOfView.cs" id="12_m2mxi"]
|
[ext_resource type="Script" uid="uid://b6k73aj5povgv" path="res://player_controller/Scripts/FieldOfView.cs" id="12_m2mxi"]
|
||||||
[ext_resource type="Script" uid="uid://b5nk6ntlps3x0" path="res://systems/inputs/input_system.gd" id="16_v31n3"]
|
[ext_resource type="Script" uid="uid://b5nk6ntlps3x0" path="res://systems/inputs/input_system.gd" id="16_v31n3"]
|
||||||
[ext_resource type="Resource" uid="uid://htqvokm8mufq" path="res://systems/inputs/walk_mode/move.tres" id="17_h6vvl"]
|
[ext_resource type="Resource" uid="uid://htqvokm8mufq" path="res://systems/inputs/walk_mode/move.tres" id="17_h6vvl"]
|
||||||
|
[ext_resource type="Script" uid="uid://dyy5njw6pxoh4" path="res://systems/move/MoveSystem.cs" id="20_rxwoh"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dbe5f0p6lvqtr" path="res://systems/tween_queue/tween_queue_system.tscn" id="22_rpwev"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
|
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
|
||||||
|
|
||||||
@ -33,8 +35,6 @@
|
|||||||
|
|
||||||
[node name="Player" type="CharacterBody3D"]
|
[node name="Player" type="CharacterBody3D"]
|
||||||
script = ExtResource("1_poq2x")
|
script = ExtResource("1_poq2x")
|
||||||
WalkSpeed = 10.0
|
|
||||||
SprintSpeed = 15.0
|
|
||||||
|
|
||||||
[node name="InputController" type="Node3D" parent="."]
|
[node name="InputController" type="Node3D" parent="."]
|
||||||
script = ExtResource("16_v31n3")
|
script = ExtResource("16_v31n3")
|
||||||
@ -45,6 +45,7 @@ rotate_floorplane = ExtResource("5_4u7i3")
|
|||||||
aim_pressed = ExtResource("7_cresl")
|
aim_pressed = ExtResource("7_cresl")
|
||||||
aim_released = ExtResource("8_lhb11")
|
aim_released = ExtResource("8_lhb11")
|
||||||
aim_canceled = ExtResource("9_5p2qc")
|
aim_canceled = ExtResource("9_5p2qc")
|
||||||
|
jump = ExtResource("10_4u7i3")
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
@ -64,6 +65,9 @@ script = ExtResource("5_umw0l")
|
|||||||
[node name="Stamina" type="Node3D" parent="."]
|
[node name="Stamina" type="Node3D" parent="."]
|
||||||
script = ExtResource("6_lxtc4")
|
script = ExtResource("6_lxtc4")
|
||||||
|
|
||||||
|
[node name="StairsSystem" type="Node3D" parent="."]
|
||||||
|
script = ExtResource("7_bmt5a")
|
||||||
|
|
||||||
[node name="StairsAheadRayCast3D" type="RayCast3D" parent="."]
|
[node name="StairsAheadRayCast3D" type="RayCast3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -0.828)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -0.828)
|
||||||
target_position = Vector3(0, -0.55, 0)
|
target_position = Vector3(0, -0.55, 0)
|
||||||
@ -94,19 +98,9 @@ surface_material_override/0 = SubResource("StandardMaterial3D_v31n3")
|
|||||||
MantleEndLocationDistanceFromWall = 1.0
|
MantleEndLocationDistanceFromWall = 1.0
|
||||||
MantleHeightCastStart = 2.0
|
MantleHeightCastStart = 2.0
|
||||||
|
|
||||||
[node name="StairsSystem" type="Node3D" parent="."]
|
|
||||||
script = ExtResource("7_bmt5a")
|
|
||||||
|
|
||||||
[node name="Gravity" type="Node3D" parent="."]
|
|
||||||
script = ExtResource("9_lsueh")
|
|
||||||
AdditionalGravityPower = 5.0
|
|
||||||
|
|
||||||
[node name="Bobbing" type="Node3D" parent="."]
|
[node name="Bobbing" type="Node3D" parent="."]
|
||||||
script = ExtResource("10_7wk1w")
|
script = ExtResource("10_7wk1w")
|
||||||
|
|
||||||
[node name="Mouse" type="Node3D" parent="."]
|
|
||||||
script = ExtResource("11_huhen")
|
|
||||||
|
|
||||||
[node name="FieldOfView" type="Node3D" parent="."]
|
[node name="FieldOfView" type="Node3D" parent="."]
|
||||||
script = ExtResource("12_m2mxi")
|
script = ExtResource("12_m2mxi")
|
||||||
|
|
||||||
@ -128,9 +122,22 @@ target_position = Vector3(0, 1, 0)
|
|||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.296, 1.4, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.296, 1.4, 0)
|
||||||
target_position = Vector3(0, 1, 0)
|
target_position = Vector3(0, 1, 0)
|
||||||
|
|
||||||
|
[node name="MoveSystem" type="Node3D" parent="."]
|
||||||
|
script = ExtResource("20_rxwoh")
|
||||||
|
WalkSpeed = 10.0
|
||||||
|
SprintSpeed = 15.0
|
||||||
|
|
||||||
|
[node name="Gravity" type="Node3D" parent="."]
|
||||||
|
script = ExtResource("9_lsueh")
|
||||||
|
Weight = 10.0
|
||||||
|
StartVelocity = 4.0
|
||||||
|
|
||||||
|
[node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")]
|
||||||
|
|
||||||
[connection signal="input_aim_canceled" from="InputController" to="." method="OnInputAimCanceled"]
|
[connection signal="input_aim_canceled" from="InputController" to="." method="OnInputAimCanceled"]
|
||||||
[connection signal="input_aim_pressed" from="InputController" to="." method="OnInputAimPressed"]
|
[connection signal="input_aim_pressed" from="InputController" to="." method="OnInputAimPressed"]
|
||||||
[connection signal="input_aim_released" from="InputController" to="." method="OnInputAimReleased"]
|
[connection signal="input_aim_released" from="InputController" to="." method="OnInputAimReleased"]
|
||||||
|
[connection signal="input_jump" from="InputController" to="." method="OnInputJumpPressed"]
|
||||||
[connection signal="input_move" from="InputController" to="." method="OnInputMove"]
|
[connection signal="input_move" from="InputController" to="." method="OnInputMove"]
|
||||||
[connection signal="input_rotate_floorplane" from="InputController" to="." method="OnInputRotateFloorplane"]
|
[connection signal="input_rotate_floorplane" from="InputController" to="." method="OnInputRotateFloorplane"]
|
||||||
[connection signal="input_rotate_y" from="InputController" to="." method="OnInputRotateY"]
|
[connection signal="input_rotate_y" from="InputController" to="." method="OnInputRotateY"]
|
||||||
|
@ -18,6 +18,6 @@ public partial class Gravity: Node3D
|
|||||||
_gravity = gravitySetting;
|
_gravity = gravitySetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CalculateJumpForce() => Weight * (_gravity * (StartVelocity / AdditionalGravityPower));
|
public float CalculateJumpForce() => _gravity * (StartVelocity / AdditionalGravityPower);
|
||||||
public float CalculateGravityForce() => _gravity * Weight / 30.0f;
|
public float CalculateGravityForce() => _gravity * Weight;
|
||||||
}
|
}
|
||||||
|
@ -18,37 +18,15 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
public CapsuleCollider CapsuleCollider;
|
public CapsuleCollider CapsuleCollider;
|
||||||
public Gravity Gravity;
|
public Gravity Gravity;
|
||||||
public HealthSystem HealthSystem;
|
public HealthSystem HealthSystem;
|
||||||
|
public MoveSystem MoveSystem;
|
||||||
|
public TweenQueueSystem TweenQueueSystem;
|
||||||
|
|
||||||
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
|
||||||
public float WalkSpeed { get; set; } = 5.0f;
|
|
||||||
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
|
||||||
public float SprintSpeed { get; set; } = 7.2f;
|
|
||||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
|
||||||
public float CrouchSpeed { get; set; } = 2.5f;
|
|
||||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
|
||||||
public float CrouchTransitionSpeed { get; set; } = 20.0f;
|
|
||||||
|
|
||||||
[Export(PropertyHint.Range, "0,5,0.1,or_greater")]
|
|
||||||
public float DoubleJumpSpeedFactor { get; set; } = 2f;
|
|
||||||
|
|
||||||
private bool _canDoubleJump = true;
|
|
||||||
private bool _movementEnabled = true;
|
private bool _movementEnabled = true;
|
||||||
|
|
||||||
private bool _isTweening = false;
|
|
||||||
private record TweenInputs(Vector3 Location, float Duration);
|
|
||||||
|
|
||||||
private Queue<TweenInputs> _tweenInputs = new Queue<TweenInputs>();
|
|
||||||
|
|
||||||
private bool _shouldMantle = false;
|
private bool _shouldMantle = false;
|
||||||
private Vector3 _dashLocation = Vector3.Zero;
|
private Vector3 _dashLocation = Vector3.Zero;
|
||||||
private Vector3 _mantleLocation = Vector3.Zero;
|
private Vector3 _mantleLocation = Vector3.Zero;
|
||||||
|
|
||||||
private float _currentSpeed;
|
|
||||||
|
|
||||||
private const float DecelerationSpeedFactorFloor = 15.0f;
|
|
||||||
private const float DecelerationSpeedFactorAir = 7.0f;
|
|
||||||
|
|
||||||
private float _lastFrameWasOnFloor = -Mathf.Inf;
|
private float _lastFrameWasOnFloor = -Mathf.Inf;
|
||||||
|
|
||||||
private const int NumOfHeadCollisionDetectors = 4;
|
private const int NumOfHeadCollisionDetectors = 4;
|
||||||
@ -91,12 +69,18 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
GD.Print("Aim canceled");
|
GD.Print("Aim canceled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnInputJumpPressed()
|
||||||
|
{
|
||||||
|
bool doesCapsuleHaveCrouchingHeight = CapsuleCollider.IsCrouchingHeight();
|
||||||
|
bool isPlayerDead = HealthSystem.IsDead();
|
||||||
|
|
||||||
|
if (!doesCapsuleHaveCrouchingHeight && !isPlayerDead)
|
||||||
|
MoveSystem.Jump(IsOnFloor());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_currentSpeed = WalkSpeed;
|
|
||||||
|
|
||||||
HeadSystem = GetNode<HeadSystem>("HeadSystem");
|
HeadSystem = GetNode<HeadSystem>("HeadSystem");
|
||||||
HeadSystem.Init();
|
HeadSystem.Init();
|
||||||
|
|
||||||
@ -137,23 +121,31 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
FieldOfView = GetNode<FieldOfView>("FieldOfView");
|
FieldOfView = GetNode<FieldOfView>("FieldOfView");
|
||||||
FieldOfView.Init(camera);
|
FieldOfView.Init(camera);
|
||||||
|
|
||||||
Stamina = GetNode<Stamina>("Stamina");
|
|
||||||
Stamina.SetSpeeds(WalkSpeed, SprintSpeed);
|
|
||||||
|
|
||||||
StairsSystem = GetNode<StairsSystem>("StairsSystem");
|
|
||||||
StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth);
|
|
||||||
|
|
||||||
MantleSystem = GetNode<MantleSystem>("MantleSystem");
|
|
||||||
MantleSystem.Init(HeadSystem);
|
|
||||||
|
|
||||||
DashSystem = GetNode<DashSystem>("DashSystem");
|
|
||||||
DashSystem.Init(HeadSystem, camera);
|
|
||||||
|
|
||||||
CapsuleCollider = GetNode<CapsuleCollider>("CapsuleCollider");
|
CapsuleCollider = GetNode<CapsuleCollider>("CapsuleCollider");
|
||||||
|
|
||||||
Gravity = GetNode<Gravity>("Gravity");
|
Gravity = GetNode<Gravity>("Gravity");
|
||||||
Gravity.Init(gravitySetting);
|
Gravity.Init(gravitySetting);
|
||||||
|
|
||||||
|
MantleSystem = GetNode<MantleSystem>("MantleSystem");
|
||||||
|
MantleSystem.Init(HeadSystem);
|
||||||
|
|
||||||
|
TweenQueueSystem = GetNode<TweenQueueSystem>("TweenQueueSystem");
|
||||||
|
TweenQueueSystem.Init(this);
|
||||||
|
|
||||||
|
MoveSystem = GetNode<MoveSystem>("MoveSystem");
|
||||||
|
var moveSystemParams = new MoveSystem.MoveSystemParameters(this, Gravity, MantleSystem, TweenQueueSystem,
|
||||||
|
HeadSystem, CapsuleCollider);
|
||||||
|
MoveSystem.Init(moveSystemParams);
|
||||||
|
|
||||||
|
Stamina = GetNode<Stamina>("Stamina");
|
||||||
|
Stamina.SetSpeeds(MoveSystem.WalkSpeed, MoveSystem.SprintSpeed);
|
||||||
|
|
||||||
|
StairsSystem = GetNode<StairsSystem>("StairsSystem");
|
||||||
|
StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth);
|
||||||
|
|
||||||
|
DashSystem = GetNode<DashSystem>("DashSystem");
|
||||||
|
DashSystem.Init(HeadSystem, camera);
|
||||||
|
|
||||||
HealthSystem = GetNode<HealthSystem>("HealthSystem");
|
HealthSystem = GetNode<HealthSystem>("HealthSystem");
|
||||||
|
|
||||||
HealthSystem.HealthSystemInitParams healthSystemParams = new HealthSystem.HealthSystemInitParams()
|
HealthSystem.HealthSystemInitParams healthSystemParams = new HealthSystem.HealthSystemInitParams()
|
||||||
@ -170,50 +162,9 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
HealthSystem.Init(healthSystemParams);
|
HealthSystem.Init(healthSystemParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisableMovement()
|
|
||||||
{
|
|
||||||
_movementEnabled = false;
|
|
||||||
}
|
|
||||||
public void EnableMovement()
|
|
||||||
{
|
|
||||||
_movementEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndTween()
|
|
||||||
{
|
|
||||||
EnableMovement();
|
|
||||||
_isTweening = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TweenToLocation(TweenInputs inputs)
|
|
||||||
{
|
|
||||||
var (location, duration) = inputs;
|
|
||||||
|
|
||||||
var tween = GetTree().CreateTween();
|
|
||||||
var callback = new Callable(this, MethodName.EndTween);
|
|
||||||
|
|
||||||
tween.TweenProperty(this, "position", location, duration);
|
|
||||||
tween.TweenCallback(callback);
|
|
||||||
|
|
||||||
DisableMovement();
|
|
||||||
_isTweening = true;
|
|
||||||
tween.Play();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void QueueTween(TweenInputs inputs)
|
|
||||||
{
|
|
||||||
_tweenInputs.Enqueue(inputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void QueueTween(Vector3 location, float duration)
|
|
||||||
{
|
|
||||||
QueueTween(new TweenInputs(location, duration));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _PhysicsProcess(double delta)
|
public override void _PhysicsProcess(double delta)
|
||||||
{
|
{
|
||||||
if (_tweenInputs.Count > 0 && !_isTweening)
|
TweenQueueSystem.ProcessTweens();
|
||||||
TweenToLocation(_tweenInputs.Dequeue());
|
|
||||||
|
|
||||||
if (Input.IsActionPressed("aim_dash"))
|
if (Input.IsActionPressed("aim_dash"))
|
||||||
{
|
{
|
||||||
@ -223,154 +174,20 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
if (Input.IsActionJustReleased("aim_dash"))
|
if (Input.IsActionJustReleased("aim_dash"))
|
||||||
{
|
{
|
||||||
DashSystem.Dash();
|
DashSystem.Dash();
|
||||||
QueueTween(_dashLocation, 0.1f);
|
TweenQueueSystem.QueueTween(_dashLocation, 0.1f);
|
||||||
if (_shouldMantle)
|
if (_shouldMantle)
|
||||||
{
|
{
|
||||||
QueueTween(_mantleLocation, 0.1f);
|
TweenQueueSystem.QueueTween(_mantleLocation, 0.1f);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var mantleLocationResult = MantleSystem.FindMantleInFrontOfPlayer();
|
|
||||||
if (isOnFloorCustom())
|
|
||||||
{
|
|
||||||
_lastFrameWasOnFloor = Engine.GetPhysicsFrames();
|
|
||||||
_canDoubleJump = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adding the gravity
|
|
||||||
if (!isOnFloorCustom())
|
|
||||||
{
|
|
||||||
Velocity = new Vector3(
|
|
||||||
x: Velocity.X,
|
|
||||||
y: Velocity.Y - (Gravity.CalculateGravityForce() * (float)delta),
|
|
||||||
z: Velocity.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doesCapsuleHaveCrouchingHeight = CapsuleCollider.IsCrouchingHeight();
|
|
||||||
|
|
||||||
bool isPlayerDead = HealthSystem.IsDead();
|
|
||||||
|
|
||||||
// Handle Jump input
|
|
||||||
if (Input.IsActionJustPressed("jump")
|
|
||||||
&& !doesCapsuleHaveCrouchingHeight
|
|
||||||
&& !isPlayerDead)
|
|
||||||
{
|
|
||||||
if (mantleLocationResult.IsSome(out var mantleLocation))
|
|
||||||
{
|
|
||||||
var duration = 0.1f * mantleLocation.DistanceTo(Position);
|
|
||||||
QueueTween(mantleLocation, duration);
|
|
||||||
}
|
|
||||||
else if (isOnFloorCustom())
|
|
||||||
{
|
|
||||||
Velocity = new Vector3(
|
|
||||||
x: Velocity.X,
|
|
||||||
y: Gravity.CalculateJumpForce() * (float)delta,
|
|
||||||
z: Velocity.Z);
|
|
||||||
}
|
|
||||||
else if (!isOnFloorCustom()
|
|
||||||
&& _canDoubleJump)
|
|
||||||
{
|
|
||||||
_canDoubleJump = false;
|
|
||||||
Velocity = new Vector3(
|
|
||||||
x: Velocity.X,
|
|
||||||
y: Gravity.CalculateJumpForce() * (float)delta * DoubleJumpSpeedFactor,
|
|
||||||
z: Velocity.Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHeadTouchingCeiling = IsHeadTouchingCeiling();
|
|
||||||
bool doesCapsuleHaveDefaultHeight = CapsuleCollider.IsDefaultHeight();
|
|
||||||
|
|
||||||
// The code below is required to quickly adjust player's position on Y-axis when there's a ceiling on the
|
|
||||||
// trajectory of player's jump and player is standing
|
|
||||||
if (isHeadTouchingCeiling && doesCapsuleHaveDefaultHeight)
|
|
||||||
{
|
|
||||||
Velocity = new Vector3(
|
|
||||||
x: Velocity.X,
|
|
||||||
y: Velocity.Y - 2.0f,
|
|
||||||
z: Velocity.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isPlayerDead)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Used both for detecting the moment when we enter into crouching mode and the moment when we're already
|
|
||||||
// in the crouching mode
|
|
||||||
if (Input.IsActionPressed("crouch") ||
|
|
||||||
(doesCapsuleHaveCrouchingHeight && isHeadTouchingCeiling))
|
|
||||||
{
|
|
||||||
CapsuleCollider.Crouch((float)delta, CrouchTransitionSpeed);
|
|
||||||
_currentSpeed = CrouchSpeed;
|
|
||||||
}
|
|
||||||
// Used both for the moment when we exit the crouching mode and for the moment when we just walk
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CapsuleCollider.UndoCrouching((float)delta, CrouchTransitionSpeed);
|
|
||||||
_currentSpeed = WalkSpeed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each component of the boolean statement for sprinting is required
|
var isPlayerDead = HealthSystem.IsDead();
|
||||||
if (Input.IsActionPressed("sprint") && !isHeadTouchingCeiling &&
|
var isHeadTouchingCeiling = IsHeadTouchingCeiling();
|
||||||
!doesCapsuleHaveCrouchingHeight && !isPlayerDead)
|
|
||||||
{
|
MoveSystem.MoveAround(delta, _inputMove, isOnFloorCustom(), isPlayerDead, isHeadTouchingCeiling);
|
||||||
_currentSpeed = SprintSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
|
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
|
||||||
HeadSystem.LookAround(inputLookDir);
|
HeadSystem.LookAround(inputLookDir);
|
||||||
|
|
||||||
// Basis is a 3x4 matrix. It contains information about scaling and rotation of head.
|
|
||||||
// By multiplying our Vector3 by this matrix we're doing multiple things:
|
|
||||||
// a) We start to operate in global space;
|
|
||||||
// b) We're applying to Vector3 the current rotation of "head" object;
|
|
||||||
// c) We're applying to Vector3 the current scaling of "head" object;
|
|
||||||
Vector3 direction = HeadSystem.Transform.Basis * _inputMove;
|
|
||||||
|
|
||||||
if (isPlayerDead)
|
|
||||||
{
|
|
||||||
direction = Vector3.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isOnFloorCustom())
|
|
||||||
{
|
|
||||||
// Set velocity based on input direction when on the floor
|
|
||||||
if (direction.Length() > 0)
|
|
||||||
{
|
|
||||||
float availableSpeed = Stamina.AccountStamina(delta, _currentSpeed);
|
|
||||||
|
|
||||||
float newX = direction.X * availableSpeed;
|
|
||||||
float newZ = direction.Z * availableSpeed;
|
|
||||||
|
|
||||||
Velocity = new Vector3(newX, Velocity.Y, newZ);
|
|
||||||
}
|
|
||||||
// If there is no input, smoothly decelerate the character on the floor
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float xDeceleration = Mathf.Lerp(Velocity.X, direction.X * _currentSpeed,
|
|
||||||
(float)delta * DecelerationSpeedFactorFloor);
|
|
||||||
float zDeceleration = Mathf.Lerp(Velocity.Z, direction.Z * _currentSpeed,
|
|
||||||
(float)delta * DecelerationSpeedFactorFloor);
|
|
||||||
|
|
||||||
Velocity = new Vector3(xDeceleration, Velocity.Y, zDeceleration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float xDeceleration = Mathf.Lerp(Velocity.X, direction.X * _currentSpeed,
|
|
||||||
(float)delta * DecelerationSpeedFactorAir);
|
|
||||||
float zDeceleration = Mathf.Lerp(Velocity.Z, direction.Z * _currentSpeed,
|
|
||||||
(float)delta * DecelerationSpeedFactorAir);
|
|
||||||
|
|
||||||
Velocity = new Vector3(xDeceleration, Velocity.Y, zDeceleration);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPlayerDead)
|
|
||||||
{
|
|
||||||
MoveAndSlide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams
|
Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams
|
||||||
{
|
{
|
||||||
Delta = (float)delta,
|
Delta = (float)delta,
|
||||||
@ -384,7 +201,7 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
{
|
{
|
||||||
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(),
|
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(),
|
||||||
Delta = (float)delta,
|
Delta = (float)delta,
|
||||||
SprintSpeed = SprintSpeed,
|
SprintSpeed = MoveSystem.SprintSpeed,
|
||||||
Velocity = Velocity
|
Velocity = Velocity
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -394,7 +211,7 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
{
|
{
|
||||||
IsOnFloorCustom = isOnFloorCustom(),
|
IsOnFloorCustom = isOnFloorCustom(),
|
||||||
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(),
|
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(),
|
||||||
CurrentSpeedGreaterThanWalkSpeed = _currentSpeed > WalkSpeed,
|
CurrentSpeedGreaterThanWalkSpeed = MoveSystem._currentSpeed > MoveSystem.WalkSpeed,
|
||||||
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(),
|
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(),
|
||||||
Delta = (float)delta,
|
Delta = (float)delta,
|
||||||
FloorMaxAngle = FloorMaxAngle,
|
FloorMaxAngle = FloorMaxAngle,
|
||||||
@ -443,7 +260,7 @@ public partial class PlayerController : CharacterBody3D
|
|||||||
StairsSystem.SlideCameraParams slideCameraParams = new StairsSystem.SlideCameraParams
|
StairsSystem.SlideCameraParams slideCameraParams = new StairsSystem.SlideCameraParams
|
||||||
{
|
{
|
||||||
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(),
|
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(),
|
||||||
CurrentSpeedGreaterThanWalkSpeed = _currentSpeed > WalkSpeed,
|
CurrentSpeedGreaterThanWalkSpeed = MoveSystem._currentSpeed > MoveSystem.WalkSpeed,
|
||||||
BetweenCrouchingAndNormalHeight = CapsuleCollider.IsBetweenCrouchingAndNormalHeight(),
|
BetweenCrouchingAndNormalHeight = CapsuleCollider.IsBetweenCrouchingAndNormalHeight(),
|
||||||
Delta = (float)delta
|
Delta = (float)delta
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@ extends Node3D
|
|||||||
@export var aim_pressed:GUIDEAction
|
@export var aim_pressed:GUIDEAction
|
||||||
@export var aim_released:GUIDEAction
|
@export var aim_released:GUIDEAction
|
||||||
@export var aim_canceled:GUIDEAction
|
@export var aim_canceled:GUIDEAction
|
||||||
|
@export var jump:GUIDEAction
|
||||||
|
|
||||||
signal input_move(value: Vector3)
|
signal input_move(value: Vector3)
|
||||||
signal input_rotate_y(value: float)
|
signal input_rotate_y(value: float)
|
||||||
@ -20,6 +21,7 @@ signal input_rotate_floorplane(value: float)
|
|||||||
signal input_aim_pressed
|
signal input_aim_pressed
|
||||||
signal input_aim_released
|
signal input_aim_released
|
||||||
signal input_aim_canceled
|
signal input_aim_canceled
|
||||||
|
signal input_jump
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
GUIDE.enable_mapping_context(base_mode)
|
GUIDE.enable_mapping_context(base_mode)
|
||||||
@ -27,8 +29,12 @@ func _ready() -> void:
|
|||||||
aim_pressed.triggered.connect(on_input_aim_pressed)
|
aim_pressed.triggered.connect(on_input_aim_pressed)
|
||||||
aim_released.triggered.connect(on_input_aim_released)
|
aim_released.triggered.connect(on_input_aim_released)
|
||||||
aim_canceled.triggered.connect(on_input_aim_canceled)
|
aim_canceled.triggered.connect(on_input_aim_canceled)
|
||||||
|
jump.triggered.connect(on_input_jump)
|
||||||
|
|
||||||
|
|
||||||
|
func on_input_jump():
|
||||||
|
input_jump.emit()
|
||||||
|
|
||||||
func on_input_aim_pressed():
|
func on_input_aim_pressed():
|
||||||
input_aim_pressed.emit()
|
input_aim_pressed.emit()
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=53 format=3 uid="uid://bl5crtu1gkrtr"]
|
[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=58 format=3 uid="uid://bl5crtu1gkrtr"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cpplm41b5bt6m" path="res://addons/guide/guide_action_mapping.gd" id="1_0pi3k"]
|
[ext_resource type="Script" uid="uid://cpplm41b5bt6m" path="res://addons/guide/guide_action_mapping.gd" id="1_0pi3k"]
|
||||||
[ext_resource type="Script" uid="uid://dsa1dnifd6w32" path="res://addons/guide/guide_mapping_context.gd" id="2_ho3ad"]
|
[ext_resource type="Script" uid="uid://dsa1dnifd6w32" path="res://addons/guide/guide_mapping_context.gd" id="2_ho3ad"]
|
||||||
@ -22,6 +22,7 @@
|
|||||||
[ext_resource type="Script" uid="uid://rvttn472ix6v" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="19_2murt"]
|
[ext_resource type="Script" uid="uid://rvttn472ix6v" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="19_2murt"]
|
||||||
[ext_resource type="Script" uid="uid://brsxcrai2te83" path="res://addons/guide/triggers/guide_trigger_chorded_action.gd" id="20_xcfo4"]
|
[ext_resource type="Script" uid="uid://brsxcrai2te83" path="res://addons/guide/triggers/guide_trigger_chorded_action.gd" id="20_xcfo4"]
|
||||||
[ext_resource type="Script" uid="uid://b52rqq28tuqpg" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="21_k8ji4"]
|
[ext_resource type="Script" uid="uid://b52rqq28tuqpg" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="21_k8ji4"]
|
||||||
|
[ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://systems/inputs/walk_mode/jump.tres" id="22_ufouq"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_vkvga"]
|
[sub_resource type="Resource" id="Resource_vkvga"]
|
||||||
script = ExtResource("4_oapce")
|
script = ExtResource("4_oapce")
|
||||||
@ -52,6 +53,7 @@ triggers = Array[ExtResource("8_nf3uo")]([])
|
|||||||
script = ExtResource("1_0pi3k")
|
script = ExtResource("1_0pi3k")
|
||||||
action = ExtResource("2_p4e1v")
|
action = ExtResource("2_p4e1v")
|
||||||
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_1igva")])
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_1igva")])
|
||||||
|
metadata/_guide_input_mappings_collapsed = false
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_05q5j"]
|
[sub_resource type="Resource" id="Resource_05q5j"]
|
||||||
script = ExtResource("10_500v3")
|
script = ExtResource("10_500v3")
|
||||||
@ -88,6 +90,7 @@ triggers = Array[ExtResource("8_nf3uo")]([])
|
|||||||
script = ExtResource("1_0pi3k")
|
script = ExtResource("1_0pi3k")
|
||||||
action = ExtResource("9_paxxe")
|
action = ExtResource("9_paxxe")
|
||||||
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_dew8i")])
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_dew8i")])
|
||||||
|
metadata/_guide_input_mappings_collapsed = true
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_pf0ii"]
|
[sub_resource type="Resource" id="Resource_pf0ii"]
|
||||||
script = ExtResource("10_500v3")
|
script = ExtResource("10_500v3")
|
||||||
@ -124,8 +127,9 @@ triggers = Array[ExtResource("8_nf3uo")]([])
|
|||||||
script = ExtResource("1_0pi3k")
|
script = ExtResource("1_0pi3k")
|
||||||
action = ExtResource("13_3y0c4")
|
action = ExtResource("13_3y0c4")
|
||||||
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_qu2wi")])
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_qu2wi")])
|
||||||
|
metadata/_guide_input_mappings_collapsed = true
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_lg6ir"]
|
[sub_resource type="Resource" id="Resource_ufouq"]
|
||||||
script = ExtResource("10_500v3")
|
script = ExtResource("10_500v3")
|
||||||
axis = 4
|
axis = 4
|
||||||
joy_index = -1
|
joy_index = -1
|
||||||
@ -140,7 +144,7 @@ override_action_settings = false
|
|||||||
is_remappable = false
|
is_remappable = false
|
||||||
display_name = ""
|
display_name = ""
|
||||||
display_category = ""
|
display_category = ""
|
||||||
input = SubResource("Resource_lg6ir")
|
input = SubResource("Resource_ufouq")
|
||||||
modifiers = Array[ExtResource("5_j3mg7")]([])
|
modifiers = Array[ExtResource("5_j3mg7")]([])
|
||||||
triggers = Array[ExtResource("8_nf3uo")]([SubResource("Resource_n42ky")])
|
triggers = Array[ExtResource("8_nf3uo")]([SubResource("Resource_n42ky")])
|
||||||
|
|
||||||
@ -148,6 +152,7 @@ triggers = Array[ExtResource("8_nf3uo")]([SubResource("Resource_n42ky")])
|
|||||||
script = ExtResource("1_0pi3k")
|
script = ExtResource("1_0pi3k")
|
||||||
action = ExtResource("14_bi271")
|
action = ExtResource("14_bi271")
|
||||||
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_qbthx")])
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_qbthx")])
|
||||||
|
metadata/_guide_input_mappings_collapsed = false
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_cqc4k"]
|
[sub_resource type="Resource" id="Resource_cqc4k"]
|
||||||
script = ExtResource("10_500v3")
|
script = ExtResource("10_500v3")
|
||||||
@ -172,6 +177,7 @@ triggers = Array[ExtResource("8_nf3uo")]([SubResource("Resource_vanwy")])
|
|||||||
script = ExtResource("1_0pi3k")
|
script = ExtResource("1_0pi3k")
|
||||||
action = ExtResource("16_34gm1")
|
action = ExtResource("16_34gm1")
|
||||||
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_bkx7d")])
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_bkx7d")])
|
||||||
|
metadata/_guide_input_mappings_collapsed = true
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_lfx76"]
|
[sub_resource type="Resource" id="Resource_lfx76"]
|
||||||
script = ExtResource("19_2murt")
|
script = ExtResource("19_2murt")
|
||||||
@ -202,8 +208,33 @@ script = ExtResource("1_0pi3k")
|
|||||||
action = ExtResource("18_4dlli")
|
action = ExtResource("18_4dlli")
|
||||||
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_4ee3d")])
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_4ee3d")])
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_oapce"]
|
||||||
|
script = ExtResource("19_2murt")
|
||||||
|
button = 0
|
||||||
|
joy_index = -1
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_j3mg7"]
|
||||||
|
script = ExtResource("21_k8ji4")
|
||||||
|
actuation_threshold = 0.5
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_8w5gu"]
|
||||||
|
script = ExtResource("3_ufouq")
|
||||||
|
override_action_settings = false
|
||||||
|
is_remappable = false
|
||||||
|
display_name = ""
|
||||||
|
display_category = ""
|
||||||
|
input = SubResource("Resource_oapce")
|
||||||
|
modifiers = Array[ExtResource("5_j3mg7")]([])
|
||||||
|
triggers = Array[ExtResource("8_nf3uo")]([SubResource("Resource_j3mg7")])
|
||||||
|
metadata/_guide_triggers_collapsed = false
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_xt1x5"]
|
||||||
|
script = ExtResource("1_0pi3k")
|
||||||
|
action = ExtResource("22_ufouq")
|
||||||
|
input_mappings = Array[ExtResource("3_ufouq")]([SubResource("Resource_8w5gu")])
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("2_ho3ad")
|
script = ExtResource("2_ho3ad")
|
||||||
display_name = ""
|
display_name = ""
|
||||||
mappings = Array[ExtResource("1_0pi3k")]([SubResource("Resource_88x08"), SubResource("Resource_tgr2g"), SubResource("Resource_iarn8"), SubResource("Resource_0hmrk"), SubResource("Resource_iihs4"), SubResource("Resource_0s4kt")])
|
mappings = Array[ExtResource("1_0pi3k")]([SubResource("Resource_88x08"), SubResource("Resource_tgr2g"), SubResource("Resource_iarn8"), SubResource("Resource_0hmrk"), SubResource("Resource_iihs4"), SubResource("Resource_0s4kt"), SubResource("Resource_xt1x5")])
|
||||||
metadata/_custom_type_script = "uid://dsa1dnifd6w32"
|
metadata/_custom_type_script = "uid://dsa1dnifd6w32"
|
||||||
|
14
systems/inputs/walk_mode/jump.tres
Normal file
14
systems/inputs/walk_mode/jump.tres
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bdit2jy5gbpts"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_pxv2l"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_pxv2l")
|
||||||
|
name = &""
|
||||||
|
action_value_type = 0
|
||||||
|
block_lower_priority_actions = true
|
||||||
|
emit_as_godot_actions = false
|
||||||
|
is_remappable = false
|
||||||
|
display_name = ""
|
||||||
|
display_category = ""
|
||||||
|
metadata/_custom_type_script = "uid://cluhc11vixkf1"
|
@ -17,6 +17,8 @@ public partial class MantleSystem: Node3D
|
|||||||
private ShapeCast3D _wallInFrontCast3D;
|
private ShapeCast3D _wallInFrontCast3D;
|
||||||
private ShapeCast3D _mantleCast3D;
|
private ShapeCast3D _mantleCast3D;
|
||||||
private RayCast3D _mantleCheckCast3D;
|
private RayCast3D _mantleCheckCast3D;
|
||||||
|
|
||||||
|
private Option<Vector3> _mantleLocation;
|
||||||
|
|
||||||
public void Init(Node3D head)
|
public void Init(Node3D head)
|
||||||
{
|
{
|
||||||
@ -25,21 +27,29 @@ public partial class MantleSystem: Node3D
|
|||||||
_mantleCast3D = GetNode<ShapeCast3D>("MantleCast3D");
|
_mantleCast3D = GetNode<ShapeCast3D>("MantleCast3D");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Option<Vector3> FindMantleInFrontOfPlayer()
|
public override void _PhysicsProcess(double delta)
|
||||||
{
|
{
|
||||||
|
base._PhysicsProcess(delta);
|
||||||
|
|
||||||
_wallInFrontCast3D.SetRotation(new Vector3(
|
_wallInFrontCast3D.SetRotation(new Vector3(
|
||||||
_wallInFrontCast3D.Rotation.X,
|
_wallInFrontCast3D.Rotation.X,
|
||||||
_head.Rotation.Y,
|
_head.Rotation.Y,
|
||||||
_wallInFrontCast3D.Rotation.Z));
|
_wallInFrontCast3D.Rotation.Z));
|
||||||
|
|
||||||
if (!_wallInFrontCast3D.IsColliding())
|
if (!_wallInFrontCast3D.IsColliding())
|
||||||
{
|
{
|
||||||
return Option<Vector3>.None;
|
_mantleLocation = Option<Vector3>.None;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0);
|
var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0);
|
||||||
var collisionNormal = _wallInFrontCast3D.GetCollisionNormal(0);
|
var collisionNormal = _wallInFrontCast3D.GetCollisionNormal(0);
|
||||||
return FindMantleLocationAtPoint(collisionPoint, collisionNormal);
|
_mantleLocation = FindMantleLocationAtPoint(collisionPoint, collisionNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Option<Vector3> FindMantleInFrontOfPlayer()
|
||||||
|
{
|
||||||
|
return _mantleLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Option<Vector3> FindMantleLocationAtPoint(Vector3 point, Vector3 wallNormal)
|
public Option<Vector3> FindMantleLocationAtPoint(Vector3 point, Vector3 wallNormal)
|
||||||
|
@ -22,7 +22,7 @@ debug_shape_custom_color = Color(1, 0, 0, 1)
|
|||||||
[node name="WallInFrontCast3D" type="ShapeCast3D" parent="."]
|
[node name="WallInFrontCast3D" type="ShapeCast3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
shape = SubResource("CapsuleShape3D_qu4wy")
|
shape = SubResource("CapsuleShape3D_qu4wy")
|
||||||
target_position = Vector3(0, 0, -1.5)
|
target_position = Vector3(0, 0, -2)
|
||||||
max_results = 1
|
max_results = 1
|
||||||
collision_mask = 2
|
collision_mask = 2
|
||||||
debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
|
debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
|
||||||
|
184
systems/move/MoveSystem.cs
Normal file
184
systems/move/MoveSystem.cs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
using Godot;
|
||||||
|
using PolarBears.PlayerControllerAddon;
|
||||||
|
|
||||||
|
public partial class MoveSystem : Node3D
|
||||||
|
{
|
||||||
|
public record MoveSystemParameters(
|
||||||
|
CharacterBody3D Parent,
|
||||||
|
Gravity Gravity,
|
||||||
|
MantleSystem MantleSystem,
|
||||||
|
TweenQueueSystem TweenQueueSystem,
|
||||||
|
HeadSystem HeadSystem,
|
||||||
|
CapsuleCollider CapsuleCollider);
|
||||||
|
|
||||||
|
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
||||||
|
public float WalkSpeed { get; set; } = 5.0f;
|
||||||
|
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
||||||
|
public float SprintSpeed { get; set; } = 7.2f;
|
||||||
|
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||||
|
public float CrouchSpeed { get; set; } = 2.5f;
|
||||||
|
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
||||||
|
|
||||||
|
public float _currentSpeed;
|
||||||
|
private const float DecelerationSpeedFactorFloor = 15.0f;
|
||||||
|
private const float DecelerationSpeedFactorAir = 7.0f;
|
||||||
|
|
||||||
|
public float CrouchTransitionSpeed { get; set; } = 20.0f;
|
||||||
|
[Export(PropertyHint.Range, "0,5,0.1,or_greater")]
|
||||||
|
public float DoubleJumpSpeedFactor { get; set; } = 2f;
|
||||||
|
|
||||||
|
private bool _canDoubleJump = true;
|
||||||
|
private float _lastFrameWasOnFloor = -Mathf.Inf;
|
||||||
|
|
||||||
|
private Gravity _gravity;
|
||||||
|
private CharacterBody3D _parent;
|
||||||
|
private MantleSystem _mantleSystem;
|
||||||
|
private TweenQueueSystem _tweenQueueSystem;
|
||||||
|
private CapsuleCollider _capsuleCollider;
|
||||||
|
private HeadSystem _headSystem;
|
||||||
|
public void Init(MoveSystemParameters parameters)
|
||||||
|
{
|
||||||
|
_parent = parameters.Parent;
|
||||||
|
_gravity = parameters.Gravity;
|
||||||
|
_mantleSystem = parameters.MantleSystem;
|
||||||
|
_tweenQueueSystem = parameters.TweenQueueSystem;
|
||||||
|
_capsuleCollider = parameters.CapsuleCollider;
|
||||||
|
_headSystem = parameters.HeadSystem;
|
||||||
|
|
||||||
|
_currentSpeed = WalkSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveAround(double delta, Vector3 movementDirection, bool isOnFloor, bool isDead, bool isHeadTouchingCeiling)
|
||||||
|
{
|
||||||
|
var doesCapsuleHaveCrouchingHeight = _capsuleCollider.IsCrouchingHeight();
|
||||||
|
var doesCapsuleHaveDefaultHeight = _capsuleCollider.IsDefaultHeight();
|
||||||
|
|
||||||
|
// Adding the gravity
|
||||||
|
if (!isOnFloor)
|
||||||
|
{
|
||||||
|
_parent.Velocity = new Vector3(
|
||||||
|
x: _parent.Velocity.X,
|
||||||
|
y: _parent.Velocity.Y - (_gravity.CalculateGravityForce() * (float)delta),
|
||||||
|
z: _parent.Velocity.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOnFloor)
|
||||||
|
{
|
||||||
|
_lastFrameWasOnFloor = Engine.GetPhysicsFrames();
|
||||||
|
_canDoubleJump = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The code below is required to quickly adjust player's position on Y-axis when there's a ceiling on the
|
||||||
|
// trajectory of player's jump and player is standing
|
||||||
|
if (isHeadTouchingCeiling && doesCapsuleHaveDefaultHeight)
|
||||||
|
{
|
||||||
|
_parent.Velocity = new Vector3(
|
||||||
|
x: _parent.Velocity.X,
|
||||||
|
y: _parent.Velocity.Y - 2.0f,
|
||||||
|
z: _parent.Velocity.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!isDead)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Used both for detecting the moment when we enter into crouching mode and the moment when we're already
|
||||||
|
// in the crouching mode
|
||||||
|
if (Input.IsActionPressed("crouch") ||
|
||||||
|
(doesCapsuleHaveCrouchingHeight && isHeadTouchingCeiling))
|
||||||
|
{
|
||||||
|
_capsuleCollider.Crouch((float)delta, CrouchTransitionSpeed);
|
||||||
|
_currentSpeed = CrouchSpeed;
|
||||||
|
}
|
||||||
|
// Used both for the moment when we exit the crouching mode and for the moment when we just walk
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_capsuleCollider.UndoCrouching((float)delta, CrouchTransitionSpeed);
|
||||||
|
_currentSpeed = WalkSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each component of the boolean statement for sprinting is required
|
||||||
|
if (Input.IsActionPressed("sprint") && !isHeadTouchingCeiling &&
|
||||||
|
!doesCapsuleHaveCrouchingHeight && !isDead)
|
||||||
|
{
|
||||||
|
_currentSpeed = SprintSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basis is a 3x4 matrix. It contains information about scaling and rotation of head.
|
||||||
|
// By multiplying our Vector3 by this matrix we're doing multiple things:
|
||||||
|
// a) We start to operate in global space;
|
||||||
|
// b) We're applying to Vector3 the current rotation of "head" object;
|
||||||
|
// c) We're applying to Vector3 the current scaling of "head" object;
|
||||||
|
Vector3 direction = _headSystem.Transform.Basis * movementDirection;
|
||||||
|
|
||||||
|
if (isDead)
|
||||||
|
{
|
||||||
|
direction = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isOnFloor)
|
||||||
|
{
|
||||||
|
// Set velocity based on input direction when on the floor
|
||||||
|
if (direction.Length() > 0)
|
||||||
|
{
|
||||||
|
float newX = direction.X * _currentSpeed;
|
||||||
|
float newZ = direction.Z * _currentSpeed;
|
||||||
|
|
||||||
|
_parent.Velocity = new Vector3(newX, _parent.Velocity.Y, newZ);
|
||||||
|
}
|
||||||
|
// If there is no input, smoothly decelerate the character on the floor
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float xDeceleration = Mathf.Lerp(_parent.Velocity.X, direction.X * _currentSpeed,
|
||||||
|
(float)delta * DecelerationSpeedFactorFloor);
|
||||||
|
float zDeceleration = Mathf.Lerp(_parent.Velocity.Z, direction.Z * _currentSpeed,
|
||||||
|
(float)delta * DecelerationSpeedFactorFloor);
|
||||||
|
|
||||||
|
_parent.Velocity = new Vector3(xDeceleration, _parent.Velocity.Y, zDeceleration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float xDeceleration = Mathf.Lerp(_parent.Velocity.X, direction.X * _currentSpeed,
|
||||||
|
(float)delta * DecelerationSpeedFactorAir);
|
||||||
|
float zDeceleration = Mathf.Lerp(_parent.Velocity.Z, direction.Z * _currentSpeed,
|
||||||
|
(float)delta * DecelerationSpeedFactorAir);
|
||||||
|
|
||||||
|
_parent.Velocity = new Vector3(xDeceleration, _parent.Velocity.Y, zDeceleration);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDead)
|
||||||
|
{
|
||||||
|
_parent.MoveAndSlide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Jump(bool isOnFloor)
|
||||||
|
{
|
||||||
|
var mantleLocationResult = _mantleSystem.FindMantleInFrontOfPlayer();
|
||||||
|
if (mantleLocationResult.IsSome(out var mantleLocation))
|
||||||
|
{
|
||||||
|
var duration = 0.1f * mantleLocation.DistanceTo(_parent.Position);
|
||||||
|
_tweenQueueSystem.QueueTween(mantleLocation, duration);
|
||||||
|
}
|
||||||
|
else if (isOnFloor)
|
||||||
|
{
|
||||||
|
_parent.Velocity = new Vector3(
|
||||||
|
x: _parent.Velocity.X,
|
||||||
|
y: _gravity.CalculateJumpForce(),
|
||||||
|
z: _parent.Velocity.Z);
|
||||||
|
}
|
||||||
|
else if (_canDoubleJump)
|
||||||
|
{
|
||||||
|
_canDoubleJump = false;
|
||||||
|
_parent.Velocity = new Vector3(
|
||||||
|
x: _parent.Velocity.X,
|
||||||
|
y: _gravity.CalculateJumpForce() * DoubleJumpSpeedFactor,
|
||||||
|
z: _parent.Velocity.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
1
systems/move/MoveSystem.cs.uid
Normal file
1
systems/move/MoveSystem.cs.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://dyy5njw6pxoh4
|
52
systems/tween_queue/TweenQueueSystem.cs
Normal file
52
systems/tween_queue/TweenQueueSystem.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class TweenQueueSystem : Node3D
|
||||||
|
{
|
||||||
|
public record TweenInputs(Vector3 Location, float Duration);
|
||||||
|
|
||||||
|
private Queue<TweenInputs> _tweenInputs = new Queue<TweenInputs>();
|
||||||
|
private Node3D _tweenObject;
|
||||||
|
private bool _isTweening = false;
|
||||||
|
|
||||||
|
public void Init(Node3D tweenObject)
|
||||||
|
{
|
||||||
|
_tweenObject = tweenObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndTween()
|
||||||
|
{
|
||||||
|
_isTweening = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TweenToLocation(TweenInputs inputs)
|
||||||
|
{
|
||||||
|
var (location, duration) = inputs;
|
||||||
|
|
||||||
|
var tween = GetTree().CreateTween();
|
||||||
|
var callback = new Callable(this, MethodName.EndTween);
|
||||||
|
|
||||||
|
tween.TweenProperty(_tweenObject, "position", location, duration);
|
||||||
|
tween.TweenCallback(callback);
|
||||||
|
|
||||||
|
_isTweening = true;
|
||||||
|
tween.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void QueueTween(TweenInputs inputs)
|
||||||
|
{
|
||||||
|
_tweenInputs.Enqueue(inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void QueueTween(Vector3 location, float duration)
|
||||||
|
{
|
||||||
|
QueueTween(new TweenInputs(location, duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessTweens()
|
||||||
|
{
|
||||||
|
if (_tweenInputs.Count > 0 && !_isTweening)
|
||||||
|
TweenToLocation(_tweenInputs.Dequeue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
systems/tween_queue/TweenQueueSystem.cs.uid
Normal file
1
systems/tween_queue/TweenQueueSystem.cs.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://crm4u4r56hvg7
|
6
systems/tween_queue/tween_queue_system.tscn
Normal file
6
systems/tween_queue/tween_queue_system.tscn
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://dbe5f0p6lvqtr"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://crm4u4r56hvg7" path="res://systems/tween_queue/TweenQueueSystem.cs" id="1_iqosd"]
|
||||||
|
|
||||||
|
[node name="TweenQueueSystem" type="Node3D"]
|
||||||
|
script = ExtResource("1_iqosd")
|
Reference in New Issue
Block a user