complete project reorganization
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 55s
Create tag and build when new code gets to main / Test (push) Successful in 7m7s
Create tag and build when new code gets to main / Export (push) Successful in 9m56s

This commit is contained in:
2026-02-04 11:20:00 +01:00
parent b6e8d0b590
commit cd519e528f
824 changed files with 397 additions and 16380 deletions

View File

@@ -0,0 +1,160 @@
using Godot;
using Movementtests.interfaces;
namespace Movementtests.systems;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_wind.png")]
public partial class DashSystem: Node3D
{
public record DashLocation(bool HasHit, Vector3 TargetLocation, Vector3 CollisionPoint, Vector3 CollisionNormal, GodotObject HitObject = null);
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
public float DashSpeed { get; set; } = 0.1f;
[Export(PropertyHint.Range, "0,1000,1,or_greater")]
public float PostDashSpeed { get; set; } = 0f;
public bool HasHit { get; set; }
public bool CanDashThroughTarget { get; set; }
public Vector3 TargetLocation { get; set; }
public Vector3 CollisionPoint { get; set; }
public Vector3 CollisionNormal { get; set; }
public GodotObject CollidedObject { get; set; }
public Vector3 PlannedLocation { get; set; }
public bool ShouldMantle { get; set; }
public Vector3 PlannedMantleLocation { get; set; }
public MantleSystem MantleSystem { get; set; }
private HeadSystem _head;
public ShapeCast3D DashCast3D;
private Camera3D _camera;
private Vector3 _dashDirection = Vector3.Zero;
private ShapeCast3D _dashCastDrop;
private MeshInstance3D _dashDropIndicator;
private MeshInstance3D _dashDropLocationIndicator;
private MeshInstance3D _dashTarget;
private CpuParticles3D _dashIndicator;
private AnimationPlayer _dashIndicatorAnim;
[Export]
public PackedScene DashIndicatorScene { get; set; }
[Signal]
public delegate void DashStartedEventHandler();
[Signal]
public delegate void DashEndedEventHandler();
[Signal]
public delegate void DashProgressEventHandler(float progress);
private Vector3 _globalDashPosition = Vector3.Zero;
public float DashCastRadius { get; set; }
public void Init(HeadSystem head, Camera3D camera)
{
DashCast3D = GetNode<ShapeCast3D>("DashCast3D");
var dashShape = DashCast3D.GetShape() as SphereShape3D;
DashCastRadius = dashShape!.Radius;
_dashCastDrop = GetNode<ShapeCast3D>("DashCastDrop");
_dashDropIndicator = GetNode<MeshInstance3D>("DashDropIndicator");
_dashDropIndicator.Visible = false;
_dashDropLocationIndicator = GetNode<MeshInstance3D>("DashDropLocationIndicator");
_dashDropLocationIndicator.Visible = false;
_head = head;
_camera = camera;
MantleSystem = GetNode<MantleSystem>("MantleSystem");
MantleSystem.Init();
_dashTarget = GetNode<MeshInstance3D>("DashTarget");
_dashTarget.SetVisible(false);
_dashIndicator = GetNode<CpuParticles3D>("DashIndicator");
_dashIndicatorAnim = GetNode<AnimationPlayer>("DashIndicator/AnimationPlayer");
}
private DashLocation ComputeDashLocation()
{
var targetLocation = DashCast3D.ToGlobal(DashCast3D.TargetPosition);
var hasHit = DashCast3D.IsColliding();
if (!hasHit)
{
return new DashLocation(false, targetLocation, Vector3.Zero, Vector3.Zero);
}
var collisionPoint = DashCast3D.GetCollisionPoint(0);
var collisionNormal = DashCast3D.GetCollisionNormal(0);
var collidedObject = DashCast3D.GetCollider(0);
var fraction = DashCast3D.GetClosestCollisionSafeFraction();
var globalSweepPath = targetLocation - DashCast3D.GlobalPosition;
var locationAlongPath = DashCast3D.GlobalPosition + globalSweepPath * fraction;
return new DashLocation(true, locationAlongPath, collisionPoint, collisionNormal, collidedObject);
}
public void PrepareDash()
{
DashCast3D.SetRotation(_head.GetGlobalLookRotation());
(HasHit, PlannedLocation, CollisionPoint, CollisionNormal, CollidedObject) = ComputeDashLocation();
CanDashThroughTarget = false;
if (CollidedObject is ITargetable targetable)
{
_dashTarget.SetVisible(false);
CanDashThroughTarget = true;
return;
}
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);
targetColor = ShouldMantle ? new Color(0.2f, 0.2f, 1f) : targetColor;
var targetMaterial = (StandardMaterial3D) _dashTarget.GetSurfaceOverrideMaterial(0);
targetMaterial.SetAlbedo(targetColor);
_dashTarget.SetVisible(true);
var targetLocation = ShouldMantle ? MantleSystem.FirstMantleProfilePoint : PlannedLocation;
_dashTarget.SetGlobalPosition(targetLocation);
return;
var shouldShowDropIndicator = !HasHit && !ShouldMantle;
_dashDropIndicator.SetVisible(shouldShowDropIndicator);
_dashDropLocationIndicator.SetVisible(shouldShowDropIndicator);
if (shouldShowDropIndicator)
{
_dashCastDrop.GlobalPosition = targetLocation; // Place drop indication cast at dash location
var startDropLocation = targetLocation; // Start of the drop is the dash target location
// End of the drop is either max cast distance or first collision
var hasDropLocationHit = _dashCastDrop.IsColliding();
var endDropLocation = hasDropLocationHit ? _dashCastDrop.GetCollisionPoint(0) : _dashCastDrop.ToGlobal(DashCast3D.TargetPosition);
// Only show drop location indicator if drop cast has hit
_dashDropLocationIndicator.SetVisible(hasDropLocationHit);
_dashDropLocationIndicator.SetGlobalPosition(endDropLocation);
var dropLength = (endDropLocation - startDropLocation).Length();
var dropDirection = (endDropLocation - startDropLocation).Normalized();
_dashDropIndicator.SetScale(new Vector3(1, dropLength, 1));
_dashDropIndicator.SetGlobalPosition(startDropLocation + dropDirection * dropLength * 0.5f);
}
}
public void StopPreparingDash()
{
CanDashThroughTarget = false;
_dashTarget.SetVisible(false);
_dashDropIndicator.SetVisible(false);
_dashDropLocationIndicator.SetVisible(false);
}
}

