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="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="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="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://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="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="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"]
|
||||
|
||||
@ -33,8 +35,6 @@
|
||||
|
||||
[node name="Player" type="CharacterBody3D"]
|
||||
script = ExtResource("1_poq2x")
|
||||
WalkSpeed = 10.0
|
||||
SprintSpeed = 15.0
|
||||
|
||||
[node name="InputController" type="Node3D" parent="."]
|
||||
script = ExtResource("16_v31n3")
|
||||
@ -45,6 +45,7 @@ rotate_floorplane = ExtResource("5_4u7i3")
|
||||
aim_pressed = ExtResource("7_cresl")
|
||||
aim_released = ExtResource("8_lhb11")
|
||||
aim_canceled = ExtResource("9_5p2qc")
|
||||
jump = ExtResource("10_4u7i3")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
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="."]
|
||||
script = ExtResource("6_lxtc4")
|
||||
|
||||
[node name="StairsSystem" type="Node3D" parent="."]
|
||||
script = ExtResource("7_bmt5a")
|
||||
|
||||
[node name="StairsAheadRayCast3D" type="RayCast3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -0.828)
|
||||
target_position = Vector3(0, -0.55, 0)
|
||||
@ -94,19 +98,9 @@ surface_material_override/0 = SubResource("StandardMaterial3D_v31n3")
|
||||
MantleEndLocationDistanceFromWall = 1.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="."]
|
||||
script = ExtResource("10_7wk1w")
|
||||
|
||||
[node name="Mouse" type="Node3D" parent="."]
|
||||
script = ExtResource("11_huhen")
|
||||
|
||||
[node name="FieldOfView" type="Node3D" parent="."]
|
||||
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)
|
||||
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_pressed" from="InputController" to="." method="OnInputAimPressed"]
|
||||
[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_rotate_floorplane" from="InputController" to="." method="OnInputRotateFloorplane"]
|
||||
[connection signal="input_rotate_y" from="InputController" to="." method="OnInputRotateY"]
|
||||
|
@ -18,6 +18,6 @@ public partial class Gravity: Node3D
|
||||
_gravity = gravitySetting;
|
||||
}
|
||||
|
||||
public float CalculateJumpForce() => Weight * (_gravity * (StartVelocity / AdditionalGravityPower));
|
||||
public float CalculateGravityForce() => _gravity * Weight / 30.0f;
|
||||
public float CalculateJumpForce() => _gravity * (StartVelocity / AdditionalGravityPower);
|
||||
public float CalculateGravityForce() => _gravity * Weight;
|
||||
}
|
||||
|
@ -18,37 +18,15 @@ public partial class PlayerController : CharacterBody3D
|
||||
public CapsuleCollider CapsuleCollider;
|
||||
public Gravity Gravity;
|
||||
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 _isTweening = false;
|
||||
private record TweenInputs(Vector3 Location, float Duration);
|
||||
|
||||
private Queue<TweenInputs> _tweenInputs = new Queue<TweenInputs>();
|
||||
|
||||
private bool _shouldMantle = false;
|
||||
private Vector3 _dashLocation = 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 const int NumOfHeadCollisionDetectors = 4;
|
||||
@ -91,12 +69,18 @@ public partial class PlayerController : CharacterBody3D
|
||||
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()
|
||||
{
|
||||
_currentSpeed = WalkSpeed;
|
||||
|
||||
HeadSystem = GetNode<HeadSystem>("HeadSystem");
|
||||
HeadSystem.Init();
|
||||
|
||||
@ -137,23 +121,31 @@ public partial class PlayerController : CharacterBody3D
|
||||
FieldOfView = GetNode<FieldOfView>("FieldOfView");
|
||||
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");
|
||||
|
||||
Gravity = GetNode<Gravity>("Gravity");
|
||||
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.HealthSystemInitParams healthSystemParams = new HealthSystem.HealthSystemInitParams()
|
||||
@ -170,50 +162,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
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)
|
||||
{
|
||||
if (_tweenInputs.Count > 0 && !_isTweening)
|
||||
TweenToLocation(_tweenInputs.Dequeue());
|
||||
TweenQueueSystem.ProcessTweens();
|
||||
|
||||
if (Input.IsActionPressed("aim_dash"))
|
||||
{
|
||||
@ -223,154 +174,20 @@ public partial class PlayerController : CharacterBody3D
|
||||
if (Input.IsActionJustReleased("aim_dash"))
|
||||
{
|
||||
DashSystem.Dash();
|
||||
QueueTween(_dashLocation, 0.1f);
|
||||
TweenQueueSystem.QueueTween(_dashLocation, 0.1f);
|
||||
if (_shouldMantle)
|
||||
{
|
||||
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;
|
||||
TweenQueueSystem.QueueTween(_mantleLocation, 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
// Each component of the boolean statement for sprinting is required
|
||||
if (Input.IsActionPressed("sprint") && !isHeadTouchingCeiling &&
|
||||
!doesCapsuleHaveCrouchingHeight && !isPlayerDead)
|
||||
{
|
||||
_currentSpeed = SprintSpeed;
|
||||
}
|
||||
|
||||
var isPlayerDead = HealthSystem.IsDead();
|
||||
var isHeadTouchingCeiling = IsHeadTouchingCeiling();
|
||||
|
||||
MoveSystem.MoveAround(delta, _inputMove, isOnFloorCustom(), isPlayerDead, isHeadTouchingCeiling);
|
||||
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
|
||||
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
|
||||
{
|
||||
Delta = (float)delta,
|
||||
@ -384,7 +201,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
{
|
||||
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(),
|
||||
Delta = (float)delta,
|
||||
SprintSpeed = SprintSpeed,
|
||||
SprintSpeed = MoveSystem.SprintSpeed,
|
||||
Velocity = Velocity
|
||||
};
|
||||
|
||||
@ -394,7 +211,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
{
|
||||
IsOnFloorCustom = isOnFloorCustom(),
|
||||
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(),
|
||||
CurrentSpeedGreaterThanWalkSpeed = _currentSpeed > WalkSpeed,
|
||||
CurrentSpeedGreaterThanWalkSpeed = MoveSystem._currentSpeed > MoveSystem.WalkSpeed,
|
||||
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(),
|
||||
Delta = (float)delta,
|
||||
FloorMaxAngle = FloorMaxAngle,
|
||||
@ -443,7 +260,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
StairsSystem.SlideCameraParams slideCameraParams = new StairsSystem.SlideCameraParams
|
||||
{
|
||||
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(),
|
||||
CurrentSpeedGreaterThanWalkSpeed = _currentSpeed > WalkSpeed,
|
||||
CurrentSpeedGreaterThanWalkSpeed = MoveSystem._currentSpeed > MoveSystem.WalkSpeed,
|
||||
BetweenCrouchingAndNormalHeight = CapsuleCollider.IsBetweenCrouchingAndNormalHeight(),
|
||||
Delta = (float)delta
|
||||
};
|
||||
|
Reference in New Issue
Block a user