Compare commits

...

5 Commits

Author SHA1 Message Date
a98785abec Update .gitea/workflows/main.yaml
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 18s
Create tag and build when new code gets to main / Export (push) Successful in 8m49s
2025-12-10 21:26:25 +00:00
7c4e541446 fixed input mapping context issue
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Export (push) Successful in 6m5s
2025-12-10 17:10:41 +01:00
7d31d17034 tuto fixes
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 6m7s
2025-12-10 10:04:05 +01:00
2ff8cc74cc camera incline on wall run and normal run
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 21s
Create tag and build when new code gets to main / Export (push) Successful in 6m17s
2025-12-08 12:23:36 +01:00
fabafbb35b small improvements on the wall run
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 18s
Create tag and build when new code gets to main / Export (push) Successful in 5m54s
2025-11-14 16:39:17 +01:00
10 changed files with 136 additions and 56 deletions

View File

@@ -69,11 +69,11 @@ jobs:
# mkdir -v -p build/linux # mkdir -v -p build/linux
# godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64 # godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
# zip -r Linux.zip build/linux # zip -r Linux.zip build/linux
# - name: Mac Build - name: Mac Build
# run: | run: |
# mkdir -v -p build/mac mkdir -v -p build/mac
# godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
# zip -r Mac.zip build/mac zip -r Mac.zip build/mac
- name: Upload to Itch - name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3 uses: KikimoraGames/itch-publish@v0.0.3
@@ -102,12 +102,12 @@ jobs:
# buildNumber: ${{ needs.BumpTag.outputs.tag_name }} # buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
# gameData: Linux.zip # gameData: Linux.zip
# buildChannel: linux # buildChannel: linux
# - name: Upload to Itch - name: Upload to Itch
# uses: KikimoraGames/itch-publish@v0.0.3 uses: KikimoraGames/itch-publish@v0.0.3
# with: with:
# butlerApiKey: ${{ secrets.BUTLER_TOKEN }} butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
# itchUsername: ${{ env.ITCHIO_USERNAME }} itchUsername: ${{ env.ITCHIO_USERNAME }}
# itchGameId: ${{ env.ITCHIO_GAMEID }} itchGameId: ${{ env.ITCHIO_GAMEID }}
# buildNumber: ${{ needs.BumpTag.outputs.tag_name }} buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
# gameData: Mac.zip gameData: Mac.zip
# buildChannel: mac buildChannel: mac

View File

@@ -14,6 +14,7 @@ var credits_scene
var sub_menu var sub_menu
func load_game_scene() -> void: func load_game_scene() -> void:
GUIDE.disable_mapping_context(menu_context)
SceneLoader.load_scene(game_scene_path) SceneLoader.load_scene(game_scene_path)
func new_game() -> void: func new_game() -> void:

View File