View File

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

View File

@@ -0,0 +1,77 @@
[gd_scene format=3 uid="uid://hd0868f4pb63"]
[ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://scenes/player_controller/components/dash/light-ring.jpg" id="1_jadbb"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tqt6i"]
transparency = 1
blend_mode = 1
shading_mode = 0
albedo_texture = ExtResource("1_jadbb")
billboard_mode = 1
[sub_resource type="PlaneMesh" id="PlaneMesh_jngg2"]
orientation = 2
[sub_resource type="Animation" id="Animation_fmn25"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:mesh:size")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(2, 2)]
}
[sub_resource type="Animation" id="Animation_stbcc"]
resource_name = "start"
length = 0.2
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:mesh:size")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.2),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(2, 2), Vector2(0, 0)]
}
tracks/1/type = "method"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.2),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"queue_free"
}]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_3aile"]
_data = {
&"RESET": SubResource("Animation_fmn25"),
&"start": SubResource("Animation_stbcc")
}
[node name="DashIndicator" type="CPUParticles3D" unique_id=585575469]
material_override = SubResource("StandardMaterial3D_tqt6i")
emitting = false
amount = 1
lifetime = 0.5
one_shot = true
mesh = SubResource("PlaneMesh_jngg2")
gravity = Vector3(0, 0, 0)
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=686842148]
libraries/ = SubResource("AnimationLibrary_3aile")
autoplay = &"start"

