From 2ff8cc74cca4964e7d63207f77fb161490fb3af5 Mon Sep 17 00:00:00 2001 From: Minimata Date: Mon, 8 Dec 2025 12:23:36 +0100 Subject: [PATCH] camera incline on wall run and normal run --- player_controller/PlayerController.tscn | 2 ++ player_controller/Scripts/PlayerController.cs | 31 ++++++++++++----- systems/head/HeadSystem.cs | 34 ++++++++++++++++++- systems/mantle/MantleSystem.cs | 5 +++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index 97a542da..88a30479 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -129,6 +129,8 @@ CapsuleDefaultHeight = 1.7 [node name="HeadSystem" parent="." instance=ExtResource("11_rxwoh")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) +CameraInclineAcceleration = 20.0 +GroundedCameraIncline = 3.0 [node name="StairsSystem" type="Node3D" parent="."] script = ExtResource("7_bmt5a") diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index 3d96a6bc..b4df176f 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -476,6 +476,7 @@ public partial class PlayerController : CharacterBody3D private Vector3 _wallHugStartLocation = Vector3.Zero; private Vector3 _wallHugStartNormal = Vector3.Zero; private Vector3 _wallHugStartProjectedVelocity = Vector3.Zero; + private Vector3 _currentWallContactPoint = Vector3.Zero; public void OnWallDetected() { @@ -491,12 +492,17 @@ public partial class PlayerController : CharacterBody3D public void OnWallStarted() { _wallHugStartNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up); - _wallHugStartLocation = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero) + _wallHugStartNormal * _playerRadius; + _currentWallContactPoint = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero); + _wallHugStartLocation = _currentWallContactPoint + _wallHugStartNormal * _playerRadius; _wallHugStartProjectedVelocity = Velocity.Slide(_wallHugStartNormal); } public void OnWallStopped() { + _wallHugStartLocation = Vector3.Zero; + _currentWallContactPoint = Vector3.Zero; + _wallHugStartNormal = Vector3.Zero; + _wallHugStartProjectedVelocity = Vector3.Zero; } public void HandleWallHugging(float delta) @@ -528,11 +534,10 @@ public partial class PlayerController : CharacterBody3D Velocity = finalHVel + Vector3.Up*verticalSpeed; Velocity *= 0.995f; - if (WallRunSnapper.IsColliding()) - { - GD.Print((WallRunSnapper.GetCollisionPoint() - WallRunSnapper.GlobalPosition).Length()); - } + _currentWallContactPoint = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero); + if (isOnFloorCustom()) + _playerState.SendEvent("grounded"); if (!WallHugSystem.IsWallHugging() || Velocity.Length() < WallRunSpeedThreshold) { _playerState.SendEvent("start_falling"); @@ -643,9 +648,14 @@ public partial class PlayerController : CharacterBody3D return _inputMoveKeyboard; } + public Vector3 GetGlobalMoveInput() + { + return Transform.Basis * HeadSystem.Transform.Basis * GetMoveInput(); + } + public Vector3 ComputeHVelocity(float delta, float accelerationFactor, float decelerationFactor, Vector3? direction = null) { - var dir = direction ?? Transform.Basis * HeadSystem.Transform.Basis * GetMoveInput(); + var dir = direction ?? GetGlobalMoveInput(); var acceleration = dir.Length() > 0 ? accelerationFactor : decelerationFactor; @@ -1096,11 +1106,14 @@ public partial class PlayerController : CharacterBody3D /////////////////////////// // Stateless logic //////// /////////////////////////// - private void LookAround() + private void LookAround(double delta) { Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane); var lookSensitivity = _isUsingGamepad ? _lookSensitivityMultiplier : _mouseSensitivityMultiplier; - HeadSystem.LookAround(inputLookDir, lookSensitivity); + + var wallHugContactPoint = _onWallRunning.Active ? _currentWallContactPoint : Vector3.Zero; + var playerVelocity = GetGlobalMoveInput(); + HeadSystem.LookAround(delta, inputLookDir, playerVelocity, wallHugContactPoint, lookSensitivity); } public void MoveOnGround(double delta) @@ -1239,7 +1252,7 @@ public partial class PlayerController : CharacterBody3D /////////////////////////// public override void _PhysicsProcess(double delta) { - LookAround(); + LookAround(delta); CameraModifications((float) delta); HandleStairs((float) delta); _plannedMantleLocation = MantleSystem.FindMantleForHeadRotation(HeadSystem.Rotation.Y); diff --git a/systems/head/HeadSystem.cs b/systems/head/HeadSystem.cs index 022a9cc8..dea69e65 100644 --- a/systems/head/HeadSystem.cs +++ b/systems/head/HeadSystem.cs @@ -1,5 +1,6 @@ using System; using Godot; +using RustyOptions; namespace Movementtests.systems; @@ -11,6 +12,15 @@ public partial class HeadSystem : Node3D [Export(PropertyHint.Range, "0,10,0.1,or_greater")] public float LookSensitivity { get; set; } = 1f; + + [Export(PropertyHint.Range, "0.1,50,0.1,or_greater")] + public double CameraInclineAcceleration { get; set; } = 10f; + + [Export(PropertyHint.Range, "0,10,0.1,or_greater")] + public float WallRunCameraIncline { get; set; } = 5f; + + [Export(PropertyHint.Range, "0,10,0.1,or_greater")] + public float GroundedCameraIncline { get; set; } = 5f; public void Init() { @@ -25,7 +35,7 @@ public partial class HeadSystem : Node3D _animationPlayer.Play("mantle"); } - public void LookAround(Vector2 lookDir, float sensitivitMultiplier = 1f) + public void LookAround(double delta, Vector2 lookDir, Vector3 playerVelocity, Vector3? wallContactPoint = null, float sensitivitMultiplier = 1f) { // Horizontal movement of head float angleForHorizontalRotation = lookDir.X * LookSensitivity * sensitivitMultiplier; @@ -35,11 +45,33 @@ public partial class HeadSystem : Node3D Vector3 currentCameraRotation = _cameraAnchor.Rotation; currentCameraRotation.X += Convert.ToSingle(lookDir.Y * LookSensitivity * sensitivitMultiplier); currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f)); + + var isWallRunning = wallContactPoint.HasValue && wallContactPoint.Value.Length() > Mathf.Epsilon; + var cameraIncline = 0f; + if (isWallRunning) + { + var directionToWall = (wallContactPoint.Value - GlobalPosition).Normalized(); + var cameraInclineFactor = ComputeCameraInclineFactor(directionToWall); + cameraIncline = Mathf.DegToRad(WallRunCameraIncline * cameraInclineFactor); + } + else + { + var cameraInclineFactor = ComputeCameraInclineFactor(playerVelocity); + cameraIncline = Mathf.DegToRad(GroundedCameraIncline * cameraInclineFactor * -1.0f); + } + currentCameraRotation.Z = (float) Mathf.Lerp(currentCameraRotation.Z, cameraIncline, delta * CameraInclineAcceleration); _cameraAnchor.Rotation = currentCameraRotation; _camera.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated(); } + public float ComputeCameraInclineFactor(Vector3 direction) + { + var forward = GetForwardHorizontalVector().Normalized(); + var crossProduct = forward.Cross(direction); + return crossProduct.Length()*Mathf.Sign(crossProduct.Y); + } + public Vector3 GetForwardHorizontalVector() { return GetGlobalTransform().Basis.Z; diff --git a/systems/mantle/MantleSystem.cs b/systems/mantle/MantleSystem.cs index 9b584579..d1f606d5 100644 --- a/systems/mantle/MantleSystem.cs +++ b/systems/mantle/MantleSystem.cs @@ -33,6 +33,11 @@ public partial class MantleSystem: Node3D { return Option.None; } + if (_wallInFrontCast3D.GetCollisionNormal(0).Y > 0.8f) + { + GD.Print(_wallInFrontCast3D.GetCollisionNormal(0).Y); + return Option.None; + } var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0); var collisionNormal = _wallInFrontCast3D.GetCollisionNormal(0);