@@ -30,6 +30,7 @@ glow_enabled = true
[node name="Player" parent="." instance=ExtResource("1_1s2y7")] [node name="Player" parent="." instance=ExtResource("1_1s2y7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1.5) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1.5)
TutorialDone = true
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_1bvp3") environment = SubResource("Environment_1bvp3")

View File

@@ -1,7 +1,8 @@
[gd_scene load_steps=40 format=3 uid="uid://dmkw8cmalm5k"] [gd_scene load_steps=41 format=3 uid="uid://dmkw8cmalm5k"]
[ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://player_controller/PlayerController.tscn" id="1_2vsi6"] [ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://player_controller/PlayerController.tscn" id="1_2vsi6"]
[ext_resource type="Script" uid="uid://blenis2y55fmg" path="res://tools/city_helpers.gd" id="1_qwuk2"] [ext_resource type="Script" uid="uid://blenis2y55fmg" path="res://tools/city_helpers.gd" id="1_qwuk2"]
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="2_p287n"]
[ext_resource type="Texture2D" uid="uid://ca4kkq3w8cd4n" path="res://assets/sky/sky_15_2k.png" id="2_ruo5i"] [ext_resource type="Texture2D" uid="uid://ca4kkq3w8cd4n" path="res://assets/sky/sky_15_2k.png" id="2_ruo5i"]
[ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="2_uet8a"] [ext_resource type="PackedScene" uid="uid://dkr80d2pi0d41" path="res://addons/guide/debugger/guide_debugger.tscn" id="2_uet8a"]
[ext_resource type="Script" uid="uid://cyh0d64pfygbl" path="res://addons/maaacks_game_template/base/scripts/pause_menu_controller.gd" id="7_ukfuy"] [ext_resource type="Script" uid="uid://cyh0d64pfygbl" path="res://addons/maaacks_game_template/base/scripts/pause_menu_controller.gd" id="7_ukfuy"]
@@ -49,7 +50,7 @@ size = Vector3(12, 11.5, 5)
size = Vector3(12, 13, 7) size = Vector3(12, 13, 7)
[sub_resource type="BoxShape3D" id="BoxShape3D_lnjrw"] [sub_resource type="BoxShape3D" id="BoxShape3D_lnjrw"]
size = Vector3(14, 15.5, 13.5) size = Vector3(14, 10, 13.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_3w3wd"] [sub_resource type="BoxShape3D" id="BoxShape3D_3w3wd"]
size = Vector3(13, 16.5, 11.5) size = Vector3(13, 16.5, 11.5)
@@ -91,6 +92,7 @@ adjustment_enabled = true
[node name="Main" type="Node3D"] [node name="Main" type="Node3D"]
script = ExtResource("1_qwuk2") script = ExtResource("1_qwuk2")
base_mode = ExtResource("2_p287n")
[node name="BackgroundMusicPlayer" parent="." instance=ExtResource("9_i2xii")] [node name="BackgroundMusicPlayer" parent="." instance=ExtResource("9_i2xii")]
stream = ExtResource("10_eca4n") stream = ExtResource("10_eca4n")
@@ -102,7 +104,6 @@ player = NodePath("../Player")
pause = ExtResource("10_0ari0") pause = ExtResource("10_0ari0")
[node name="TutorialController" type="Control" parent="."] [node name="TutorialController" type="Control" parent="."]
visible = false
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
@@ -318,10 +319,9 @@ shape = SubResource("BoxShape3D_3wccx")
[node name="TutoDash2" parent="TutoTriggers" instance=ExtResource("16_qwuk2")] [node name="TutoDash2" parent="TutoTriggers" instance=ExtResource("16_qwuk2")]
transform = Transform3D(0.14133325, 0, 0.98996216, 0, 1, 0, -0.98996216, 0, 0.14133325, 28.885735, 27.749329, 25.360323) transform = Transform3D(0.14133325, 0, 0.98996216, 0, 1, 0, -0.98996216, 0, 0.14133325, 28.885735, 27.749329, 25.360323)
first_input_texture = ExtResource("16_crf87") first_input_texture = ExtResource("19_efsse")
second_input_texture = ExtResource("19_efsse") complex_input_text = "against wall"
complex_input_text = "in air" tuto_text = "Wall run"
tuto_text = "Dash"
[node name="CollisionShape3D" type="CollisionShape3D" parent="TutoTriggers/TutoDash2"] [node name="CollisionShape3D" type="CollisionShape3D" parent="TutoTriggers/TutoDash2"]
transform = Transform3D(1.0000031, 0, -4.917383e-07, 0, 1, 0, 4.917383e-07, 0, 1.0000031, 5.500023, 5, 0) transform = Transform3D(1.0000031, 0, -4.917383e-07, 0, 1, 0, 4.917383e-07, 0, 1.0000031, 5.500023, 5, 0)
@@ -333,7 +333,7 @@ collision_layer = 0
collision_mask = 16 collision_mask = 16
[node name="CollisionShape3D" type="CollisionShape3D" parent="TutoTriggers/TriggerTutoWeaponThrow"] [node name="CollisionShape3D" type="CollisionShape3D" parent="TutoTriggers/TriggerTutoWeaponThrow"]
transform = Transform3D(0.9961947, 0, -0.08715595, 0, 1, 0, 0.08715595, 0, 0.9961947, 4.4208603, 7, -4.632329) transform = Transform3D(0.9961947, 0, -0.08715595, 0, 1, 0, 0.08715595, 0, 0.9961947, 4.4208603, 9.75, -4.632329)
shape = SubResource("BoxShape3D_lnjrw") shape = SubResource("BoxShape3D_lnjrw")
[node name="TriggerTutoEnjoy" type="Area3D" parent="TutoTriggers"] [node name="TriggerTutoEnjoy" type="Area3D" parent="TutoTriggers"]
@@ -376,10 +376,9 @@ shadow_opacity = 0.95
shadow_blur = 2.435 shadow_blur = 2.435
[node name="Player" parent="." node_paths=PackedStringArray("TutorialWeaponTarget") instance=ExtResource("1_2vsi6")] [node name="Player" parent="." node_paths=PackedStringArray("TutorialWeaponTarget") instance=ExtResource("1_2vsi6")]
transform = Transform3D(0.054514527, 0, -0.9985129, 0, 1, 0, 0.9985129, 0, 0.054514527, -6, 75.5, -13.5) transform = Transform3D(0.054514527, 0, -0.9985129, 0, 1, 0, 0.9985129, 0, 0.054514527, 0, -132.75, 118)
collision_layer = 17 collision_layer = 17
TutorialWeaponTarget = NodePath("../PlacedTutorialWeapon/WeaponLocationTarget") TutorialWeaponTarget = NodePath("../PlacedTutorialWeapon/WeaponLocationTarget")
TutorialDone = true
AccelerationAir = 1.5 AccelerationAir = 1.5
[node name="DebugLayer" type="CanvasLayer" parent="."] [node name="DebugLayer" type="CanvasLayer" parent="."]

View File

@@ -84,6 +84,14 @@ PostDashSpeed = 30.0
WallHugGravityLesseningFactor = 15.0 WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 8.0 WallHugDownwardMaxSpeed = 8.0
WallHugHorizontalDeceleration = 0.5 WallHugHorizontalDeceleration = 0.5
WallRunAltitudeLossSpeed = 12.0
WallRunSpeedThreshold = 5.0
[node name="WallRunSnapper" type="RayCast3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
target_position = Vector3(0, 0, -5)
collision_mask = 2
[node name="InputController" type="Node3D" parent="."] [node name="InputController" type="Node3D" parent="."]
script = ExtResource("16_v31n3") script = ExtResource("16_v31n3")
@@ -121,6 +129,8 @@ CapsuleDefaultHeight = 1.7
[node name="HeadSystem" parent="." instance=ExtResource("11_rxwoh")] [node name="HeadSystem" parent="." instance=ExtResource("11_rxwoh")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) 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="."] [node name="StairsSystem" type="Node3D" parent="."]
script = ExtResource("7_bmt5a") script = ExtResource("7_bmt5a")
@@ -163,7 +173,6 @@ target_position = Vector3(0, 1, 0)
[node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")] [node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")]
[node name="WallHugSystem" type="Node3D" parent="."] [node name="WallHugSystem" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
script = ExtResource("27_n7qhm") script = ExtResource("27_n7qhm")
[node name="back" type="RayCast3D" parent="WallHugSystem"] [node name="back" type="RayCast3D" parent="WallHugSystem"]

View File

@@ -35,6 +35,7 @@ public partial class PlayerController : CharacterBody3D
public Node3D DashIndicatorNode; public Node3D DashIndicatorNode;
public MeshInstance3D DashIndicatorMesh; public MeshInstance3D DashIndicatorMesh;
public CylinderMesh DashIndicatorMeshCylinder; public CylinderMesh DashIndicatorMeshCylinder;
public RayCast3D WallRunSnapper;
private bool _movementEnabled = true; private bool _movementEnabled = true;
@@ -154,6 +155,16 @@ public partial class PlayerController : CharacterBody3D
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")] [Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
public float WallHugHorizontalDeceleration { get; set; } = 5f; public float WallHugHorizontalDeceleration { get; set; } = 5f;
// Wall run
[ExportGroup("Wall run")]
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunUpwardVelocity { get; set; } = 10f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunAltitudeLossSpeed { get; set; } = 10f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunSpeedThreshold { get; set; } = 8f;
private float _targetSpeed; private float _targetSpeed;
private float _gravity; private float _gravity;
@@ -246,6 +257,7 @@ public partial class PlayerController : CharacterBody3D
DashSystem = GetNode<DashSystem>("DashSystem"); DashSystem = GetNode<DashSystem>("DashSystem");
StairsSystem = GetNode<StairsSystem>("StairsSystem"); StairsSystem = GetNode<StairsSystem>("StairsSystem");
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem"); WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D"); RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D"); RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
_headCollisionDetectors = new RayCast3D[NUM_OF_HEAD_COLLISION_DETECTORS]; _headCollisionDetectors = new RayCast3D[NUM_OF_HEAD_COLLISION_DETECTORS];
@@ -427,8 +439,6 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("start_falling"); _playerState.SendEvent("start_falling");
} }
private float _wallRunSpeedThreshold = 8f;
public void HandleAirborne(float delta) public void HandleAirborne(float delta)
{ {
MoveInAir(delta); MoveInAir(delta);
@@ -444,19 +454,21 @@ public partial class PlayerController : CharacterBody3D
// Should we start a wall run // Should we start a wall run
var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Zero); var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Zero);
var isIndeedWall = wallNormal.Y < 0.1;
var hvel = new Vector3(Velocity.X, 0, Velocity.Z); var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
var hvelProjected = hvel.Slide(_wallHugStartNormal); var hvelProjected = hvel.Slide(_wallHugStartNormal);
var haveEnoughSpeed = hvelProjected.Length() > _wallRunSpeedThreshold; var haveEnoughSpeed = hvelProjected.Length() > WallRunSpeedThreshold;
var isHeadPlanting = Velocity.AngleTo(wallNormal) < Math.PI / 4; var isCoplanarEnough = Velocity.AngleTo(wallNormal) > Math.PI/4 && Velocity.AngleTo(wallNormal) < 3*Math.PI/4;
var isGoingDownwards = Velocity.AngleTo(Vector3.Down) < Math.PI / 4; var isGoingDownwards = Velocity.AngleTo(Vector3.Down) < Math.PI/4;
if (haveEnoughSpeed && !isHeadPlanting && !isGoingDownwards) if (haveEnoughSpeed && isCoplanarEnough && !isGoingDownwards && isIndeedWall && !_coyoteEnabled.Active)
{ {
SetVerticalVelocity(WallRunUpwardVelocity);
_playerState.SendEvent("wall_run"); _playerState.SendEvent("wall_run");
return; return;
} }
// If all else fail and we go down, we hug // If all else fail and we go down, we hug
if (Velocity.Y < 0) if (Velocity.Y < 0 && !_coyoteEnabled.Active)
_playerState.SendEvent("wall_hug"); _playerState.SendEvent("wall_hug");
} }
@@ -464,6 +476,7 @@ public partial class PlayerController : CharacterBody3D
private Vector3 _wallHugStartLocation = Vector3.Zero; private Vector3 _wallHugStartLocation = Vector3.Zero;
private Vector3 _wallHugStartNormal = Vector3.Zero; private Vector3 _wallHugStartNormal = Vector3.Zero;
private Vector3 _wallHugStartProjectedVelocity = Vector3.Zero; private Vector3 _wallHugStartProjectedVelocity = Vector3.Zero;
private Vector3 _currentWallContactPoint = Vector3.Zero;
public void OnWallDetected() public void OnWallDetected()
{ {
@@ -476,18 +489,20 @@ public partial class PlayerController : CharacterBody3D
_wallHugStartNormal = newWallNormal; _wallHugStartNormal = newWallNormal;
} }
private float _timeSinceWallStarted;
public void OnWallStarted() public void OnWallStarted()
{ {
_wallHugStartNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up); _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); _wallHugStartProjectedVelocity = Velocity.Slide(_wallHugStartNormal);
_timeSinceWallStarted = 0;
} }
public void OnWallStopped() public void OnWallStopped()
{ {
_wallHugStartLocation = Vector3.Zero;
_currentWallContactPoint = Vector3.Zero;
_wallHugStartNormal = Vector3.Zero;
_wallHugStartProjectedVelocity = Vector3.Zero;
} }
public void HandleWallHugging(float delta) public void HandleWallHugging(float delta)
@@ -505,23 +520,25 @@ public partial class PlayerController : CharacterBody3D
WallHang(delta); WallHang(delta);
} }
private float _wallRunUpwardVelocity = 10f;
public void HandleWallRunning(float delta) public void HandleWallRunning(float delta)
{ {
_timeSinceWallStarted += delta; // Find horizontal velocity projected on the current wall
var hvel = new Vector3(Velocity.X, 0, Velocity.Z); var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
var hvelProjected = hvel.Slide(_wallHugStartNormal); 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) // Reorient horizontal velocity so we keep it coplanar with the wall without losing speed
var finalHVel = hvelProjected.Normalized() * hvel.Length();
// Adapt vertical speed
var verticalSpeed = Velocity.Y - WallRunAltitudeLossSpeed * delta;
Velocity = finalHVel + Vector3.Up*verticalSpeed;
Velocity *= 0.995f;
_currentWallContactPoint = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
if (!WallHugSystem.IsWallHugging() || Velocity.Length() < WallRunSpeedThreshold)
{ {
_playerState.SendEvent("start_falling"); _playerState.SendEvent("start_falling");
} }
@@ -549,7 +566,10 @@ public partial class PlayerController : CharacterBody3D
{ {
if (CanMantle()) if (CanMantle())
{ {
MantleToLocation(_plannedMantleLocation.Unwrap()); var location = _plannedMantleLocation.UnwrapOr(Vector3.Zero);
if (location == Vector3.Zero)
return; // For some reason CanMantle can return an invalid location so fuck off I guess
MantleToLocation(location);
return; return;
} }
@@ -558,6 +578,7 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("megajump"); _playerState.SendEvent("megajump");
return; return;
} }
_playerState.SendEvent("jump"); _playerState.SendEvent("jump");
} }
@@ -582,6 +603,7 @@ public partial class PlayerController : CharacterBody3D
public void OnDoubleJumpStarted() public void OnDoubleJumpStarted()
{ {
_canDash = true; _canDash = true;
_canDashAirborne = true;
OnJumpStarted(DoubleJumpStartVelocity); OnJumpStarted(DoubleJumpStartVelocity);
} }
public void OnMegaJumpStarted() public void OnMegaJumpStarted()
@@ -626,9 +648,14 @@ public partial class PlayerController : CharacterBody3D
return _inputMoveKeyboard; return _inputMoveKeyboard;
} }
public Vector3 GetGlobalMoveInput()
{
return Transform.Basis * HeadSystem.Transform.Basis * GetMoveInput();
}
public Vector3 ComputeHVelocity(float delta, float accelerationFactor, float decelerationFactor, Vector3? direction = null) 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; var acceleration = dir.Length() > 0 ? accelerationFactor : decelerationFactor;
@@ -943,6 +970,9 @@ public partial class PlayerController : CharacterBody3D
public void PlaceWeaponForTutorial() public void PlaceWeaponForTutorial()
{ {
if (TutorialDone)
return;
RemoveChild(WeaponRoot); RemoveChild(WeaponRoot);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponRoot); GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponRoot);
WeaponRoot.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition); WeaponRoot.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition);
@@ -1076,11 +1106,14 @@ public partial class PlayerController : CharacterBody3D
/////////////////////////// ///////////////////////////
// Stateless logic //////// // Stateless logic ////////
/////////////////////////// ///////////////////////////
private void LookAround() private void LookAround(double delta)
{ {
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane); Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
var lookSensitivity = _isUsingGamepad ? _lookSensitivityMultiplier : _mouseSensitivityMultiplier; 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) public void MoveOnGround(double delta)
@@ -1158,7 +1191,7 @@ public partial class PlayerController : CharacterBody3D
Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams
{ {
Delta = delta, Delta = delta,
IsOnFloorCustom = isOnFloorCustom(), IsOnFloorCustom = isOnFloorCustom() || _onWallRunning.Active,
Velocity = Velocity, Velocity = Velocity,
SettingsMultiplier = _headBobbingMultiplier SettingsMultiplier = _headBobbingMultiplier
}; };
@@ -1219,7 +1252,7 @@ public partial class PlayerController : CharacterBody3D
/////////////////////////// ///////////////////////////
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
LookAround(); LookAround(delta);
CameraModifications((float) delta); CameraModifications((float) delta);
HandleStairs((float) delta); HandleStairs((float) delta);
_plannedMantleLocation = MantleSystem.FindMantleForHeadRotation(HeadSystem.Rotation.Y); _plannedMantleLocation = MantleSystem.FindMantleForHeadRotation(HeadSystem.Rotation.Y);