View File

@@ -0,0 +1,57 @@
[gd_scene format=3 uid="uid://cqduhd4opgwvm"]
[ext_resource type="Script" uid="uid://dwoppk8j5fxeg" path="res://scenes/player_controller/components/dash/DashSystem.cs" id="1_hwig2"]
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://scenes/player_controller/components/mantle/mantle_system.tscn" id="2_pff7b"]
[ext_resource type="PackedScene" uid="uid://hd0868f4pb63" path="res://scenes/player_controller/components/dash/dash_indicator.tscn" id="2_tqt6i"]
[sub_resource type="SphereShape3D" id="SphereShape3D_jngg2"]
[sub_resource type="SphereMesh" id="SphereMesh_qu4wy"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_v31n3"]
[sub_resource type="CylinderMesh" id="CylinderMesh_jngg2"]
top_radius = 0.1
bottom_radius = 0.1
height = 1.0
[sub_resource type="TorusMesh" id="TorusMesh_tqt6i"]
inner_radius = 0.1
outer_radius = 0.5
[node name="DashSystem" type="Node3D" unique_id=2116632075]
script = ExtResource("1_hwig2")
DashIndicatorScene = ExtResource("2_tqt6i")
[node name="DashCast3D" type="ShapeCast3D" parent="." unique_id=1635795914]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
shape = SubResource("SphereShape3D_jngg2")
target_position = Vector3(0, 0, -12)
max_results = 1
collision_mask = 304
debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
[node name="DashCastDrop" type="ShapeCast3D" parent="." unique_id=980436638]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 1.6, 0)
shape = SubResource("SphereShape3D_jngg2")
target_position = Vector3(0, 0, -50)
max_results = 1
collision_mask = 304
debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
[node name="DashTarget" type="MeshInstance3D" parent="." unique_id=711803810]
mesh = SubResource("SphereMesh_qu4wy")
surface_material_override/0 = SubResource("StandardMaterial3D_v31n3")
[node name="MantleSystem" parent="." unique_id=1511791010 instance=ExtResource("2_pff7b")]
MantleEndLocationDistanceFromWall = 0.25
MantleHeightCastStart = 2.0
[node name="DashIndicator" parent="." unique_id=98967688 instance=ExtResource("2_tqt6i")]
visible = false
[node name="DashDropIndicator" type="MeshInstance3D" parent="." unique_id=173959533]
mesh = SubResource("CylinderMesh_jngg2")
[node name="DashDropLocationIndicator" type="MeshInstance3D" parent="." unique_id=1260955364]
mesh = SubResource("TorusMesh_tqt6i")

View File

@@ -0,0 +1,5 @@
[gd_resource type="Curve" format=3 uid="uid://c2a8soliruf35"]
[resource]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.5, 1), -1.89032e-07, -1.89032e-07, 0, 0, Vector2(0.8, 0.05), -9.56219, 0.0, 0, 1, Vector2(0.995, 0.05), 0.0, 0.0, 0, 0, Vector2(1, 1), -0.0540619, -0.0540619, 0, 0]
point_count = 5

BIN
scenes/player_controller/components/dash/light-ring.jpg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://chvt6g0xn5c2m"
path.s3tc="res://.godot/imported/light-ring.jpg-59a7aa6aff8e55915b68cd23f0e30ad8.s3tc.ctex"
path.etc2="res://.godot/imported/light-ring.jpg-59a7aa6aff8e55915b68cd23f0e30ad8.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://scenes/player_controller/components/dash/light-ring.jpg"
dest_files=["res://.godot/imported/light-ring.jpg-59a7aa6aff8e55915b68cd23f0e30ad8.s3tc.ctex", "res://.godot/imported/light-ring.jpg-59a7aa6aff8e55915b68cd23f0e30ad8.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0