Compare commits

..

17 Commits

Author SHA1 Message Date
1a4b2f4c19 Ended with remapping and removed old junk
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 10m34s
2026-01-12 15:41:43 +01:00
52a9c3f120 Remapped some inputs and added slide, slam and parry mappings 2026-01-12 14:58:43 +01:00
2301884418 added a wall jump section in the GYM 2026-01-12 12:01:40 +01:00
04054cfeae Added ground-like movement (i.e. air control when close to ground) and wall jumping away from the wall is always possible even when facing it 2026-01-12 11:52:35 +01:00
66be7838bb buffered inputs revamped and added mantle jumps and dashed
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 10m30s
2026-01-11 18:14:53 +01:00
1eb65d1520 some shader work and improved mantle feel 2026-01-11 17:09:58 +01:00
f2a39316ba shader changes that don't do anything
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 9m48s
2026-01-07 17:11:49 +01:00
fffd8c947b implementing jump input buffering on grounded
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 9m47s
2026-01-07 09:58:18 +01:00
a1d57d6a1a some tuto fixing
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 9m49s
2026-01-06 16:35:17 +01:00
941205af2b small gravity and jump balancing, removed wall jumping coyote times
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 9m34s
2026-01-06 16:08:39 +01:00
6c2ad89687 fixing the manlting into geo
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 9m42s
2026-01-06 12:36:38 +01:00
59494f9e98 updating CI to build for linux as well
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 9m34s
2025-12-25 09:37:51 +01:00
510246c341 fix a scene load issue
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 8m22s
2025-12-22 14:25:17 +01:00
b184bcdea5 added a small dash when leaving a wall run organically
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 8m36s
2025-12-21 17:23:38 +01:00
cf52af4237 mantling after aimed dash with new mantle system 2025-12-21 16:44:35 +01:00
e0fc301414 fixed user stuff
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 17s
Create tag and build when new code gets to main / Export (push) Successful in 8m10s
2025-12-19 19:11:53 +01:00
b792e8721c mantle system fix amazing
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 22s
Create tag and build when new code gets to main / Export (push) Successful in 8m19s
2025-12-19 18:59:34 +01:00
30 changed files with 1305 additions and 1159 deletions

View File

@@ -54,27 +54,12 @@ jobs:
- name: Import resources and build solution
run: |
godot --headless --editor --build-solutions --quit --import --path $PWD
- name: Build Windows
run: |
mkdir -v -p build/windows
godot --headless --verbose --build-solutions --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
zip -r Windows.zip build/windows
- name: Build Windows ARM
run: |
mkdir -v -p build/windowsArm
godot --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
zip -r WindowsArm.zip build/windowsArm
# - name: Linux Build
# run: |
# mkdir -v -p build/linux
# godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
# zip -r Linux.zip build/linux
- name: Mac Build
run: |
mkdir -v -p build/mac
godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
zip -r Mac.zip build/mac
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:
@@ -84,6 +69,12 @@ jobs:
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
gameData: Windows.zip
buildChannel: windows
- name: Build Windows ARM
run: |
mkdir -v -p build/windowsArm
godot --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
zip -r WindowsArm.zip build/windowsArm
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:
@@ -93,15 +84,27 @@ jobs:
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
gameData: WindowsArm.zip
buildChannel: windows-arm
# - name: Upload to Itch
# uses: KikimoraGames/itch-publish@v0.0.3
# with:
# butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
# itchUsername: ${{ env.ITCHIO_USERNAME }}
# itchGameId: ${{ env.ITCHIO_GAMEID }}
# buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
# gameData: Linux.zip
# buildChannel: linux
- name: Linux Build
run: |
mkdir -v -p build/linux
godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
zip -r Linux.zip build/linux
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
itchUsername: ${{ env.ITCHIO_USERNAME }}
itchGameId: ${{ env.ITCHIO_GAMEID }}
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
gameData: Linux.zip
buildChannel: linux
- name: Mac Build
run: |
mkdir -v -p build/mac
godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
zip -r Mac.zip build/mac
- name: Upload to Itch
uses: KikimoraGames/itch-publish@v0.0.3
with:

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@
.import/
/builds
/communication
# Imported translations (automatically generated from CSV files)
*.translation

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,7 @@ shader_parameter/floorRoughnessMap = ExtResource("4_rir86")
shader_parameter/floorNormalMap = ExtResource("3_f1b6h")
shader_parameter/floorHeightMap = ExtResource("2_0e3id")
shader_parameter/floorUvScale = 0.5
shader_parameter/enablePom = true
shader_parameter/enablePom = false
shader_parameter/heightMinLayers = 8
shader_parameter/heightMaxLayers = 64
shader_parameter/heightScale = 0.08

View File