View File

@@ -1,5 +1,6 @@
using System; using System;
using Godot; using Godot;
using RustyOptions;
namespace Movementtests.systems; namespace Movementtests.systems;
@@ -11,6 +12,15 @@ public partial class HeadSystem : Node3D
[Export(PropertyHint.Range, "0,10,0.1,or_greater")] [Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float LookSensitivity { get; set; } = 1f; 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() public void Init()
{ {
@@ -25,7 +35,7 @@ public partial class HeadSystem : Node3D
_animationPlayer.Play("mantle"); _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 // Horizontal movement of head
float angleForHorizontalRotation = lookDir.X * LookSensitivity * sensitivitMultiplier; float angleForHorizontalRotation = lookDir.X * LookSensitivity * sensitivitMultiplier;
@@ -35,11 +45,33 @@ public partial class HeadSystem : Node3D
Vector3 currentCameraRotation = _cameraAnchor.Rotation; Vector3 currentCameraRotation = _cameraAnchor.Rotation;
currentCameraRotation.X += Convert.ToSingle(lookDir.Y * LookSensitivity * sensitivitMultiplier); currentCameraRotation.X += Convert.ToSingle(lookDir.Y * LookSensitivity * sensitivitMultiplier);
currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f)); 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; _cameraAnchor.Rotation = currentCameraRotation;
_camera.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated(); _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() public Vector3 GetForwardHorizontalVector()
{ {
return GetGlobalTransform().Basis.Z; return GetGlobalTransform().Basis.Z;

View File

@@ -82,6 +82,7 @@ func on_input_hit():
input_hit.emit() input_hit.emit()
func on_input_jump_started(): func on_input_jump_started():
print("jump")
input_jump_started.emit() input_jump_started.emit()
func on_input_jump_ongoing(): func on_input_jump_ongoing():

View File

@@ -33,6 +33,10 @@ public partial class MantleSystem: Node3D
{ {
return Option<Vector3>.None; return Option<Vector3>.None;
} }
if (_wallInFrontCast3D.GetCollisionNormal(0).Y > 0.8f)
{
return Option<Vector3>.None;
}
var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0); var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0);
var collisionNormal = _wallInFrontCast3D.GetCollisionNormal(0); var collisionNormal = _wallInFrontCast3D.GetCollisionNormal(0);

View File

@@ -5,8 +5,8 @@ extends Node3D
@export_tool_button("Tuto start", "Callable") var player_tuto_start = place_player_tuto_start @export_tool_button("Tuto start", "Callable") var player_tuto_start = place_player_tuto_start
@export_tool_button("Playground", "Callable") var player_playground = place_player_playground @export_tool_button("Playground", "Callable") var player_playground = place_player_playground
@onready var player: CharacterBody3D = $Player
@onready var player: CharacterBody3D = $Player
func place_player_tuto_start(): func place_player_tuto_start():
player.position = Vector3(0, -132.75, 118) player.position = Vector3(0, -132.75, 118)