wall run, keyboard controls, mouse sensitivity setting, and more
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using GodotStateCharts;
|
||||
using Movementtests.addons.godot_state_charts.csharp;
|
||||
@@ -14,6 +15,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
MoveCamera,
|
||||
None,
|
||||
}
|
||||
private bool _isUsingGamepad = false;
|
||||
|
||||
// User API to important child nodes.
|
||||
public HeadSystem HeadSystem;
|
||||
@@ -48,6 +50,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
private RayCast3D[] _headCollisionDetectors;
|
||||
|
||||
private Vector3 _inputMove = Vector3.Zero;
|
||||
private Vector3 _inputMoveKeyboard = Vector3.Zero;
|
||||
private float _inputRotateY;
|
||||
private float _inputRotateFloorplane;
|
||||
|
||||
@@ -59,6 +62,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
private Timer _powerCooldownTimer;
|
||||
|
||||
[Export] public Marker3D TutorialWeaponTarget;
|
||||
[Export] public bool TutorialDone { get; set; }
|
||||
|
||||
[ExportCategory("Movement")]
|
||||
[ExportGroup("Ground")]
|
||||
@@ -165,7 +169,6 @@ public partial class PlayerController : CharacterBody3D
|
||||
PlayerUi.SetNumberOfDashesLeft(value);
|
||||
}
|
||||
}
|
||||
public bool TutorialDone { get; set; }
|
||||
|
||||
public AllowedInputs CurrentlyAllowedInputs { get; set; } = AllowedInputs.All;
|
||||
|
||||
@@ -191,9 +194,10 @@ public partial class PlayerController : CharacterBody3D
|
||||
private StateChartState _simpleDash;
|
||||
private StateChartState _poweredDash;
|
||||
private StateChartState _aimedDash;
|
||||
private StateChartState _onWallHugCanceled;
|
||||
private StateChartState _onWall;
|
||||
private StateChartState _onWallHugging;
|
||||
private StateChartState _onWallHanging;
|
||||
private StateChartState _onWallRunning;
|
||||
|
||||
private Transition _onJumpFromWall;
|
||||
private Transition _onMegajumpFromWall;
|
||||
@@ -202,6 +206,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
private float _playerRadius;
|
||||
|
||||
private float _lookSensitivityMultiplier = 1.0f;
|
||||
private float _mouseSensitivityMultiplier = 1.0f;
|
||||
private float _headBobbingMultiplier = 1.0f;
|
||||
private float _fovChangeMultiplier = 1.0f;
|
||||
|
||||
@@ -286,9 +291,10 @@ public partial class PlayerController : CharacterBody3D
|
||||
_megaJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/MegaJump"));
|
||||
_onJumpFromWall = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/OnJump"));
|
||||
_onMegajumpFromWall = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/OnMegajump"));
|
||||
_onWall = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall"));
|
||||
_onWallHugging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hugging"));
|
||||
_onWallHugCanceled = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/HugCanceled"));
|
||||
_onWallHanging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging"));
|
||||
_onWallRunning = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Running"));
|
||||
// State timers
|
||||
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
|
||||
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
|
||||
@@ -329,7 +335,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
Stamina.SetSpeeds(WalkSpeed, WalkSpeed);
|
||||
|
||||
EmpoweredActionsLeft = MaxNumberOfEmpoweredActions;
|
||||
PlaceWeaponForTutorial();
|
||||
|
||||
if (!TutorialDone)
|
||||
PlaceWeaponForTutorial();
|
||||
|
||||
///////////////////////////
|
||||
// Signal setup ///////////
|
||||
@@ -374,9 +382,11 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
_simpleDashCooldownTimer.Timeout += DashCooldownTimeout;
|
||||
|
||||
_onWallHugCanceled.StatePhysicsProcessing += HandleAirborne;
|
||||
_onWall.StateEntered += OnWallStarted;
|
||||
_onWall.StateExited += OnWallStopped;
|
||||
_onWallHugging.StatePhysicsProcessing += HandleWallHugging;
|
||||
_onWallHanging.StatePhysicsProcessing += HandleWallHanging;
|
||||
_onWallRunning.StatePhysicsProcessing += HandleWallRunning;
|
||||
|
||||
_onJumpFromWall.Taken += OnJumpFromWall;
|
||||
_onMegajumpFromWall.Taken += OnMegajumpFromWall;
|
||||
@@ -409,6 +419,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
}
|
||||
|
||||
_lookSensitivityMultiplier = (float) config.GetValue("InputSettings", "LookSensitivity", 1.0f);
|
||||
_mouseSensitivityMultiplier = (float) config.GetValue("InputSettings", "MouseSensitivity", 1.0f);
|
||||
_headBobbingMultiplier = (float) config.GetValue("InputSettings", "HeadBobbingWhileWalking", 1.0f);
|
||||
_fovChangeMultiplier = (float) config.GetValue("InputSettings", "FovChangeWithSpeed", 1.0f);
|
||||
}
|
||||
@@ -418,11 +429,6 @@ public partial class PlayerController : CharacterBody3D
|
||||
TutorialDone = true;
|
||||
}
|
||||
|
||||
public void OnWallDetected()
|
||||
{
|
||||
FinishPoweredDash();
|
||||
}
|
||||
|
||||
public void OnGrounded()
|
||||
{
|
||||
_isWallJumpAvailable = true;
|
||||
@@ -443,26 +449,121 @@ public partial class PlayerController : CharacterBody3D
|
||||
if (!isOnFloorCustom())
|
||||
_playerState.SendEvent("start_falling");
|
||||
}
|
||||
|
||||
private float _wallRunSpeedThreshold = 8f;
|
||||
|
||||
public void HandleAirborne(float delta)
|
||||
{
|
||||
MoveInAir(delta);
|
||||
if (isOnFloorCustom())
|
||||
_playerState.SendEvent("grounded");
|
||||
if (WallHugSystem.IsWallHugging() && Velocity.Y < 0)
|
||||
|
||||
if (!WallHugSystem.IsWallHugging())
|
||||
return;
|
||||
|
||||
// Going upwards, we stay simply airborne
|
||||
if (Velocity.AngleTo(Vector3.Up) < Math.PI / 4)
|
||||
return;
|
||||
|
||||
// Should we start a wall run
|
||||
var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Zero);
|
||||
var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
|
||||
var hvelProjected = hvel.Slide(_wallHugStartNormal);
|
||||
var haveEnoughSpeed = hvelProjected.Length() > _wallRunSpeedThreshold;
|
||||
var isHeadPlanting = Velocity.AngleTo(wallNormal) < Math.PI / 4;
|
||||
var isGoingDownwards = Velocity.AngleTo(Vector3.Down) < Math.PI / 4;
|
||||
if (haveEnoughSpeed && !isHeadPlanting && !isGoingDownwards)
|
||||
{
|
||||
_playerState.SendEvent("wall_run");
|
||||
return;
|
||||
}
|
||||
|
||||
// If all else fail and we go down, we hug
|
||||
if (Velocity.Y < 0)
|
||||
_playerState.SendEvent("wall_hug");
|
||||
|
||||
}
|
||||
|
||||
private Vector3 _wallHugStartLocation = Vector3.Zero;
|
||||
private Vector3 _wallHugStartNormal = Vector3.Zero;
|
||||
private Vector3 _wallHugStartProjectedVelocity = Vector3.Zero;
|
||||
|
||||
public void OnWallDetected()
|
||||
{
|
||||
FinishPoweredDash();
|
||||
|
||||
if (!_onWall.Active)
|
||||
return;
|
||||
|
||||
var newWallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
|
||||
_wallHugStartNormal = newWallNormal;
|
||||
}
|
||||
|
||||
private float _timeSinceWallStarted;
|
||||
|
||||
public void OnWallStarted()
|
||||
{
|
||||
_wallHugStartNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
|
||||
_wallHugStartLocation = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero) + _wallHugStartNormal * _playerRadius;
|
||||
_wallHugStartProjectedVelocity = Velocity.Slide(_wallHugStartNormal);
|
||||
_timeSinceWallStarted = 0;
|
||||
}
|
||||
|
||||
public void OnWallStopped()
|
||||
{
|
||||
}
|
||||
|
||||
public void HandleWallHugging(float delta)
|
||||
{
|
||||
WallHug(delta);
|
||||
if (isOnFloorCustom())
|
||||
_playerState.SendEvent("grounded");
|
||||
if (!WallHugSystem.IsWallHugging())
|
||||
{
|
||||
_playerState.SendEvent("start_falling");
|
||||
}
|
||||
}
|
||||
public void HandleWallHanging(float delta)
|
||||
{
|
||||
WallHang(delta);
|
||||
}
|
||||
|
||||
private float _wallRunUpwardVelocity = 10f;
|
||||
|
||||
public void HandleWallRunning(float delta)
|
||||
{
|
||||
_timeSinceWallStarted += delta;
|
||||
|
||||
var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
|
||||
var hvelProjected = hvel.Slide(_wallHugStartNormal);
|
||||
Velocity = hvelProjected + hvelProjected.Length()*Vector3.Up*0.3f/(1+_timeSinceWallStarted);
|
||||
Velocity *= 0.99f;
|
||||
|
||||
// if (CanMantle())
|
||||
// {
|
||||
// MantleToLocation(_plannedMantleLocation.Unwrap());
|
||||
// }
|
||||
|
||||
if (!WallHugSystem.IsWallHugging() || Velocity.Length() < _wallRunSpeedThreshold)
|
||||
{
|
||||
_playerState.SendEvent("start_falling");
|
||||
}
|
||||
}
|
||||
|
||||
public void WallHug(float delta)
|
||||
{
|
||||
var hvel = ComputeHVelocity(delta, WallHugHorizontalDeceleration, WallHugHorizontalDeceleration);
|
||||
var hvelProjected = hvel.Slide(_wallHugStartNormal);
|
||||
var vvel = Velocity.Y - (CalculateGravityForce() * delta / WallHugGravityLesseningFactor);
|
||||
vvel = Math.Abs(vvel) > WallHugDownwardMaxSpeed ? -WallHugDownwardMaxSpeed : vvel;
|
||||
Velocity = hvelProjected + vvel*Vector3.Up;
|
||||
}
|
||||
|
||||
public void WallHang(float delta)
|
||||
{
|
||||
Velocity = Vector3.Zero;
|
||||
GlobalPosition = _wallHugStartLocation;
|
||||
}
|
||||
|
||||
private Option<Vector3> _plannedMantleLocation = Option<Vector3>.None;
|
||||
|
||||
@@ -511,20 +612,6 @@ public partial class PlayerController : CharacterBody3D
|
||||
PerformEmpoweredAction();
|
||||
OnJumpStarted(MegaJumpStartVelocity);
|
||||
}
|
||||
|
||||
public void WallHug(float delta)
|
||||
{
|
||||
var hvel = ComputeHVelocity(delta, WallHugHorizontalDeceleration, WallHugHorizontalDeceleration);
|
||||
var vvel = Velocity.Y - (CalculateGravityForce() * delta / WallHugGravityLesseningFactor);
|
||||
vvel = Math.Abs(vvel) > WallHugDownwardMaxSpeed ? -WallHugDownwardMaxSpeed : vvel;
|
||||
Velocity = hvel + vvel*Vector3.Up;
|
||||
}
|
||||
|
||||
public void WallHang(float delta)
|
||||
{
|
||||
Velocity = Vector3.Zero;
|
||||
MoveAndSlide();
|
||||
}
|
||||
|
||||
public void ComputeJumpFromWallHSpeed(float jumpStrength)
|
||||
{
|
||||
@@ -533,7 +620,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
// _isWallJumpAvailable = false;
|
||||
// var isLookingTowardsWall = HeadSystem.GetForwardHorizontalVector().Dot(wallNormal) > 0.5;
|
||||
// var jumpDirection = isLookingTowardsWall ? Vector3.Up : wallNormal;
|
||||
var wallNormal = WallHugSystem.GetWallNormal().UnwrapOr(Vector3.Up);
|
||||
var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
|
||||
var jumpVector = wallNormal * jumpStrength;
|
||||
|
||||
var currentHorizontalVelocity = new Vector2(Velocity.X, Velocity.Z);
|
||||
@@ -550,9 +637,21 @@ public partial class PlayerController : CharacterBody3D
|
||||
ComputeJumpFromWallHSpeed(WallMegajumpStartVelocity);
|
||||
}
|
||||
|
||||
public void InputDeviceChanged(bool isUsingGamepad)
|
||||
{
|
||||
_isUsingGamepad = isUsingGamepad;
|
||||
}
|
||||
|
||||
public Vector3 GetMoveInput()
|
||||
{
|
||||
if (_isUsingGamepad)
|
||||
return _inputMove;
|
||||
return _inputMoveKeyboard;
|
||||
}
|
||||
|
||||
public Vector3 ComputeHVelocity(float delta, float accelerationFactor, float decelerationFactor, Vector3? direction = null)
|
||||
{
|
||||
var dir = direction ?? Transform.Basis * HeadSystem.Transform.Basis * _inputMove;
|
||||
var dir = direction ?? Transform.Basis * HeadSystem.Transform.Basis * GetMoveInput();
|
||||
|
||||
var acceleration = dir.Length() > 0 ? accelerationFactor : decelerationFactor;
|
||||
|
||||
@@ -654,6 +753,12 @@ public partial class PlayerController : CharacterBody3D
|
||||
///////////////////////////
|
||||
// Input Management ///////
|
||||
///////////////////////////
|
||||
|
||||
public void OnInputMoveKeyboard(Vector3 value)
|
||||
{
|
||||
_inputMoveKeyboard = value;
|
||||
}
|
||||
|
||||
public void OnInputMove(Vector3 value)
|
||||
{
|
||||
_inputMove = value;
|
||||
@@ -911,13 +1016,13 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
public Vector3 GetInputGlobalHDirection()
|
||||
{
|
||||
var direction = Transform.Basis * HeadSystem.Transform.Basis * _inputMove;
|
||||
var direction = Transform.Basis * HeadSystem.Transform.Basis * GetMoveInput();
|
||||
return new Vector3(direction.X, 0, direction.Z).Normalized();
|
||||
}
|
||||
|
||||
public Vector3 GetInputLocalHDirection()
|
||||
{
|
||||
var direction = _inputMove;
|
||||
var direction = GetMoveInput();
|
||||
return new Vector3(direction.X, 0, direction.Z).Normalized();
|
||||
}
|
||||
|
||||
@@ -997,7 +1102,8 @@ public partial class PlayerController : CharacterBody3D
|
||||
private void LookAround()
|
||||
{
|
||||
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
|
||||
HeadSystem.LookAround(inputLookDir, _lookSensitivityMultiplier);
|
||||
var lookSensitivity = _isUsingGamepad ? _lookSensitivityMultiplier : _mouseSensitivityMultiplier;
|
||||
HeadSystem.LookAround(inputLookDir, lookSensitivity);
|
||||
}
|
||||
|
||||
public void MoveOnGround(double delta)
|
||||
|
||||
Reference in New Issue
Block a user