@@ -28,6 +28,7 @@ uniform float heightScale = 1.0;
varying vec3 worldPos;
varying vec3 worldNormal;
varying vec3 diffuse;
void vertex() {
@@ -177,12 +178,14 @@ void fragment() {
// sample and output
SPECULAR = specular;
ALBEDO = triplanarSample(texCoordX, texCoordY, texCoordZ, blend, yDot).rgb;
diffuse = ALBEDO;
ROUGHNESS = triplanarRoughness(texCoordX, texCoordY, texCoordZ, blend, yDot).r;
NORMAL = mix(worldNormal, triplanarNormal(yDot, texCoordX, texCoordY, texCoordZ, blend), normalMapStrength);
NORMAL = normalize((VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz);
}
//void light() {
// // Called for every pixel for every light affecting the material.
// // Uncomment to replace the default light processing function with this one.
//}
void light() {
float lambert = clamp(dot(NORMAL, LIGHT), 0.0, 1.0);
float halfLambert = pow(lambert*0.5 + 0.5, 5);
DIFFUSE_LIGHT += halfLambert * ATTENUATION * LIGHT_COLOR / PI;
}

View File

@@ -31,7 +31,7 @@ shader_parameter/floorRoughnessMap = ExtResource("4_4vhk1")
shader_parameter/floorNormalMap = ExtResource("3_ytvoj")
shader_parameter/floorHeightMap = ExtResource("2_4vhk1")
shader_parameter/floorUvScale = 0.5
shader_parameter/enablePom = true
shader_parameter/enablePom = false
shader_parameter/heightMinLayers = 8
shader_parameter/heightMaxLayers = 64
shader_parameter/heightScale = 0.2

View File

@@ -27,7 +27,7 @@ shader_parameter/floorRoughnessMap = ExtResource("4_ob11h")
shader_parameter/floorNormalMap = ExtResource("3_ff2cr")
shader_parameter/floorHeightMap = ExtResource("2_roy1o")
shader_parameter/floorUvScale = 0.5
shader_parameter/enablePom = true
shader_parameter/enablePom = false
shader_parameter/heightMinLayers = 8
shader_parameter/heightMaxLayers = 64
shader_parameter/heightScale = 1.0

Binary file not shown.

Binary file not shown.

View File

@@ -159,6 +159,38 @@ text = "0.5m"
transform = Transform3D(-2.18557e-07, -5, -2.18557e-07, 0, -2.18557e-07, 5, -5, 2.18557e-07, 9.55343e-15, -7, 0.1, -6.5)
text = "1m"
[node name="Label3D22" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, 1)
text = "1.5m"
[node name="Label3D23" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -11)
text = "2m"
[node name="Label3D24" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -21.5)
text = "3m"
[node name="Label3D25" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -31)
text = "4m"
[node name="Label3D26" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -41.5)
text = "5m"
[node name="Label3D27" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -51.5)
text = "6m"
[node name="Label3D28" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -61)
text = "7m"
[node name="Label3D29" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.1855689e-07, 5, 2.18557e-07, 0, -2.18557e-07, 5, 5, 2.1855689e-07, 9.55343e-15, -28.5, 0.1, -74.5)
text = "8m"
[node name="Label3D8" type="Label3D" parent="Greybox/JumpHeights"]
transform = Transform3D(-2.18557e-07, -5, -2.18557e-07, 0, -2.18557e-07, 5, -5, 2.18557e-07, 9.55343e-15, -7, 0.1, -11.5)
text = "1.5m"
@@ -324,9 +356,57 @@ size = Vector3(5, 17.5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D29" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.5, 10, -76.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -30.25, 10, -40)
use_collision = true
size = Vector3(5, 20, 5)
size = Vector3(0.5, 20, 80)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D33" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -24.75, 10, -5)
use_collision = true
size = Vector3(7.5, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D34" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -24.5, 10, -15)
use_collision = true
size = Vector3(7, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D35" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -24, 10, -25)
use_collision = true
size = Vector3(6, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D36" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23.5, 10, -35)
use_collision = true
size = Vector3(5, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D37" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23, 10, -45)
use_collision = true
size = Vector3(4, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D38" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -22.5, 10, -55)
use_collision = true
size = Vector3(3, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D39" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -22, 10, -65)
use_collision = true
size = Vector3(2, 20, 10)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D40" type="CSGBox3D" parent="Greybox/JumpHeights"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.5, 10, -75)
use_collision = true
size = Vector3(1, 20, 10)
material = ExtResource("3_vvhq3")
[node name="Passageways" type="CSGCombiner3D" parent="Greybox"]
@@ -567,6 +647,12 @@ use_collision = true
size = Vector3(3, 1, 0.25)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D57" type="CSGBox3D" parent="Greybox/Mantles"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -13, 3.5, -21.629175)
use_collision = true
size = Vector3(5, 1, 0.25)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D54" type="CSGBox3D" parent="Greybox/Mantles"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.5, 1, 20.125)
use_collision = true

View File

@@ -1,8 +1,7 @@
[gd_scene load_steps=41 format=3 uid="uid://dmkw8cmalm5k"]
[gd_scene load_steps=40 format=3 uid="uid://dmkw8cmalm5k"]
[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="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="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"]
@@ -92,7 +91,6 @@ adjustment_enabled = true
[node name="Main" type="Node3D"]
script = ExtResource("1_qwuk2")
base_mode = ExtResource("2_p287n")
[node name="BackgroundMusicPlayer" parent="." instance=ExtResource("9_i2xii")]
stream = ExtResource("10_eca4n")
@@ -104,6 +102,7 @@ player = NodePath("../Player")
pause = ExtResource("10_0ari0")
[node name="TutorialController" type="Control" parent="."]
visible = false
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -376,9 +375,10 @@ shadow_opacity = 0.95
shadow_blur = 2.435
[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, 0, -132.75, 118)
transform = Transform3D(0.054514527, 0, -0.9985129, 0, 1, 0, 0.9985129, 0, 0.054514527, -6, 75.5, -13.5)
collision_layer = 17
TutorialWeaponTarget = NodePath("../PlacedTutorialWeapon/WeaponLocationTarget")
TutorialDone = true
AccelerationAir = 1.5
[node name="DebugLayer" type="CanvasLayer" parent="."]

View File

@@ -1,6 +1,7 @@
[gd_scene load_steps=47 format=3 uid="uid://bei4nhkf8lwdo"]
[gd_scene load_steps=49 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="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"]
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="3_cresl"]
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
@@ -13,22 +14,22 @@
[ext_resource type="Script" uid="uid://dd1yrt7eiiyf4" path="res://player_controller/Scripts/CapsuleCollider.cs" id="8_lmtjd"]
[ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://systems/inputs/base_mode/aim_down.tres" id="8_obsfv"]
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="8_qu4wy"]
[ext_resource type="Resource" uid="uid://7wm8ywvujwf" path="res://systems/inputs/base_mode/aim_cancel.tres" id="9_5p2qc"]
[ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="9_nob5r"]
[ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://systems/inputs/base_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="Resource" uid="uid://b334rau1yxmm7" path="res://systems/inputs/base_mode/empower_down.tres" id="10_nodcl"]
[ext_resource type="Resource" uid="uid://b5gx3q8nvu72e" path="res://systems/inputs/base_mode/hit.tres" id="11_cresl"]
[ext_resource type="Resource" uid="uid://bbce5wfwxpns1" path="res://systems/inputs/base_mode/empower_release.tres" id="11_ruloh"]
[ext_resource type="PackedScene" uid="uid://0ysqmqphq6mq" path="res://systems/head/head_system.tscn" id="11_rxwoh"]
[ext_resource type="Resource" uid="uid://d2r0ur8k3cuu3" path="res://systems/inputs/base_mode/dash.tres" id="12_34snm"]
[ext_resource type="Script" uid="uid://b6k73aj5povgv" path="res://player_controller/Scripts/FieldOfView.cs" id="12_m2mxi"]
[ext_resource type="Resource" uid="uid://55b0dsvioj08" path="res://systems/inputs/base_mode/jump_pressed.tres" id="13_nob5r"]
[ext_resource type="Shape3D" uid="uid://keseacdcooot" path="res://player_controller/resources/PlayerShape.tres" id="13_r7i3q"]
[ext_resource type="Resource" uid="uid://bw5k2gsv3jqcv" path="res://systems/inputs/base_mode/throw.tres" id="16_nob5r"]
[ext_resource type="Script" uid="uid://b5nk6ntlps3x0" path="res://systems/inputs/input_system.gd" id="16_v31n3"]
[ext_resource type="Resource" uid="uid://b334rau1yxmm7" path="res://systems/inputs/base_mode/slide.tres" id="17_6lejt"]
[ext_resource type="Resource" uid="uid://htqvokm8mufq" path="res://systems/inputs/base_mode/move.tres" id="17_h6vvl"]
[ext_resource type="PackedScene" uid="uid://cqduhd4opgwvm" path="res://systems/dash/dash_system.tscn" id="18_q5h8a"]
[ext_resource type="Resource" uid="uid://bbce5wfwxpns1" path="res://systems/inputs/base_mode/slide_pressed.tres" id="18_q14ux"]
[ext_resource type="Resource" uid="uid://spo3pbqjx0eb" path="res://systems/inputs/base_mode/parry.tres" id="18_ruloh"]
[ext_resource type="Resource" uid="uid://dxy0071ic1wdj" path="res://systems/inputs/base_mode/slam.tres" id="20_nob5r"]
[ext_resource type="PackedScene" uid="uid://dbe5f0p6lvqtr" path="res://systems/tween_queue/tween_queue_system.tscn" id="22_rpwev"]
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="24_q5h8a"]
[ext_resource type="Script" uid="uid://couw105c3bde4" path="res://addons/godot_state_charts/state_chart.gd" id="25_wv70j"]
@@ -56,37 +57,39 @@ top_radius = 0.2
bottom_radius = 0.2
height = 1.0
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_6lejt"]
radius = 1.0
height = 3.0
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"]
blend_mode = 1
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_poq2x")
WalkSpeed = 7.5
AccelerationAir = 2.0
DecelerationAir = 0.1
Weight = 5.0
MantleTime = 0.3
AccelerationFloor = 4.0
DecelerationFloor = 3.0
AccelerationAir = 0.8
DecelerationAir = 0.02
Weight = 4.0
MantlePath = ExtResource("2_6lejt")
MantleDashStrength = 25.0
MantleJumpStartVelocity = 15.0
CoyoteTime = 0.3
SimpleJumpStartVelocity = 8.0
InputBufferFrames = 5
SimpleJumpStartVelocity = 6.0
SimpleJumpHangTimeInFrames = 1
SimpleJumpGravityLesseningFactor = 2.5
DoubleJumpStartVelocity = 15.0
SimpleJumpGravityLesseningFactor = 2.0
DoubleJumpHangTimeInFrames = 3
DoubleJumpGravityLesseningFactor = 1.5
MegaJumpStartVelocity = 30.0
MegaJumpHangTimeInFrames = 12
MegaJumpGravityLesseningFactor = 1.2
WallJumpStartVelocity = 12.0
WallJumpStartVelocity = 8.0
MaxNumberOfEmpoweredActions = 3
SimpleDashStrength = 15.0
PoweredDashStrength = 30.0
AimedDashTime = 0.2
PostDashSpeed = 30.0
WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 8.0
WallHugHorizontalDeceleration = 0.5
WallRunAltitudeLossSpeed = 12.0
WallRunSpeedThreshold = 10.0
[node name="WallRunSnapper" type="RayCast3D" parent="."]
unique_name_in_owner = true
@@ -102,19 +105,19 @@ move_left = ExtResource("5_q14ux")
move_right = ExtResource("6_q7bng")
move_front = ExtResource("7_m8gvy")
move_back = ExtResource("8_jb43f")
rotate_y = ExtResource("4_rxwoh")
rotate_vertical = ExtResource("4_rxwoh")
rotate_floorplane = ExtResource("5_4u7i3")
aim_down = ExtResource("8_obsfv")
aim_pressed = ExtResource("9_nob5r")
aim_released = ExtResource("8_lhb11")
jump = ExtResource("10_4u7i3")
jump_pressed = ExtResource("13_nob5r")
empower_down = ExtResource("10_nodcl")
empower_released = ExtResource("11_ruloh")
aim_canceled = ExtResource("9_5p2qc")
slide = ExtResource("17_6lejt")
slide_pressed = ExtResource("18_q14ux")
hit = ExtResource("11_cresl")
parry = ExtResource("18_ruloh")
dash = ExtResource("12_34snm")
throw = ExtResource("16_nob5r")
slam = ExtResource("20_nob5r")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
@@ -176,7 +179,6 @@ target_position = Vector3(0, 1, 0)
[node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")]
[node name="WallHugSystem" type="Node3D" parent="."]
visible = false
script = ExtResource("27_n7qhm")
[node name="back" type="RayCast3D" parent="WallHugSystem"]
@@ -233,7 +235,17 @@ visible = false
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 0, -1)
mesh = SubResource("CylinderMesh_nodcl")
[node name="GroundDetector" type="ShapeCast3D" parent="."]
shape = SubResource("CapsuleShape3D_6lejt")
target_position = Vector3(0, -0.5, 0)
collision_mask = 2
[node name="DashCooldown" type="Timer" parent="."]
wait_time = 0.8
one_shot = true
[node name="AirborneDashCooldown" type="Timer" parent="."]
wait_time = 0.5
one_shot = true
[node name="PowerCooldown" type="Timer" parent="."]
@@ -253,6 +265,7 @@ offset_bottom = 1.0
initial_node_to_watch = NodePath("../StateChart")
[node name="UI" type="Control" parent="."]
visible = false
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -380,28 +393,6 @@ delay_in_seconds = "0.0"
[node name="Canceled" type="Node" parent="StateChart/Root/Aim"]
script = ExtResource("27_34snm")
[node name="Empower" type="Node" parent="StateChart/Root"]
script = ExtResource("26_infe6")
initial_state = NodePath("Off")
[node name="Off" type="Node" parent="StateChart/Root/Empower"]
script = ExtResource("27_34snm")
[node name="ToOn" type="Node" parent="StateChart/Root/Empower/Off"]
script = ExtResource("28_n7qhm")
to = NodePath("../../On")
event = &"empower_down"
delay_in_seconds = "0.0"
[node name="On" type="Node" parent="StateChart/Root/Empower"]
script = ExtResource("27_34snm")
[node name="ToOff" type="Node" parent="StateChart/Root/Empower/On"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Off")
event = &"empower_released"
delay_in_seconds = "0.0"
[node name="PowerReserve" type="Node" parent="StateChart/Root"]
script = ExtResource("26_infe6")
initial_state = NodePath("Full")
@@ -498,49 +489,55 @@ to = NodePath("../../Grounded")
event = &"grounded"
delay_in_seconds = "0.0"
[node name="OnMantleOtherSide" type="Node" parent="StateChart/Root/Movement/Mantling"]
script = ExtResource("28_n7qhm")
to = NodePath("../../OnWall/Hugging")
event = &"on_wall"
delay_in_seconds = "0.0"
[node name="Jump" type="Node" parent="StateChart/Root/Movement"]
script = ExtResource("26_infe6")
initial_state = NodePath("SimpleJump")
[node name="OnMantle" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Mantling")
event = &"mantle"
delay_in_seconds = "0.0"
[node name="SimpleJump" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("27_34snm")
[node name="OnMegajump" type="Node" parent="StateChart/Root/Movement/Jump/SimpleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../MegaJump")
event = &"megajump"
delay_in_seconds = "0.0"
[node name="OnJumpEnded" type="Node" parent="StateChart/Root/Movement/Jump/SimpleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Airborne/DoubleJumpEnabled")
event = &"jump_ended"
delay_in_seconds = "0.0"
[node name="DoubleJump" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("27_34snm")
[node name="OnMegajump" type="Node" parent="StateChart/Root/Movement/Jump/DoubleJump"]
[node name="OnMegajump" type="Node" parent="StateChart/Root/Movement/Jump/SimpleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../MegaJump")
event = &"megajump"
delay_in_seconds = "0.0"
[node name="DoubleJump" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("27_34snm")
[node name="OnJumpEnded" type="Node" parent="StateChart/Root/Movement/Jump/DoubleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Airborne/Falling")
event = &"jump_ended"
delay_in_seconds = "0.0"
[node name="OnMegajump" type="Node" parent="StateChart/Root/Movement/Jump/DoubleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../MegaJump")
event = &"megajump"
delay_in_seconds = "0.0"
[node name="MegaJump" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("27_34snm")
[node name="OnJumpEnded" type="Node" parent="StateChart/Root/Movement/Jump/MegaJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Airborne/Falling")
event = &"jump_ended"
delay_in_seconds = "0.0"
[node name="Dashing" type="Node" parent="StateChart/Root/Movement"]
script = ExtResource("26_infe6")
initial_state = NodePath("Dash")
@@ -606,7 +603,7 @@ default_state = NodePath("../CoyoteEnabled")
[node name="OnWallRun" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("28_n7qhm")
to = NodePath("../../OnWall/RunningCoyoteEnabled")
to = NodePath("../../OnWall/Running")
event = &"wall_run"
delay_in_seconds = "0.0"
@@ -648,7 +645,6 @@ script = ExtResource("27_34snm")
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/DoubleJumpEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../OnWall/HuggingCoyoteEnabled")
event = &"wall_hug"
delay_in_seconds = "0.0"
@@ -669,7 +665,7 @@ script = ExtResource("27_34snm")
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../OnWall/HuggingCoyoteEnabled")
to = NodePath("../../../OnWall/Hugging")
event = &"wall_hug"
delay_in_seconds = "0.0"
@@ -683,12 +679,6 @@ delay_in_seconds = "0.0"
script = ExtResource("26_infe6")
initial_state = NodePath("Hugging")
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Dashing/Dash")
event = &"dash"
delay_in_seconds = "0.0"
[node name="OnGrounded" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Grounded")
@@ -707,78 +697,61 @@ to = NodePath("../../Airborne/Reset")
event = &"start_falling"
delay_in_seconds = "0.0"
[node name="HuggingCoyoteEnabled" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("27_34snm")
[node name="OnExpiration" type="Node" parent="StateChart/Root/Movement/OnWall/HuggingCoyoteEnabled"]
[node name="OnMantle" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Hugging")
event = &"coyote_expired"
to = NodePath("../../Mantling")
event = &"mantle"
delay_in_seconds = "0.0"
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/HuggingCoyoteEnabled"]
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/DoubleJump")
to = NodePath("../../Jump/DoubleJump")
event = &"jump"
delay_in_seconds = "0.0"
[node name="Hugging" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/Hugging"]
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/OnWall/Hugging"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
event = &"jump"
to = NodePath("../../../Dashing/Dash")
event = &"dash"
delay_in_seconds = "0.0"
[node name="Hanging" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/Hanging"]
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/OnWall/Hanging"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
event = &"jump"
delay_in_seconds = "0.0"
[node name="RunningCoyoteEnabled" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/RunningCoyoteEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/DoubleJump")
event = &"jump"
delay_in_seconds = "0.0"
[node name="OnExpiration" type="Node" parent="StateChart/Root/Movement/OnWall/RunningCoyoteEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Running")
event = &"coyote_expired"
to = NodePath("../../../Dashing/Dash")
event = &"dash"
delay_in_seconds = "0.0"
[node name="Running" type="Node" parent="StateChart/Root/Movement/OnWall"]
script = ExtResource("27_34snm")
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/Running"]
[node name="OnLeaveWall" type="Node" parent="StateChart/Root/Movement/OnWall/Running"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
event = &"jump"
to = NodePath("../../../Airborne/CoyoteEnabled")
event = &"start_falling"
delay_in_seconds = "0.0"
[connection signal="input_aim_canceled" from="InputController" to="." method="OnInputAimCanceled"]
[connection signal="input_aim_down" from="InputController" to="." method="OnInputAimDown"]
[connection signal="input_aim_pressed" from="InputController" to="." method="OnInputAimPressed"]
[connection signal="input_aim_released" from="InputController" to="." method="OnInputAimReleased"]
[connection signal="input_dash" from="InputController" to="." method="OnInputDashPressed"]
[connection signal="input_device_changed" from="InputController" to="." method="InputDeviceChanged"]
[connection signal="input_empower_down" from="InputController" to="." method="OnInputEmpowerDown"]
[connection signal="input_empower_released" from="InputController" to="." method="OnInputEmpowerReleased"]
[connection signal="input_hit" from="InputController" to="." method="OnInputHitPressed"]
[connection signal="input_jump_ended" from="InputController" to="." method="OnInputJumpEnded"]
[connection signal="input_jump_ongoing" from="InputController" to="." method="OnInputJumpOngoing"]
[connection signal="input_jump_started" from="InputController" to="." method="OnInputJumpStarted"]
[connection signal="input_move" from="InputController" to="." method="OnInputMove"]
[connection signal="input_move_keyboard" from="InputController" to="." method="OnInputMoveKeyboard"]
[connection signal="input_parry" from="InputController" to="." method="OnInputParryPressed"]
[connection signal="input_rotate_floorplane" from="InputController" to="." method="OnInputRotateFloorplane"]
[connection signal="input_rotate_y" from="InputController" to="." method="OnInputRotateY"]
[connection signal="input_throw" from="InputController" to="." method="OnInputThrowPressed"]
[connection signal="input_slam" from="InputController" to="." method="OnInputSlamPressed"]
[connection signal="input_slide_ended" from="InputController" to="." method="OnInputSlideEnded"]
[connection signal="input_slide_ongoing" from="InputController" to="." method="OnInputSlideOngoing"]
[connection signal="input_slide_started" from="InputController" to="." method="OnInputSlideStarted"]
[connection signal="WallDetected" from="WallHugSystem" to="." method="OnWallDetected"]

View File

@@ -16,6 +16,16 @@ public partial class PlayerController : CharacterBody3D
}
private bool _isUsingGamepad;
public enum BufferedActions
{
None,
Jump,
MantleJump,
Dash,
MantleDash
}
private BufferedActions _bufferedAction = BufferedActions.None;
// User API to important child nodes.
public HeadSystem HeadSystem;
public Bobbing Bobbing;
@@ -34,6 +44,7 @@ public partial class PlayerController : CharacterBody3D
public MeshInstance3D DashIndicatorMesh;
public CylinderMesh DashIndicatorMeshCylinder;
public RayCast3D WallRunSnapper;
public ShapeCast3D GroundDetector;
private bool _movementEnabled = true;
@@ -58,6 +69,7 @@ public partial class PlayerController : CharacterBody3D
// Timers
private Timer _timeScaleAimInAirTimer;
private Timer _simpleDashCooldownTimer;
private Timer _airborneDashCooldownTimer;
private Timer _powerCooldownTimer;
[Export] public Marker3D TutorialWeaponTarget;
@@ -78,14 +90,25 @@ public partial class PlayerController : CharacterBody3D
public float DecelerationAir = 1.0f;
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float Weight { get; set; } = 3.0f;
// Mantle
[ExportGroup("Mantle")]
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float MantleTime { get; set; } = 0.1f;
[Export]
public PackedScene MantlePath { get; set; }
[Export(PropertyHint.Range, "0,50,0.1")]
public float MantleDashStrength { get; set; } = 15f;
[Export(PropertyHint.Range, "0,100,1,or_greater")]
public float MantleJumpStartVelocity { get; set; } = 20.0f;
// Jump
[ExportGroup("Jump")]
[Export(PropertyHint.Range, "0,1,0.01")]
public float CoyoteTime { get; set; } = 0.2f;
[Export(PropertyHint.Range, "0,10,1,or_greater")]
public int InputBufferFrames { get; set; } = 3;
// Simple jump
[ExportSubgroup("Simple jump")]
@@ -106,22 +129,10 @@ public partial class PlayerController : CharacterBody3D
[Export(PropertyHint.Range, "1,10,0.1,or_greater")]
public float DoubleJumpGravityLesseningFactor { get; set; } = 3f;
// Mega jump
[ExportSubgroup("Mega jump")]
[Export(PropertyHint.Range, "0,100,1,or_greater")]
public float MegaJumpStartVelocity { get; set; } = 10.0f;
[Export(PropertyHint.Range, "0,10,1,or_greater")]
public int MegaJumpHangTimeInFrames { get; set; } = 5;
[Export(PropertyHint.Range, "1,10,0.1,or_greater")]
public float MegaJumpGravityLesseningFactor { get; set; } = 3f;
// Wall jump
[ExportSubgroup("Wall jump")]
[Export(PropertyHint.Range, "0,100,1,or_greater")]
public float WallJumpStartVelocity { get; set; } = 10.0f;
[Export(PropertyHint.Range, "0,100,1,or_greater")]
public float WallMegajumpStartVelocity { get; set; } = 20.0f;
// Dash
[ExportGroup("Dash")]
@@ -131,12 +142,6 @@ public partial class PlayerController : CharacterBody3D
[ExportSubgroup("Simple")]
[Export(PropertyHint.Range, "0,50,0.1")]
public float SimpleDashStrength { get; set; } = 10f;
// Powered Dash
[ExportSubgroup("Powered")]
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float PoweredDashTime { get; set; } = 0.3f;
[Export(PropertyHint.Range, "0,100,0.1")]
public float PoweredDashStrength { get; set; } = 10f;
// Aimed Dash
[ExportSubgroup("Special")]
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
@@ -186,10 +191,14 @@ public partial class PlayerController : CharacterBody3D
private bool _canDash = true;
private bool _shouldMantleOnDashEnded;
private Vector3 _wallHugStartLocation = Vector3.Zero;
private Vector3 _wallHugStartNormal = Vector3.Zero;
private Vector3 _wallHugStartProjectedVelocity = Vector3.Zero;
private Vector3 _currentWallContactPoint = Vector3.Zero;
private StateChart _playerState;
private StateChartState _aiming;
private StateChartState _empowerOn;
private StateChartState _powerExpired;
private StateChartState _powerRecharging;
private StateChartState _powerFull;
@@ -197,30 +206,24 @@ public partial class PlayerController : CharacterBody3D
private StateChartState _grounded;
private StateChartState _airborne;
private StateChartState _coyoteEnabled;
private StateChartState _doubleJumpEnabled;
private StateChartState _simpleJump;
private StateChartState _doubleJump;
private StateChartState _megaJump;
private StateChartState _mantling;
private StateChartState _simpleDash;
private StateChartState _poweredDash;
private StateChartState _aimedDash;
private StateChartState _onWall;
private StateChartState _onWallHugging;
private StateChartState _onWallHuggingCoyoteEnabled;
private StateChartState _onWallHanging;
private StateChartState _onWallRunning;
private StateChartState _onWallRunningCoyoteEnabled;
private Transition _onJumpFromWallCoyote;
private Transition _onJumpFromWallRunCoyote;
private Transition _onJumpFromWall1;
private Transition _onJumpFromWall2;
private Transition _onJumpFromWall3;
private Transition _onMegajumpFromWall;
private Transition _onJumpFromWall;
private Transition _onLeaveWallFromRun;
private int _currentInputBufferFrames;
private float _playerHeight;
private float _playerRadius;
private bool _isJumpInputPressed;
private float _lookSensitivityMultiplier = 1.0f;
private float _mouseSensitivityMultiplier = 1.0f;
@@ -265,6 +268,7 @@ public partial class PlayerController : CharacterBody3D
StairsSystem = GetNode<StairsSystem>("StairsSystem");
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
GroundDetector = GetNode<ShapeCast3D>("GroundDetector");
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
_headCollisionDetectors = new RayCast3D[NUM_OF_HEAD_COLLISION_DETECTORS];
@@ -283,10 +287,8 @@ public partial class PlayerController : CharacterBody3D
_aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On"));
_simpleDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/Dash"));
_poweredDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/PoweredDash"));
_aimedDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/AimedDash"));
// _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging"));
_empowerOn = StateChartState.Of(GetNode("StateChart/Root/Empower/On"));
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
_powerRecharging = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/AtLeastOneCharge"));
_powerFull = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Full"));
@@ -294,27 +296,21 @@ public partial class PlayerController : CharacterBody3D
_grounded = StateChartState.Of(GetNode("StateChart/Root/Movement/Grounded"));
_airborne = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne"));
_coyoteEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/CoyoteEnabled"));
_doubleJumpEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/DoubleJumpEnabled"));
// _doubleJumpEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/DoubleJumpEnabled"));
_simpleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/SimpleJump"));
_doubleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/DoubleJump"));
_megaJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/MegaJump"));
_mantling = StateChartState.Of(GetNode("StateChart/Root/Movement/Mantling"));
_onJumpFromWallCoyote = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/HuggingCoyoteEnabled/OnJump"));
_onJumpFromWallRunCoyote = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/RunningCoyoteEnabled/OnJump"));
_onJumpFromWall1 = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Hugging/OnJump"));
_onJumpFromWall2 = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging/OnJump"));
_onJumpFromWall3 = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnJump"));
_onMegajumpFromWall = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/OnMegajump"));
_onJumpFromWall = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/OnJump"));
_onWall = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall"));
_onWallHuggingCoyoteEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/HuggingCoyoteEnabled"));
_onWallHugging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hugging"));
_onWallHanging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging"));
_onWallRunning = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Running"));
_onWallRunningCoyoteEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/RunningCoyoteEnabled"));
_onLeaveWallFromRun = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnLeaveWall"));
// State timers
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
_simpleDashCooldownTimer = GetNode<Timer>("DashCooldown");
_airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown");
///////////////////////////
// Initialize components //
@@ -351,6 +347,7 @@ public partial class PlayerController : CharacterBody3D
_grounded.StateEntered += OnGrounded;
_grounded.StatePhysicsProcessing += HandleGrounded;
_airborne.StatePhysicsProcessing += HandleAirborne;
_onWall.StatePhysicsProcessing += HandleOnWall;
_coyoteEnabled.StateEntered += StartCoyoteTime;
_timeScaleAimInAirTimer.Timeout += ResetTimeScale;
@@ -368,42 +365,28 @@ public partial class PlayerController : CharacterBody3D
_doubleJump.StateEntered += OnDoubleJumpStarted;
_doubleJump.StatePhysicsProcessing += HandleDoubleJump;
_megaJump.StateEntered += OnMegaJumpStarted;
_megaJump.StatePhysicsProcessing += HandleMegaJump;
_mantling.StateEntered += OnMantleStarted;
_mantling.StatePhysicsProcessing += HandleMantling;
_simpleDash.StateEntered += OnSimpleDashStarted;
_simpleDash.StatePhysicsProcessing += HandleSimpleDash;
_poweredDash.StateEntered += OnPoweredDashStarted;
_poweredDash.StatePhysicsProcessing += HandlePoweredDash;
_poweredDash.StateExited += OnPoweredDashFinished;
_aimedDash.StateEntered += OnAimedDashStarted;
_aimedDash.StateExited += OnAimedDashFinished;
_simpleDashCooldownTimer.Timeout += DashCooldownTimeout;
_airborneDashCooldownTimer.Timeout += AirborneDashCooldownTimeout;
_onWall.StateEntered += OnWallStarted;
_onWall.StateExited += OnWallStopped;
_onWallHuggingCoyoteEnabled.StateEntered += OnWallHuggingStarted;
_onWallHuggingCoyoteEnabled.StatePhysicsProcessing += HandleWallHugging;
_onWallHugging.StatePhysicsProcessing += HandleWallHugging;
_onWallHanging.StatePhysicsProcessing += HandleWallHanging;
_onWallRunningCoyoteEnabled.StateEntered += OnWallRunningStarted;
_onWallRunningCoyoteEnabled.StatePhysicsProcessing += HandleWallRunning;
_onWallRunning.StatePhysicsProcessing += HandleWallRunning;
_onJumpFromWallCoyote.Taken += OnJumpFromWallCoyote;
_onJumpFromWallRunCoyote.Taken += OnJumpFromWallCoyote;
_onJumpFromWall1.Taken += OnJumpFromWall;
_onJumpFromWall2.Taken += OnJumpFromWall;
_onJumpFromWall3.Taken += OnJumpFromWall;
_onMegajumpFromWall.Taken += OnMegajumpFromWall;
_onJumpFromWall.Taken += OnJumpFromWall;
_onLeaveWallFromRun.Taken += OnLeaveWallFromRun;
}
public void SetAllowedInputsAll()
{
CurrentlyAllowedInputs = AllowedInputs.All;
@@ -448,28 +431,72 @@ public partial class PlayerController : CharacterBody3D
if (_simpleDashCooldownTimer.IsStopped())
_simpleDashCooldownTimer.Start();
if (_bufferedAction == BufferedActions.Jump && _currentInputBufferFrames > 0)
{
_currentInputBufferFrames = 0;
PerformJump();
}
if (_bufferedAction == BufferedActions.Dash && _currentInputBufferFrames > 0)
{
_currentInputBufferFrames = 0;
SimpleDash();
}
if (_bufferedAction == BufferedActions.MantleJump)
{
SimpleDash();
OnJumpStarted(MantleJumpStartVelocity);
}
if (_bufferedAction == BufferedActions.MantleDash)
{
SimpleDash(MantleDashStrength);
}
_bufferedAction = BufferedActions.None;
}
public void DashCooldownTimeout()
{
_canDash = true;
}
public void AirborneDashCooldownTimeout()
{
_canDashAirborne = true;
}
public bool IsPlayerInputtingForward()
{
return GetMoveInput().Z < -0.5f;
}
public bool IsTryingToMantle()
{
return MantleSystem.IsMantlePossible && IsPlayerInputtingForward() && _isJumpInputPressed;
}
public void HandleGrounded(float delta)
{
MoveOnGround(delta);
// if (IsTryingToMantle()) _playerState.SendEvent("mantle");
if (!isOnFloorCustom())
_playerState.SendEvent("start_falling");
}
public void HandleAirborne(float delta)
{
MoveInAir(delta);
var isGroundLike = GroundDetector.GetCollisionResult().Count > 0;
MoveInAir(delta, isGroundLike);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
if (IsTryingToMantle()) _playerState.SendEvent("mantle");
if (!WallHugSystem.IsWallHugging())
{
_isWallJumpAvailable = true; // reset wall jump if we left the wall
return;
}
// Going upwards, we stay simply airborne
if (Velocity.AngleTo(Vector3.Up) < Math.PI / 4)
@@ -497,29 +524,18 @@ public partial class PlayerController : CharacterBody3D
}
}
public void OnWallHuggingStarted()
public void HandleOnWall(float delta)
{
GetTree().CreateTimer(CoyoteTime).Timeout += CoyoteExpired;
if (IsTryingToMantle()) _playerState.SendEvent("mantle");
}
public void OnWallRunningStarted()
{
GetTree().CreateTimer(CoyoteTime).Timeout += CoyoteExpired;
}
private Vector3 _wallHugStartLocation = Vector3.Zero;
private Vector3 _wallHugStartNormal = Vector3.Zero;
private Vector3 _wallHugStartProjectedVelocity = Vector3.Zero;
private Vector3 _currentWallContactPoint = Vector3.Zero;
public void OnWallDetected()
{
FinishPoweredDash();
if (!_onWall.Active)
return;
var newWallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
if (newWallNormal.AngleTo(_wallHugStartNormal) > Mathf.Pi/4) return;
_wallHugStartNormal = newWallNormal;
}
@@ -537,9 +553,17 @@ public partial class PlayerController : CharacterBody3D
public void OnWallStopped()
{
}
public void OnLeaveWallFromRun()
{
SimpleDashInDirection(Velocity.Normalized());
}
public void HandleWallHugging(float delta)
{
_canDash = true;
_canDashAirborne = true;
WallHug(delta);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
@@ -555,6 +579,9 @@ public partial class PlayerController : CharacterBody3D
public void HandleWallRunning(float delta)
{
_canDash = false;
_canDashAirborne = false;
// Find horizontal velocity projected on the current wall
var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
var hvelProjected = hvel.Slide(_wallHugStartNormal);
@@ -565,16 +592,14 @@ public partial class PlayerController : CharacterBody3D
// Adapt vertical speed
var verticalSpeed = Velocity.Y - WallRunAltitudeLossSpeed * delta;
Velocity = finalHVel + Vector3.Up*verticalSpeed;
Velocity *= 0.995f;
Velocity *= 0.999f;
_currentWallContactPoint = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
if (!WallHugSystem.IsWallHugging() || Velocity.Length() < WallRunSpeedThreshold)
{
if (!WallHugSystem.IsWallHugging())
_playerState.SendEvent("start_falling");
}
}
public void WallHug(float delta)
@@ -591,9 +616,18 @@ public partial class PlayerController : CharacterBody3D
Velocity = Vector3.Zero;
GlobalPosition = _wallHugStartLocation;
}
// Jump
public void OnInputJumpStarted()
{
_currentInputBufferFrames = InputBufferFrames;
_bufferedAction = _mantling.Active ? BufferedActions.MantleJump : BufferedActions.Jump;
_isJumpInputPressed = true;
PerformJump();
}
public void PerformJump()
{
if (MantleSystem.IsMantlePossible)
{
@@ -601,25 +635,21 @@ public partial class PlayerController : CharacterBody3D
return;
}
if (_empowerOn.Active && CanPerformEmpoweredAction())
{
_playerState.SendEvent("megajump");
return;
}
if (_onWallHuggingCoyoteEnabled.Active || _onWallRunningCoyoteEnabled.Active)
{
if (!_isWallJumpAvailable) return;
}
_playerState.SendEvent("jump");
}
public bool IsFacingWall()
{
return _wallHugStartNormal.Dot(GetGlobalForwardFacingVector()) < -0.5f;
}
public void OnInputJumpOngoing()
{
}
public void OnInputJumpEnded()
{
_isJumpInputPressed = false;
_playerState.SendEvent("jump_ended");
}
@@ -635,14 +665,9 @@ public partial class PlayerController : CharacterBody3D
public void OnDoubleJumpStarted()
{
_canDash = true;
_canDashAirborne = true;
// _canDashAirborne = true;
OnJumpStarted(DoubleJumpStartVelocity);
}
public void OnMegaJumpStarted()
{
PerformEmpoweredAction();
OnJumpStarted(MegaJumpStartVelocity);
}
public void ComputeJumpFromWallHSpeed(float jumpStrength)
{
@@ -659,19 +684,27 @@ public partial class PlayerController : CharacterBody3D
SetHorizontalVelocity(currentHorizontalVelocity + wallJumpHorizontalVelocity);
}
public void OnJumpFromWallCoyote()
{
_isWallJumpAvailable = false;
}
public void OnJumpFromWall()
{
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
if (!IsFacingWall() || (!_isWallJumpAvailable && IsFacingWall()))
{
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
}
// Remove the ability to dash straight away so you cannot scale up the wall
_canDashAirborne = false;
_airborneDashCooldownTimer.Start();
_isWallJumpAvailable = false;
}
public void OnMegajumpFromWall()
public void OnInputSlideStarted()
{
}
public void OnInputSlideOngoing()
{
}
public void OnInputSlideEnded()
{
ComputeJumpFromWallHSpeed(WallMegajumpStartVelocity);
}
public void InputDeviceChanged(bool isUsingGamepad)
@@ -725,38 +758,85 @@ public partial class PlayerController : CharacterBody3D
z: velocity.Y);
}
private Path _mantlePath;
private bool _customMantle;
private Transform3D _customMantleStartTransform;
private Curve3D _customMantleCurve;
private Vector3 _mantleStartPosition;
private Vector3 _velocityOnMantleStarted = Vector3.Zero;
private bool _mantleEndedOnOtherSideOfWall;
private bool _mantleFoundGround;
public void OnMantleStarted()
{
HeadSystem.OnMantle();
_preMantleVelocity = Velocity;
var tween = GetTree().CreateTween();
tween.SetTrans(Tween.TransitionType.Cubic);
tween.SetEase(Tween.EaseType.InOut);
var inbetweenDuration = MantleTime / MantleSystem.NumberOfValidPofiles;
for (int i = 0; i < MantleSystem.NumberOfValidPofiles; i += 1)
_mantlePath = MantlePath.Instantiate() as Path;
if (_mantlePath == null)
{
var position = MantleSystem.WallProfilePositions[i];
tween.TweenProperty(this, "global_position", position, inbetweenDuration);
GD.PrintErr("Failed to instantiate MantlePath");
return;
}
_velocityOnMantleStarted = Velocity;
var transform = _customMantle ? _customMantleStartTransform : MantleSystem.GlobalTransform;
var curve = _customMantle ? _customMantleCurve : MantleSystem.MantleCurve;
_mantleEndedOnOtherSideOfWall = _customMantle ? _mantleEndedOnOtherSideOfWall : MantleSystem.EndedOnOtherSideOfWall;
_mantleFoundGround = _customMantle ? _mantleFoundGround : MantleSystem.FoundGround;
GetTree().GetRoot().AddChild(_mantlePath);
_mantlePath.Setup(transform, curve);
_mantleStartPosition = GlobalPosition;
var curveLength = curve.GetBakedLength();
var tween = GetTree().CreateTween();
tween.SetTrans(Tween.TransitionType.Linear);
tween.SetEase(Tween.EaseType.In);
tween.TweenProperty(_mantlePath.PathFollow, "progress_ratio", 1, MantleTime*curveLength);
tween.Finished += MantleFinished;
}
public void HandleMantling(float delta)
{
GlobalPosition = _mantlePath.Target.GlobalPosition;
}
public void SimpleDashInDirection(Vector3 direction, float strength = -1)
{
if (strength < 0) strength = SimpleDashStrength;
SetVelocity(direction * strength);
}
public void SimpleDash(float strength = -1)
{
SimpleDashInDirection(GetInputGlobalHDirection(), strength);
}
public void MantleFinished()
{
Velocity = _preMantleVelocity;
_mantlePath.Teardown();
// SetVelocity(_finalCurveDirection.Normalized() * _speedOverCurve);
var isThereMovementInput = GetMoveInput().Length() > 0;
if (isThereMovementInput)
{
// If there's a movement input on Mantle, we dash in the direction the mantle ended with
var positionDifference = GlobalPosition - _mantleStartPosition;
var directionHorizontal = new Vector3(positionDifference.X, 0, positionDifference.Z);
// SimpleDashInDirection(directionHorizontal.Normalized());
SetVelocity(directionHorizontal.Normalized() * WalkSpeed);
}
_customMantle = false;
_playerState.SendEvent("grounded");
}
public void HandleJump(float delta, float gravityFactor, int hangFrames)
{
if (IsTryingToMantle()) _playerState.SendEvent("mantle");
// Update horizontal velocity
var horizontalVelocity = ComputeHVelocityAir(delta);
Velocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z);
@@ -783,8 +863,8 @@ public partial class PlayerController : CharacterBody3D
SetVerticalVelocity(Velocity.Y - 2.0f);
}
// Move back to Airborne state management when starting to go down again
if (_framesSinceJumpAtApex > hangFrames)
// Move back to Airborne state when starting to go down again or if input isn't held anymore (buffered jump)
if (_framesSinceJumpAtApex > hangFrames || !_isJumpInputPressed)
_playerState.SendEvent("jump_ended");
}
public void HandleSimpleJump(float delta)
@@ -795,10 +875,6 @@ public partial class PlayerController : CharacterBody3D
{
HandleJump(delta, DoubleJumpGravityLesseningFactor, DoubleJumpHangTimeInFrames);
}
public void HandleMegaJump(float delta)
{
HandleJump(delta, MegaJumpGravityLesseningFactor, MegaJumpHangTimeInFrames);
}
public void PowerRecharging(float delta)
{
@@ -867,14 +943,6 @@ public partial class PlayerController : CharacterBody3D
ThrowWeapon();
}
}
public void OnInputEmpowerDown()
{
// _playerState.SendEvent("empower_down");
}
public void OnInputEmpowerReleased()
{
// _playerState.SendEvent("empower_released");
}
public void OnInputDashPressed()
{
if (_aiming.Active && CanPerformEmpoweredAction())
@@ -884,12 +952,6 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("cancel_aim");
return;
}
if (_empowerOn.Active && CanPerformEmpoweredAction())
{
PerformEmpoweredAction();
_playerState.SendEvent("powered_dash");
return;
}
if (_airborne.Active)
{
@@ -897,14 +959,19 @@ public partial class PlayerController : CharacterBody3D
return;
_canDashAirborne = false;
}
_currentInputBufferFrames = InputBufferFrames;
_bufferedAction = _mantling.Active ? BufferedActions.MantleDash : BufferedActions.Dash;
_playerState.SendEvent("dash");
}
public void OnAimingEntered()
public void OnInputSlamPressed()
{
GD.Print("Slam pressed");
}
public void OnInputParryPressed()
{
if (!CanPerformEmpoweredAction())
return;
if (WeaponSystem.FlyingState.Active)
{
DashToFlyingWeapon();
@@ -916,10 +983,14 @@ public partial class PlayerController : CharacterBody3D
DashToPlantedWeapon();
return;
}
}
public void OnAimingEntered()
{
if (!CanPerformEmpoweredAction())
return;
DashSystem.StartPreparingDash();
DashIndicatorMesh.Visible = true;
if (!isOnFloorCustom())
ReduceTimeScaleWhileAiming();
}
@@ -986,9 +1057,7 @@ public partial class PlayerController : CharacterBody3D
public void RecoverWeapon()
{
GetTree().GetRoot().RemoveChild(WeaponRoot);
AddChild(WeaponRoot);
WeaponRoot.SetGlobalPosition(GlobalPosition);
RecoverChildNode(WeaponRoot);
WeaponSystem.ResetWeapon();
}
@@ -1006,7 +1075,6 @@ public partial class PlayerController : CharacterBody3D
}
private Vector3 _preDashVelocity = Vector3.Zero;
public void OnAimedDashStarted()
{
// Adjusting for player height, where the middle of the capsule should get to the dash location instead of the
@@ -1020,9 +1088,12 @@ public partial class PlayerController : CharacterBody3D
var dashTween = CreatePositionTween(correctedLocation, AimedDashTime);
// dashTween.TweenMethod(Callable.From<float>(AimedDashTweenOngoing), 0.0f, 1.0f, AimedDashTime);
dashTween.Finished += AimedDashTweenEnded;
_shouldMantleOnDashEnded = DashSystem.ShouldMantle;
_mantleLocation = DashSystem.PlannedMantleLocation;
_customMantle = DashSystem.ShouldMantle;
_customMantleCurve = DashSystem.MantleSystem.MantleCurve;
_customMantleStartTransform = DashSystem.MantleSystem.GlobalTransform;
_mantleEndedOnOtherSideOfWall = DashSystem.MantleSystem.EndedOnOtherSideOfWall;
_mantleFoundGround = DashSystem.MantleSystem.FoundGround;
}
Tween CreatePositionTween(Vector3 targetLocation, float tweenTime)
@@ -1041,6 +1112,13 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("dash_finished");
}
public void OnAimedDashFinished()
{
var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? PostDashSpeed : _preDashVelocity.Length();
Velocity = _dashDirection * postDashVelocity;
if (_customMantle) _playerState.SendEvent("mantle");
}
public void PlaceWeaponForTutorial()
{
if (TutorialDone)
@@ -1051,14 +1129,25 @@ public partial class PlayerController : CharacterBody3D
WeaponRoot.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition);
WeaponSystem.CallDeferred(WeaponSystem.MethodName.PlaceWeaponForTutorial, TutorialWeaponTarget.GlobalPosition);
}
public void RemoveChildNode(Node3D node)
{
RemoveChild(node);
GetTree().GetRoot().AddChild(node);
node.SetGlobalPosition(GlobalPosition);
}
public void RecoverChildNode(Node3D node)
{
GetTree().GetRoot().RemoveChild(node);
AddChild(node);
node.SetGlobalPosition(GlobalPosition);
}
public void ThrowWeapon()
{
_playerState.SendEvent("cancel_aim");
RemoveChild(WeaponRoot);
GetTree().GetRoot().AddChild(WeaponRoot);
WeaponRoot.SetGlobalPosition(GlobalPosition);
RemoveChildNode(WeaponRoot);
var weaponTargetLocation = DashSystem.HasHit ? DashSystem.CollisionPoint : DashSystem.PlannedLocation;
WeaponSystem.ThrowWeapon(
@@ -1068,29 +1157,12 @@ public partial class PlayerController : CharacterBody3D
DashSystem.CollisionNormal);
}
public void OnAimedDashFinished()
{
var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? PostDashSpeed : _preDashVelocity.Length();
Velocity = _dashDirection * postDashVelocity;
if (_shouldMantleOnDashEnded)
{
// TODO update post dash mantle
// MantleToLocation(_mantleLocation);
GD.Print("update post dash mantle");
}
}
public void OnSimpleDashStarted()
{
if (!_canDash)
return;
_canDash = false;
var dashStrength = SimpleDashStrength;
var direction = GetInputGlobalHDirection();
SetVelocity(direction * dashStrength);
SimpleDash();
}
public void HandleSimpleDash(float delta)
@@ -1109,31 +1181,7 @@ public partial class PlayerController : CharacterBody3D
var direction = GetMoveInput();
return new Vector3(direction.X, 0, direction.Z).Normalized();
}
public void OnPoweredDashStarted()
{
Velocity = GetInputGlobalHDirection() * PoweredDashStrength;
GetTree().CreateTimer(PoweredDashTime).Timeout += FinishPoweredDash;
}
public void OnPoweredDashFinished()
{
}
public void FinishPoweredDash()
{
_playerState.SendEvent("dash_finished");
}
public void HandlePoweredDash(float delta)
{
var collision = MoveAndCollide(Velocity * delta, maxCollisions: 10);
if (collision != null)
{
FinishPoweredDash();
}
}
public bool CanPerformEmpoweredAction()
{
return EmpoweredActionsLeft > 0 && TutorialDone;
@@ -1163,7 +1211,7 @@ public partial class PlayerController : CharacterBody3D
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
var lookSensitivity = _isUsingGamepad ? _lookSensitivityMultiplier : _mouseSensitivityMultiplier;
var wallHugContactPoint = _onWallRunning.Active || _onWallRunningCoyoteEnabled.Active ? _currentWallContactPoint : Vector3.Zero;
var wallHugContactPoint = _onWallRunning.Active ? _currentWallContactPoint : Vector3.Zero;
var playerVelocity = GetGlobalMoveInput();
HeadSystem.LookAround(delta, inputLookDir, playerVelocity, wallHugContactPoint, lookSensitivity);
}
@@ -1174,9 +1222,9 @@ public partial class PlayerController : CharacterBody3D
Velocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z);
}
public void MoveInAir(double delta)
public void MoveInAir(double delta, bool isGroundLike = false)
{
var horizontalVelocity = ComputeHVelocityAir((float) delta);
var horizontalVelocity = isGroundLike ? ComputeHVelocityGround((float) delta) : ComputeHVelocityAir((float) delta);
var verticalVelocity = Velocity.Y - (CalculateGravityForce() * (float)delta);
Velocity = new Vector3(horizontalVelocity.X, verticalVelocity, horizontalVelocity.Z);
}
@@ -1243,7 +1291,7 @@ public partial class PlayerController : CharacterBody3D
Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams
{
Delta = delta,
IsOnFloorCustom = isOnFloorCustom() || _onWallRunning.Active || _onWallRunningCoyoteEnabled.Active,
IsOnFloorCustom = isOnFloorCustom() || _onWallRunning.Active,
Velocity = Velocity,
SettingsMultiplier = _headBobbingMultiplier
};
@@ -1298,17 +1346,23 @@ public partial class PlayerController : CharacterBody3D
{
WeaponRoot.SetRotation(HeadSystem.Rotation);
}
public Vector3 GetGlobalForwardFacingVector()
{
return Transform.Basis * HeadSystem.Transform.Basis * Vector3.Forward;
}
///////////////////////////
// Processes //////////////
///////////////////////////
public override void _PhysicsProcess(double delta)
{
if (_currentInputBufferFrames > 0) _currentInputBufferFrames -= 1;
LookAround(delta);
CameraModifications((float) delta);
HandleStairs((float) delta);
MantleSystem.ProcessMantle(_grounded.Active);
if (WeaponSystem.InHandState.Active)
RotateWeaponWithPlayer();

View File

@@ -161,5 +161,6 @@ common/physics_interpolation=true
[rendering]
textures/vram_compression/import_etc2_astc=true
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=5
environment/volumetric_fog/volume_size=256
environment/volumetric_fog/volume_depth=256

25
scenes/path/Path.cs Normal file
View File

@@ -0,0 +1,25 @@
using Godot;
public partial class Path : Path3D
{
public PathFollow3D PathFollow { get; private set; }
public Marker3D Target { get; private set; }
public override void _Ready()
{
PathFollow = GetNode<PathFollow3D>("PathFollow");
Target = GetNode<Marker3D>("PathFollow/Target");
}
public void Setup(Transform3D globalTransform, Curve3D curve)
{
SetGlobalTransform(globalTransform);
SetCurve(curve);
PathFollow.ProgressRatio = 0;
}
public void Teardown()
{
if (!IsQueuedForDeletion()) QueueFree();
}
}

1
scenes/path/Path.cs.uid Normal file
View File

@@ -0,0 +1 @@
uid://djdr5bvfc8f0x

13
scenes/path/path.tscn Normal file
View File

@@ -0,0 +1,13 @@
[gd_scene load_steps=3 format=3 uid="uid://cf3rrgr1imvv4"]
[ext_resource type="Script" uid="uid://djdr5bvfc8f0x" path="res://scenes/path/Path.cs" id="1_kmlhi"]
[sub_resource type="Curve3D" id="Curve3D_u4rfr"]
[node name="Path" type="Path3D"]
curve = SubResource("Curve3D_u4rfr")
script = ExtResource("1_kmlhi")
[node name="PathFollow" type="PathFollow3D" parent="."]
[node name="Target" type="Marker3D" parent="PathFollow"]

View File

@@ -20,10 +20,10 @@ public partial class DashSystem: Node3D
public bool ShouldMantle { get; set; }
public Vector3 PlannedMantleLocation { get; set; }
public MantleSystem MantleSystem { get; set; }
private Node3D _head;
private ShapeCast3D _dashCast3D;
private ShapeCast3D _playerCast3D;
private Camera3D _camera;
private Vector3 _dashDirection = Vector3.Zero;
@@ -31,7 +31,6 @@ public partial class DashSystem: Node3D
private MeshInstance3D _dashDropIndicator;
private MeshInstance3D _dashDropLocationIndicator;
private MantleSystem _mantleSystem;
private MeshInstance3D _dashTarget;
private CpuParticles3D _dashIndicator;
private AnimationPlayer _dashIndicatorAnim;
@@ -47,9 +46,6 @@ public partial class DashSystem: Node3D
public delegate void DashProgressEventHandler(float progress);
private Vector3 _globalDashPosition = Vector3.Zero;
private float _playerHeight;
private float _playerRadius;
public float DashCastRadius { get; set; }
@@ -65,16 +61,11 @@ public partial class DashSystem: Node3D
_dashDropLocationIndicator = GetNode<MeshInstance3D>("DashDropLocationIndicator");
_dashDropLocationIndicator.Visible = false;
_playerCast3D = GetNode<ShapeCast3D>("PlayerShapeCast3D");
var playerShape = _playerCast3D.GetShape() as CapsuleShape3D;
_playerHeight = playerShape!.Height;
_playerRadius = playerShape!.Radius;
_head = head;
_camera = camera;
_mantleSystem = GetNode<MantleSystem>("MantleSystem");
_mantleSystem.Init();
MantleSystem = GetNode<MantleSystem>("MantleSystem");
MantleSystem.Init();
_dashTarget = GetNode<MeshInstance3D>("DashTarget");
_dashTarget.SetVisible(false);
@@ -109,14 +100,15 @@ public partial class DashSystem: Node3D
(HasHit, PlannedLocation, CollisionPoint, CollisionNormal) = ComputeDashLocation();
ShouldMantle = false;
var mantleLocation = Vector3.Zero;
if (HasHit && Mathf.Abs(CollisionNormal.Y) < 0.5f)
{
var mantleResult = _mantleSystem.FindMantleLocationAtPoint(PlannedLocation, CollisionNormal);
ShouldMantle = mantleResult.IsSome(out mantleLocation);
}
PlannedMantleLocation = mantleLocation;
// TODO: Position mantle system to planned location, aligned with ground planned and facing the same way as the dash
// Then query it being careful when dashing underneath a platform and such
MantleSystem.SetGlobalPosition(PlannedLocation);
MantleSystem.SetRotation(new Vector3(
MantleSystem.Rotation.X,
_head.Rotation.Y,
MantleSystem.Rotation.Z));
MantleSystem.ProcessMantle(false);
ShouldMantle = MantleSystem.IsMantlePossible;
// Setup dash target
var targetColor = HasHit ? new Color(1f, 0.2f, 0.2f) : new Color(1f, 1f, 1f);
@@ -124,7 +116,7 @@ public partial class DashSystem: Node3D
var targetMaterial = (StandardMaterial3D) _dashTarget.GetSurfaceOverrideMaterial(0);
targetMaterial.SetAlbedo(targetColor);
_dashTarget.SetVisible(true);
var targetLocation = ShouldMantle ? PlannedMantleLocation : PlannedLocation;
var targetLocation = ShouldMantle ? MantleSystem.FirstMantleProfilePoint : PlannedLocation;
_dashTarget.SetGlobalPosition(targetLocation);
var shouldShowDropIndicator = !HasHit && !ShouldMantle;
@@ -160,6 +152,5 @@ public partial class DashSystem: Node3D
public void StartPreparingDash()
{
_dashTarget.SetVisible(true);
}
}

View File

@@ -1,7 +1,6 @@
[gd_scene load_steps=10 format=3 uid="uid://cqduhd4opgwvm"]
[gd_scene load_steps=9 format=3 uid="uid://cqduhd4opgwvm"]
[ext_resource type="Script" uid="uid://dwoppk8j5fxeg" path="res://systems/dash/DashSystem.cs" id="1_hwig2"]
[ext_resource type="Shape3D" uid="uid://keseacdcooot" path="res://player_controller/resources/PlayerShape.tres" id="2_jngg2"]
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="2_pff7b"]
[ext_resource type="PackedScene" uid="uid://hd0868f4pb63" path="res://systems/dash/dash_indicator.tscn" id="2_tqt6i"]
@@ -24,16 +23,8 @@ outer_radius = 0.5
script = ExtResource("1_hwig2")
DashIndicatorScene = ExtResource("2_tqt6i")
[node name="PlayerShapeCast3D" type="ShapeCast3D" parent="."]
visible = false
shape = ExtResource("2_jngg2")
target_position = Vector3(0, 0, 0)
collision_mask = 2
debug_shape_custom_color = Color(0.863327, 0.636844, 0, 1)
[node name="DashCast3D" type="ShapeCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
visible = false
shape = SubResource("SphereShape3D_jngg2")
target_position = Vector3(0, 0, -12)
max_results = 1
@@ -42,7 +33,6 @@ debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
[node name="DashCastDrop" type="ShapeCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 1.6, 0)
visible = false
shape = SubResource("SphereShape3D_jngg2")
target_position = Vector3(0, 0, -50)
max_results = 1
@@ -54,7 +44,6 @@ mesh = SubResource("SphereMesh_qu4wy")
surface_material_override/0 = SubResource("StandardMaterial3D_v31n3")
[node name="MantleSystem" parent="." instance=ExtResource("2_pff7b")]
visible = false
MantleEndLocationDistanceFromWall = 0.25
MantleHeightCastStart = 2.0

View File

@@ -1,14 +0,0 @@
[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://7wm8ywvujwf"]
[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_36r6u"]
[resource]
script = ExtResource("1_36r6u")
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"

View File

@@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=155 format=3 uid="uid://bl5crtu1gkrtr"]
[gd_resource type="Resource" script_class="GUIDEMappingContext" load_steps=157 format=3 uid="uid://bl5crtu1gkrtr"]
[ext_resource type="Script" uid="uid://cpplm41b5bt6m" path="res://addons/guide/guide_action_mapping.gd" id="1_qmhk6"]
[ext_resource type="Resource" uid="uid://htqvokm8mufq" path="res://systems/inputs/base_mode/move.tres" id="2_g6bbx"]
@@ -18,22 +18,22 @@
[ext_resource type="Script" uid="uid://b52rqq28tuqpg" path="res://addons/guide/triggers/guide_trigger_pressed.gd" id="15_fykw6"]
[ext_resource type="Script" uid="uid://b4cdrn4paoj3i" path="res://addons/guide/triggers/guide_trigger_down.gd" id="15_g6bbx"]
[ext_resource type="Script" uid="uid://cgy4anjdob2tp" path="res://addons/guide/modifiers/guide_modifier_window_relative.gd" id="15_rvpjj"]
[ext_resource type="Resource" uid="uid://b334rau1yxmm7" path="res://systems/inputs/base_mode/empower_down.tres" id="16_0qat1"]
[ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="16_li5ak"]
[ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://systems/inputs/base_mode/aim_release.tres" id="16_rvpjj"]
[ext_resource type="Script" uid="uid://vgjlx6p007lp" path="res://addons/guide/inputs/guide_input_mouse_button.gd" id="17_kxb2c"]
[ext_resource type="Script" uid="uid://biiggjw6tv4uq" path="res://addons/guide/triggers/guide_trigger_released.gd" id="17_s8kjn"]
[ext_resource type="Resource" uid="uid://7wm8ywvujwf" path="res://systems/inputs/base_mode/aim_cancel.tres" id="18_vibkn"]
[ext_resource type="Resource" uid="uid://bbce5wfwxpns1" path="res://systems/inputs/base_mode/empower_release.tres" id="19_li5ak"]
[ext_resource type="Script" uid="uid://rvttn472ix6v" path="res://addons/guide/inputs/guide_input_joy_button.gd" id="19_qkgmj"]
[ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://systems/inputs/base_mode/jump.tres" id="21_818lq"]
[ext_resource type="Resource" uid="uid://b5gx3q8nvu72e" path="res://systems/inputs/base_mode/hit.tres" id="22_2hs2y"]
[ext_resource type="Resource" uid="uid://d2r0ur8k3cuu3" path="res://systems/inputs/base_mode/dash.tres" id="23_g6bbx"]
[ext_resource type="Script" uid="uid://dsa1dnifd6w32" path="res://addons/guide/guide_mapping_context.gd" id="23_llfhp"]
[ext_resource type="Resource" uid="uid://bw5k2gsv3jqcv" path="res://systems/inputs/base_mode/throw.tres" id="24_yp12v"]
[ext_resource type="Resource" uid="uid://bbce5wfwxpns1" path="res://systems/inputs/base_mode/slide_pressed.tres" id="23_rvpjj"]
[ext_resource type="Resource" uid="uid://b334rau1yxmm7" path="res://systems/inputs/base_mode/slide.tres" id="25_s8kjn"]
[ext_resource type="Resource" uid="uid://55b0dsvioj08" path="res://systems/inputs/base_mode/jump_pressed.tres" id="25_si4d4"]
[ext_resource type="Resource" uid="uid://dgluj0ql5vth7" path="res://systems/inputs/base_mode/pause.tres" id="29_q86qg"]
[ext_resource type="Script" uid="uid://cw71o87tvdx3q" path="res://addons/guide/inputs/guide_input_key.gd" id="30_cvxqo"]
[ext_resource type="Resource" uid="uid://spo3pbqjx0eb" path="res://systems/inputs/base_mode/parry.tres" id="30_rvpjj"]
[ext_resource type="Resource" uid="uid://dxy0071ic1wdj" path="res://systems/inputs/base_mode/slam.tres" id="32_s8kjn"]
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://systems/inputs/base_mode/move_back.tres" id="33_fykw6"]
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://systems/inputs/base_mode/move_front.tres" id="34_rvpjj"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://systems/inputs/base_mode/move_left.tres" id="35_s8kjn"]
@@ -229,57 +229,54 @@ action = ExtResource("16_rvpjj")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_bkx7d"), SubResource("Resource_yxj6r")])
metadata/_guide_input_mappings_collapsed = false
[sub_resource type="Resource" id="Resource_fykw6"]
script = ExtResource("10_cvxqo")
axis = 5
[sub_resource type="Resource" id="Resource_rvpjj"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_s8kjn"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_fykw6")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_rvpjj")])
metadata/_guide_triggers_collapsed = false
[sub_resource type="Resource" id="Resource_vibkn"]
script = ExtResource("1_qmhk6")
action = ExtResource("16_0qat1")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_s8kjn")])
[sub_resource type="Resource" id="Resource_qkgmj"]
script = ExtResource("10_cvxqo")
axis = 5
[sub_resource type="Resource" id="Resource_st2ej"]
script = ExtResource("17_s8kjn")
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_818lq"]
[sub_resource type="Resource" id="Resource_s8kjn"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_qkgmj")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_st2ej")])
metadata/_guide_triggers_collapsed = false
[sub_resource type="Resource" id="Resource_wcvib"]
script = ExtResource("30_cvxqo")
key = 4194326
[sub_resource type="Resource" id="Resource_imjft"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_wcvib")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_st2ej")])
metadata/_guide_triggers_collapsed = false
[sub_resource type="Resource" id="Resource_vibkn"]
script = ExtResource("1_qmhk6")
action = ExtResource("23_rvpjj")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_s8kjn"), SubResource("Resource_imjft")])
[sub_resource type="Resource" id="Resource_f3pn5"]
script = ExtResource("10_cvxqo")
axis = 5
[sub_resource type="Resource" id="Resource_818lq"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_f3pn5")
[sub_resource type="Resource" id="Resource_qksfw"]
script = ExtResource("30_cvxqo")
key = 4194326
[sub_resource type="Resource" id="Resource_woy8j"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_qksfw")
[sub_resource type="Resource" id="Resource_2hs2y"]
script = ExtResource("1_qmhk6")
action = ExtResource("19_li5ak")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_818lq")])
[sub_resource type="Resource" id="Resource_lfx76"]
script = ExtResource("19_qkgmj")
button = 2
[sub_resource type="Resource" id="Resource_oruo7"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_4ee3d"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_lfx76")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_oruo7")])
[sub_resource type="Resource" id="Resource_0s4kt"]
script = ExtResource("1_qmhk6")
action = ExtResource("18_vibkn")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_4ee3d")])
action = ExtResource("25_s8kjn")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_818lq"), SubResource("Resource_woy8j")])
[sub_resource type="Resource" id="Resource_1fkas"]
script = ExtResource("19_qkgmj")
@@ -359,6 +356,35 @@ script = ExtResource("1_qmhk6")
action = ExtResource("22_2hs2y")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_500v3"), SubResource("Resource_a8sqk")])
[sub_resource type="Resource" id="Resource_kx31q"]
script = ExtResource("19_qkgmj")
button = 9
[sub_resource type="Resource" id="Resource_oux88"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_b7w5s"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_kx31q")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_oux88")])
[sub_resource type="Resource" id="Resource_jk2g8"]
script = ExtResource("30_cvxqo")
key = 70
[sub_resource type="Resource" id="Resource_y7p41"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_3uxou"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_jk2g8")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_y7p41")])
[sub_resource type="Resource" id="Resource_3frwi"]
script = ExtResource("1_qmhk6")
action = ExtResource("30_rvpjj")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_b7w5s"), SubResource("Resource_3uxou")])
[sub_resource type="Resource" id="Resource_g6bbx"]
script = ExtResource("19_qkgmj")
button = 1
@@ -383,52 +409,36 @@ script = ExtResource("3_yp12v")
input = SubResource("Resource_xbeov")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_rt8uw")])
[sub_resource type="Resource" id="Resource_jk2g8"]
script = ExtResource("30_cvxqo")
key = 70
[sub_resource type="Resource" id="Resource_wcvib"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_imjft"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_jk2g8")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_wcvib")])
[sub_resource type="Resource" id="Resource_kx31q"]
script = ExtResource("30_cvxqo")
key = 4194326
[sub_resource type="Resource" id="Resource_oux88"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_b7w5s"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_kx31q")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_oux88")])
[sub_resource type="Resource" id="Resource_0qat1"]
script = ExtResource("1_qmhk6")
action = ExtResource("23_g6bbx")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_1rw8g"), SubResource("Resource_hj46p"), SubResource("Resource_imjft"), SubResource("Resource_b7w5s")])
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_1rw8g"), SubResource("Resource_hj46p")])
metadata/_guide_input_mappings_collapsed = false
[sub_resource type="Resource" id="Resource_j3axn"]
[sub_resource type="Resource" id="Resource_o5yys"]
script = ExtResource("19_qkgmj")
button = 3
button = 2
[sub_resource type="Resource" id="Resource_kxb2c"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_v2ywt"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_j3axn")
input = SubResource("Resource_o5yys")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_kxb2c")])
[sub_resource type="Resource" id="Resource_qpgnj"]
script = ExtResource("30_cvxqo")
key = 69
[sub_resource type="Resource" id="Resource_s6d3g"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_qpgnj")
[sub_resource type="Resource" id="Resource_vtk18"]
script = ExtResource("1_qmhk6")
action = ExtResource("24_yp12v")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_v2ywt")])
action = ExtResource("32_s8kjn")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_v2ywt"), SubResource("Resource_s6d3g")])
[sub_resource type="Resource" id="Resource_s4bc4"]
script = ExtResource("30_cvxqo")
@@ -526,5 +536,5 @@ input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_7io5e")])
[resource]
script = ExtResource("23_llfhp")
mappings = Array[ExtResource("1_qmhk6")]([SubResource("Resource_88x08"), SubResource("Resource_tgr2g"), SubResource("Resource_iarn8"), SubResource("Resource_cvxqo"), SubResource("Resource_tb8ii"), SubResource("Resource_iihs4"), SubResource("Resource_vibkn"), SubResource("Resource_2hs2y"), SubResource("Resource_0s4kt"), SubResource("Resource_d2r0d"), SubResource("Resource_xt1x5"), SubResource("Resource_ew1hw"), SubResource("Resource_0qat1"), SubResource("Resource_vtk18"), SubResource("Resource_weyro"), SubResource("Resource_fjku4"), SubResource("Resource_odnhd"), SubResource("Resource_0eff7"), SubResource("Resource_gt77e")])
mappings = Array[ExtResource("1_qmhk6")]([SubResource("Resource_88x08"), SubResource("Resource_tgr2g"), SubResource("Resource_iarn8"), SubResource("Resource_cvxqo"), SubResource("Resource_tb8ii"), SubResource("Resource_iihs4"), SubResource("Resource_vibkn"), SubResource("Resource_2hs2y"), SubResource("Resource_d2r0d"), SubResource("Resource_xt1x5"), SubResource("Resource_ew1hw"), SubResource("Resource_3frwi"), SubResource("Resource_0qat1"), SubResource("Resource_vtk18"), SubResource("Resource_weyro"), SubResource("Resource_fjku4"), SubResource("Resource_odnhd"), SubResource("Resource_0eff7"), SubResource("Resource_gt77e")])
metadata/_custom_type_script = "uid://dsa1dnifd6w32"

View File

@@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://spo3pbqjx0eb"]
[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_hlutc"]
[resource]
script = ExtResource("1_hlutc")
metadata/_custom_type_script = "uid://cluhc11vixkf1"

View File

@@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://dxy0071ic1wdj"]
[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_6evmc"]
[resource]
script = ExtResource("1_6evmc")
metadata/_custom_type_script = "uid://cluhc11vixkf1"

View File

@@ -1,14 +0,0 @@
[gd_resource type="Resource" script_class="GUIDEAction" load_steps=2 format=3 uid="uid://bw5k2gsv3jqcv"]
[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_7f0q6"]
[resource]
script = ExtResource("1_7f0q6")
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"

View File

@@ -10,7 +10,7 @@ class_name InputController
@export var move_right:GUIDEAction
@export var move_front:GUIDEAction
@export var move_back:GUIDEAction
@export var rotate_y:GUIDEAction
@export var rotate_vertical:GUIDEAction
@export var rotate_floorplane:GUIDEAction
@export_group("Trigger actions")
@@ -21,13 +21,14 @@ class_name InputController
@export_subgroup("Jump")
@export var jump:GUIDEAction
@export var jump_pressed:GUIDEAction
@export_subgroup("Slide")
@export var slide:GUIDEAction
@export var slide_pressed:GUIDEAction
@export_subgroup("Other")
@export var empower_down:GUIDEAction
@export var empower_released:GUIDEAction
@export var aim_canceled:GUIDEAction
@export var hit:GUIDEAction
@export var parry:GUIDEAction
@export var dash:GUIDEAction
@export var throw:GUIDEAction
@export var slam:GUIDEAction
signal input_device_changed(is_gamepad: bool)
var _using_gamepad = false
@@ -46,13 +47,14 @@ signal input_aim_pressed
signal input_aim_down
signal input_aim_released
signal input_empower_down
signal input_empower_released
signal input_aim_canceled
signal input_slide_started
signal input_slide_ongoing
signal input_slide_ended
signal input_hit
signal input_parry
signal input_dash
signal input_throw
signal input_slam
func _ready() -> void:
GUIDE.enable_mapping_context(base_mode)
@@ -60,53 +62,50 @@ func _ready() -> void:
aim_down.triggered.connect(on_input_aim_down)
aim_pressed.triggered.connect(on_input_aim_pressed)
aim_released.triggered.connect(on_input_aim_released)
empower_down.triggered.connect(on_input_empower_down)
empower_released.triggered.connect(on_input_empower_released)
aim_canceled.triggered.connect(on_input_aim_canceled)
jump_pressed.triggered.connect(on_input_jump_started)
jump.triggered.connect(on_input_jump_ongoing)
jump.completed.connect(on_input_jump_ended)
hit.triggered.connect(on_input_hit)
dash.triggered.connect(on_input_dash)
throw.triggered.connect(on_input_throw)
func on_input_dash():
input_dash.emit()
slide_pressed.triggered.connect(on_input_slide_started)
slide.triggered.connect(on_input_slide_ongoing)
slide.completed.connect(on_input_slide_ended)
func on_input_throw():
input_throw.emit()
hit.triggered.connect(on_input_hit)
parry.triggered.connect(on_input_parry)
dash.triggered.connect(on_input_dash)
slam.triggered.connect(on_input_slam)
func on_input_hit():
input_hit.emit()
func on_input_parry():
input_parry.emit()
func on_input_dash():
input_dash.emit()
func on_input_slam():
input_slam.emit()
func on_input_jump_started():
input_jump_started.emit()
func on_input_jump_ongoing():
input_jump_ongoing.emit()
func on_input_jump_ended():
input_jump_ended.emit()
func on_input_aim_down():
input_aim_down.emit()
func on_input_aim_pressed():
input_aim_pressed.emit()
func on_input_aim_released():
input_aim_released.emit()
func on_input_empower_down():
input_empower_down.emit()
func on_input_empower_released():
input_empower_released.emit()
func on_input_aim_canceled():
input_aim_canceled.emit()
func on_input_slide_started():
input_slide_started.emit()
func on_input_slide_ongoing():
input_slide_ongoing.emit()
func on_input_slide_ended():
input_slide_ended.emit()
func _input(event: InputEvent) -> void:
if event is InputEventKey:
@@ -130,5 +129,5 @@ func _process(_delta: float) -> void:
input_move_keyboard.emit(keyboard_input_vector)
input_move.emit(move.value_axis_3d)
input_rotate_y.emit(rotate_y.value_axis_1d)
input_rotate_y.emit(rotate_vertical.value_axis_1d)
input_rotate_floorplane.emit(rotate_floorplane.value_axis_1d)

View File

@@ -14,17 +14,18 @@ public partial class MantleSystem: Node3D
private ShapeCast3D _wallInFrontCast3D;
private ShapeCast3D _mantleCast3D;
private ShapeCast3D _inAirWallDetect;
private ShapeCast3D _groundedWallDetect;
public Curve3D MantleCurve { get; private set; }
public Vector3 FirstMantleProfilePoint { get; private set; } = Vector3.Zero;
public bool IsMantlePossible { get; private set; } = false;
public int NumberOfValidPofiles { get; private set; } = -1;
public bool EndedOnOtherSideOfWall { get; private set; } = false;
public bool FoundGround { get; private set; } = false;
public const int WallProfileCastCount = 7;
private ShapeCast3D[] _wallProfileShapecasts = new ShapeCast3D[WallProfileCastCount];
public Vector3[] WallProfilePositions { get; private set; } = new Vector3[WallProfileCastCount];
public Vector3[] WallProfileNormals { get; private set; } = new Vector3[WallProfileCastCount];
public void Init()
{
@@ -55,22 +56,21 @@ public partial class MantleSystem: Node3D
SetCastsEnabled(isColliding);
// Reset state
NumberOfValidPofiles = -1;
IsMantlePossible = false;
if (!isColliding)
{
return;
}
EndedOnOtherSideOfWall = false;
FoundGround = false;
if (!isColliding) return;
// Check if collide with wall
// Check if face something wall-like that should be climbable
var collisionNormal = isGrounded ? _groundedWallDetect.GetCollisionNormal(0) : _inAirWallDetect.GetCollisionNormal(0);
if (collisionNormal.Y > 0.8f)
{
return;
}
NumberOfValidPofiles = 0;
var hasFirstProfileHit = false;
if (collisionNormal.Y > 0.7f) return;
var spaceState = GetWorld3D().DirectSpaceState;
MantleCurve = new Curve3D();
MantleCurve.AddPoint(Vector3.Zero);
var hasFirstProfileHit = false;
var previousProfilePoint = GlobalPosition;
foreach (var wallProfileShapecast in _wallProfileShapecasts)
{
// Haven't met the wall yet
@@ -81,56 +81,46 @@ public partial class MantleSystem: Node3D
// Got to the other side of the wall, we stop there
if (!wallProfileShapecast.IsColliding())
{
WallProfilePositions[NumberOfValidPofiles] = globalTargetPosition;
WallProfileNormals[NumberOfValidPofiles] = Vector3.Zero;
NumberOfValidPofiles += 1;
/*EndedOnOtherSideOfWall = true;
var origin = globalTargetPosition;
var end = origin + Vector3.Down*0.51f; // We check for the ground a bit below our target
var groundQuery = PhysicsRayQueryParameters3D.Create(origin, end, wallProfileShapecast.CollisionMask);
var groundResult = spaceState.IntersectRay(groundQuery);
if (groundResult.Count > 0)
{
// We found the ground, this is our final location
FoundGround = true;
Vector3 position = (Vector3) groundResult["position"];
MantleCurve.AddPoint(ToLocal(position));
}*/
break;
}
var profilePoint = wallProfileShapecast.GetCollisionPoint(0);
var profileNormal = wallProfileShapecast.GetCollisionNormal(0);
var shape = wallProfileShapecast.Shape as SphereShape3D;
var shapeRadius = shape == null ? 0.125f : shape.Radius;
var centerOfShape = profilePoint + profileNormal * shapeRadius;
// Check if we collided parallel to a wall
var isCollisionSameAsTarget = globalTargetPosition.IsEqualApprox(profilePoint);
var isCollidingWithWall = profileNormal.Y < 0.9f;
var isCollisionSameAsTarget = globalTargetPosition.IsEqualApprox(centerOfShape);
var isCollidingWithWall = profileNormal.Y < 0.1f;
if (isCollisionSameAsTarget || isCollidingWithWall) continue;
// Check if the path from the previous point makes us go through a wall
var query = PhysicsRayQueryParameters3D.Create(previousProfilePoint, centerOfShape, wallProfileShapecast.CollisionMask);
var result = spaceState.IntersectRay(query);
if (result.Count > 0) break; // We are going through a wall, we stop there
// We have a valid collision
WallProfilePositions[NumberOfValidPofiles] = profilePoint;
WallProfileNormals[NumberOfValidPofiles] = profileNormal;
if (!hasFirstProfileHit) FirstMantleProfilePoint = centerOfShape;
hasFirstProfileHit = true;
NumberOfValidPofiles += 1;
}
IsMantlePossible = NumberOfValidPofiles > 0; // Should always be true
}
public Option<Vector3> FindMantle()
{
if (!_wallInFrontCast3D.IsColliding())
{
return Option<Vector3>.None;
}
if (_wallInFrontCast3D.GetCollisionNormal(0).Y > 0.8f)
{
return Option<Vector3>.None;
previousProfilePoint = centerOfShape;
MantleCurve.AddPoint(ToLocal(centerOfShape));
}
if (MantleCurve.PointCount == 1) return;
var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0);
var collisionNormal = _wallInFrontCast3D.GetCollisionNormal(0);
return FindMantleLocationAtPoint(collisionPoint, collisionNormal);
}
public Option<Vector3> FindMantleLocationAtPoint(Vector3 point, Vector3 wallNormal)
{
var horizontalEndLocation = point - wallNormal * MantleEndLocationDistanceFromWall;
var shapeCastStartLocation = horizontalEndLocation + Vector3.Up * MantleHeightCastStart;
_mantleCast3D.SetGlobalPosition(shapeCastStartLocation);
var targetLocation = Vector3.Down * MantleHeightCastStart + Vector3.Up * MaxStepHeight;
_mantleCast3D.SetTargetPosition(targetLocation);
if (_mantleCast3D.IsColliding() && _mantleCast3D.GetCollisionNormal(0).Y >= 0.1f)
return Option.Some(_mantleCast3D.GetCollisionPoint(0));
return Option<Vector3>.None;
IsMantlePossible = true;
}
}

View File

@@ -1,7 +1,6 @@
[gd_scene load_steps=6 format=3 uid="uid://wq1okogkhc5l"]
[gd_scene load_steps=7 format=3 uid="uid://wq1okogkhc5l"]
[ext_resource type="Script" uid="uid://bja6tis1vaysu" path="res://systems/mantle/MantleSystem.cs" id="1_2oobp"]
[ext_resource type="Shape3D" uid="uid://dp2p8v7demb5j" path="res://systems/mantle/find_wall_shape.tres" id="2_i32qj"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_4coqe"]
height = 1.7
@@ -9,6 +8,13 @@ height = 1.7
[sub_resource type="SphereShape3D" id="SphereShape3D_2oobp"]
radius = 0.75
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_2oobp"]
radius = 0.25
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_i32qj"]
radius = 0.25
height = 1.5
[sub_resource type="SphereShape3D" id="SphereShape3D_i32qj"]
radius = 0.125
@@ -35,14 +41,14 @@ collision_mask = 2
debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
[node name="InAirWallDetect" type="ShapeCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.26, 0)
shape = ExtResource("2_i32qj")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.01, 0)
shape = SubResource("CapsuleShape3D_2oobp")
target_position = Vector3(0, 0, -2)
collision_mask = 2
[node name="GroundedWallDetect" type="ShapeCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.76, 0)
shape = ExtResource("2_i32qj")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.26, 0)
shape = SubResource("CapsuleShape3D_i32qj")
target_position = Vector3(0, 0, -2)
collision_mask = 2
@@ -52,47 +58,47 @@ collision_mask = 2
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -0.5)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast2" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -0.75)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast3" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast4" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1.25)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast5" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1.5)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast6" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -1.75)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2
[node name="ShapeCast7" type="ShapeCast3D" parent="WallProfileShapeCasts"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -2)
enabled = false
shape = SubResource("SphereShape3D_i32qj")
target_position = Vector3(0, -2.375, 0)
target_position = Vector3(0, -2.125, 0)
collision_mask = 2