complete project reorganization
This commit is contained in:
160
scenes/player_controller/components/dash/DashSystem.cs
Normal file
160
scenes/player_controller/components/dash/DashSystem.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dwoppk8j5fxeg
|
||||
77
scenes/player_controller/components/dash/dash_indicator.tscn
Normal file
77
scenes/player_controller/components/dash/dash_indicator.tscn
Normal 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"
|
||||
57
scenes/player_controller/components/dash/dash_system.tscn
Normal file
57
scenes/player_controller/components/dash/dash_system.tscn
Normal 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")
|
||||
@@ -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
BIN
scenes/player_controller/components/dash/light-ring.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -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
|
||||
370
scenes/player_controller/components/head/HeadSystem.cs
Normal file
370
scenes/player_controller/components/head/HeadSystem.cs
Normal file
@@ -0,0 +1,370 @@
|
||||
using System;
|
||||
using Godot;
|
||||
using RustyOptions;
|
||||
|
||||
namespace Movementtests.systems;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_face.png")]
|
||||
public partial class HeadSystem : Node3D
|
||||
{
|
||||
[Signal]
|
||||
public delegate void HitboxActivatedEventHandler();
|
||||
[Signal]
|
||||
public delegate void HitboxDeactivatedEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void ParryboxActivatedEventHandler();
|
||||
[Signal]
|
||||
public delegate void ParryboxDeactivatedEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void HitTargetEventHandler();
|
||||
[Signal]
|
||||
public delegate void GotHitEventHandler();
|
||||
[Signal]
|
||||
public delegate void DeathAnimationFinishedEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void StepFootEventHandler();
|
||||
|
||||
public record CameraParameters(
|
||||
double Delta,
|
||||
Vector2 LookDir,
|
||||
Vector3 PlayerInput,
|
||||
Vector3 PlayerVelocity,
|
||||
Vector3 WallContactPoint,
|
||||
float SensitivitMultiplier,
|
||||
bool WithCameraJitter,
|
||||
bool WithCameraBobbing,
|
||||
float BobbingMultiplier,
|
||||
float FovMultiplier);
|
||||
|
||||
private Camera3D _camera;
|
||||
private Marker3D _cameraAnchor;
|
||||
private AnimationPlayer _animationPlayer;
|
||||
private AnimationTree _animationTree;
|
||||
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float LookSensitivity { get; set; } = 1f;
|
||||
|
||||
[ExportGroup("Camera incline")]
|
||||
[Export(PropertyHint.Range, "0.1,50,0.1,or_greater")]
|
||||
public double CameraInclineAcceleration { get; set; } = 10f;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float WallRunCameraIncline { get; set; } = 5f;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float GroundedCameraIncline { get; set; } = 5f;
|
||||
|
||||
[ExportGroup("Sliding")]
|
||||
[Export(PropertyHint.Range, "0,2,0.1,or_greater")]
|
||||
public float SlidingCameraHeightOffset { get; set; } = 1.0f;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float SlidingJitterFrequency { get; set; } = 0.01f;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float SlidingJitterAmplitude { get; set; } = 0.1f;
|
||||
|
||||
private FastNoiseLite _slidingNoise = new FastNoiseLite();
|
||||
|
||||
[ExportGroup("Bobbing")]
|
||||
|
||||
private float _bobbingAccumulator; // Constantly increases when player moves in X or/and Z axis
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float BobbingFrequency { set; get; } = 2.4f;
|
||||
[Export(PropertyHint.Range, "0,0.4,0.01,or_greater")]
|
||||
public float BobbingAmplitude { set; get; } = 0.08f;
|
||||
|
||||
[ExportGroup("FOV")]
|
||||
[Export(PropertyHint.Range, "0,180,0.1,degrees")]
|
||||
public float BaseFov { get; set; } = 75.0f;
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float FovChangeFactor { get; set; } = 1.2f;
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float FovChangeSpeed { get; set; } = 6.25f;
|
||||
[Export(PropertyHint.Range, "0,100,1,or_greater")]
|
||||
public float FovMaxedOutSpeed { get; set; } = 20f;
|
||||
|
||||
[ExportGroup("First Person rig")]
|
||||
private Node3D _fpRig;
|
||||
private Node3D _rightHandedWeapon;
|
||||
private Node3D _leftHandedWeapon;
|
||||
private Node3D _fpDisplacedRig;
|
||||
private Vector3 _fpDisplacedRigInitialRotation;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float WeaponSway { get; set; } = 5f;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float WeaponLookRotation { get; set; } = 1f;
|
||||
[Export(PropertyHint.Range, "0,200,1,or_greater")]
|
||||
public float WeaponMoveRotation { get; set; } = 80f;
|
||||
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
||||
public float WeaponAdjustmentSpeed { get; set; } = 10f;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float DisplacedWeaponSway { get; set; } = 5f;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float DisplacedWeaponLookRotation { get; set; } = 1f;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float DisplacedWeaponMoveRotation { get; set; } = 0.1f;
|
||||
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
||||
public float DisplacedWeaponAdjustmentSpeed { get; set; } = 10f;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_isPlayingForcingAnim = false;
|
||||
|
||||
Input.SetMouseMode(Input.MouseModeEnum.Captured);
|
||||
_camera = GetNode<Camera3D>("CameraSmooth/Camera3D");
|
||||
_cameraAnchor = GetNode<Marker3D>("CameraAnchor");
|
||||
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
|
||||
_animationTree = GetNode<AnimationTree>("AnimationTree");
|
||||
|
||||
_fpRig = GetNode<Node3D>("FPRig");
|
||||
_rightHandedWeapon = GetNode<Node3D>("FPRig/Sword");
|
||||
_leftHandedWeapon = GetNode<Node3D>("FPRig/Parry");
|
||||
_fpDisplacedRig = GetNode<Node3D>("FPRig/Sword");
|
||||
_fpDisplacedRigInitialRotation = _fpDisplacedRig.Rotation;
|
||||
|
||||
_slidingNoise.NoiseType = FastNoiseLite.NoiseTypeEnum.Perlin;
|
||||
_slidingNoise.SetFrequency(SlidingJitterFrequency);
|
||||
}
|
||||
|
||||
public void OnMantle()
|
||||
{
|
||||
_animationTree.Set("parameters/OnMantle/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
|
||||
}
|
||||
public void OnJumpStarted()
|
||||
{
|
||||
_animationTree.Set("parameters/OnJumpStart/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
|
||||
}
|
||||
public void OnJumpEnded()
|
||||
{
|
||||
_animationTree.Set("parameters/OnJumpEnd/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
|
||||
}
|
||||
public void OnHit()
|
||||
{
|
||||
_animationTree.Set("parameters/OnHit/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
|
||||
}
|
||||
public void OnParry()
|
||||
{
|
||||
_animationTree.Set("parameters/OnParry/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
|
||||
}
|
||||
public void OnStartDeathAnimation()
|
||||
{
|
||||
_isPlayingForcingAnim = true;
|
||||
_animationTree.Set("parameters/OnDie/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
|
||||
}
|
||||
|
||||
public void OnDeathAnimationFinished()
|
||||
{
|
||||
EmitSignalDeathAnimationFinished();
|
||||
}
|
||||
|
||||
public void OnHitTarget()
|
||||
{
|
||||
EmitSignalHitTarget();
|
||||
}
|
||||
public void OnGetHit()
|
||||
{
|
||||
EmitSignalGotHit();
|
||||
}
|
||||
|
||||
public void OnHitboxActivated()
|
||||
{
|
||||
EmitSignalHitboxActivated();
|
||||
}
|
||||
public void OnHitboxDeactivated()
|
||||
{
|
||||
EmitSignalHitboxDeactivated();
|
||||
}
|
||||
|
||||
public void OnParryboxActivated()
|
||||
{
|
||||
EmitSignalHitboxActivated();
|
||||
}
|
||||
public void OnParryboxDeactivated()
|
||||
{
|
||||
EmitSignalHitboxDeactivated();
|
||||
}
|
||||
|
||||
private bool _footstepEmitted;
|
||||
private bool _isPlayingForcingAnim;
|
||||
|
||||
public void LookAround(CameraParameters inputs)
|
||||
{
|
||||
if (_isPlayingForcingAnim)
|
||||
{
|
||||
_camera.Position = Vector3.Zero;
|
||||
_camera.Rotation = Vector3.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
var (delta,
|
||||
lookDir,
|
||||
playerInput,
|
||||
playerVelocity,
|
||||
wallContactPoint,
|
||||
sensitivitMultiplier,
|
||||
withCameraJitter,
|
||||
withCameraBobbing,
|
||||
bobbingMultiplier,
|
||||
fovMultiplier) = inputs;
|
||||
|
||||
// Horizontal movement of head
|
||||
float angleForHorizontalRotation = lookDir.X * LookSensitivity * sensitivitMultiplier;
|
||||
RotateY(angleForHorizontalRotation);
|
||||
|
||||
// Vertical movement of head
|
||||
Vector3 currentCameraRotation = _cameraAnchor.Rotation;
|
||||
currentCameraRotation.X += Convert.ToSingle(lookDir.Y * LookSensitivity * sensitivitMultiplier);
|
||||
currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f));
|
||||
|
||||
// Camera incline on Wall and more
|
||||
var isWallRunning = wallContactPoint.Length() > Mathf.Epsilon;
|
||||
float cameraIncline;
|
||||
if (isWallRunning)
|
||||
{
|
||||
var directionToWall = (wallContactPoint - GlobalPosition).Normalized();
|
||||
var cameraInclineFactor = ComputeCameraInclineFactor(directionToWall);
|
||||
cameraIncline = Mathf.DegToRad(WallRunCameraIncline * cameraInclineFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cameraInclineFactor = ComputeCameraInclineFactor(playerInput);
|
||||
cameraIncline = Mathf.DegToRad(GroundedCameraIncline * cameraInclineFactor * -1.0f);
|
||||
}
|
||||
currentCameraRotation.Z = (float) Mathf.Lerp(currentCameraRotation.Z, cameraIncline, delta * CameraInclineAcceleration);
|
||||
_cameraAnchor.Rotation = currentCameraRotation;
|
||||
|
||||
if (withCameraJitter)
|
||||
{
|
||||
_cameraAnchor.Position = Vector3.Down*SlidingCameraHeightOffset;
|
||||
float noise1D = _slidingNoise.GetNoise1D(Time.GetTicksMsec());
|
||||
float noiseAmplitude = SlidingJitterAmplitude*Mathf.Clamp(playerVelocity.Length(), 0f, 1f);
|
||||
_cameraAnchor.Position += Vector3.Up*noise1D*noiseAmplitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cameraAnchor.Position = Vector3.Zero;
|
||||
}
|
||||
|
||||
Vector3 newPositionForCamera = Vector3.Zero;
|
||||
Vector3 newPositionForRig = Vector3.Zero;
|
||||
if (withCameraBobbing)
|
||||
{
|
||||
_bobbingAccumulator += (float) delta * playerVelocity.Length();
|
||||
|
||||
// As the _bobbingAccumulator increases we're changing values for sin and cos functions.
|
||||
// Because both of them are just waves, we will be slide up with y and then slide down with y
|
||||
// creating bobbing effect. The same works for cos. As the _bobbingAccumulator increases the cos decreases and then increases
|
||||
newPositionForCamera.Y = Mathf.Sin(_bobbingAccumulator * BobbingFrequency) * BobbingAmplitude * bobbingMultiplier;
|
||||
newPositionForCamera.X = Mathf.Cos(_bobbingAccumulator * BobbingFrequency / 2.0f) * BobbingAmplitude * bobbingMultiplier;
|
||||
|
||||
if (newPositionForCamera.Y < -0.07 && !_footstepEmitted) Footstep();
|
||||
if (newPositionForCamera.Y > 0) _footstepEmitted = false;
|
||||
|
||||
// Offset bobbing for weapon rig
|
||||
newPositionForRig.Y = Mathf.Cos(_bobbingAccumulator * BobbingFrequency) * BobbingAmplitude * bobbingMultiplier * 0.2f;
|
||||
newPositionForRig.X = Mathf.Sin(_bobbingAccumulator * BobbingFrequency / 2.0f) * BobbingAmplitude * bobbingMultiplier * 0.2f;
|
||||
}
|
||||
_cameraAnchor.Position += newPositionForCamera;
|
||||
|
||||
_camera.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated();
|
||||
|
||||
// First person rig adjustments
|
||||
_fpRig.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated();
|
||||
// Apply bobbing
|
||||
_fpRig.Position += newPositionForRig;
|
||||
|
||||
// Rotate the whole rig based on movement input
|
||||
var newRigRotation = _fpRig.Rotation;
|
||||
var camTilt = Mathf.Lerp(_fpRig.Rotation.Z, cameraIncline*WeaponMoveRotation, delta*WeaponAdjustmentSpeed);
|
||||
newRigRotation.Z = (float) camTilt;
|
||||
|
||||
// Rotate the whole rig based on camera rotation input
|
||||
newRigRotation.X = Mathf.Lerp(newRigRotation.X, -lookDir.Y*WeaponSway, (float) delta*WeaponAdjustmentSpeed);
|
||||
newRigRotation.Y = Mathf.Lerp(newRigRotation.Y, -lookDir.X*WeaponSway, (float) delta*WeaponAdjustmentSpeed);
|
||||
|
||||
// Apply
|
||||
_fpRig.Rotation = newRigRotation;
|
||||
|
||||
// Compute displaced rig adjustments, starting with movement input
|
||||
var newDisplacedRigRotation = _fpDisplacedRig.Rotation;
|
||||
|
||||
var howMuchForward = ComputeHowMuchInputForward(playerInput);
|
||||
var howMuchSideways = ComputeHowMuchInputSideways(playerInput);
|
||||
var displacedCamTiltForward = Mathf.Lerp(newDisplacedRigRotation.Z,
|
||||
_fpDisplacedRigInitialRotation.Z + howMuchForward*DisplacedWeaponMoveRotation,
|
||||
delta*DisplacedWeaponAdjustmentSpeed);
|
||||
var displacedCamTiltSide = Mathf.Lerp(newDisplacedRigRotation.X,
|
||||
_fpDisplacedRigInitialRotation.X - howMuchSideways*DisplacedWeaponMoveRotation,
|
||||
delta*DisplacedWeaponAdjustmentSpeed);
|
||||
|
||||
newDisplacedRigRotation.X = (float) displacedCamTiltSide;
|
||||
newDisplacedRigRotation.Z = (float) displacedCamTiltForward;
|
||||
|
||||
var displacedSwayY = Mathf.Lerp(newDisplacedRigRotation.Y,
|
||||
_fpDisplacedRigInitialRotation.Y - lookDir.X*DisplacedWeaponSway,
|
||||
delta*DisplacedWeaponAdjustmentSpeed);
|
||||
newDisplacedRigRotation.Y = (float) displacedSwayY;
|
||||
|
||||
// Apply
|
||||
_fpDisplacedRig.Rotation = newDisplacedRigRotation;
|
||||
|
||||
// Camera adjustments
|
||||
float velocityClamped = Mathf.Clamp(playerVelocity.Length(), 0.5f, FovMaxedOutSpeed);
|
||||
float targetFov = BaseFov + FovChangeFactor * velocityClamped * fovMultiplier;
|
||||
_camera.Fov = Mathf.Lerp(_camera.Fov, targetFov, (float) delta * FovChangeSpeed);
|
||||
}
|
||||
|
||||
public void Footstep()
|
||||
{
|
||||
_footstepEmitted = true;
|
||||
EmitSignalStepFoot();
|
||||
}
|
||||
|
||||
public void HideWeapon()
|
||||
{
|
||||
_rightHandedWeapon.Visible = false;
|
||||
}
|
||||
public void ShowWeapon()
|
||||
{
|
||||
_rightHandedWeapon.Visible = true;
|
||||
}
|
||||
|
||||
public float ComputeCameraInclineFactor(Vector3 direction)
|
||||
{
|
||||
var forward = GetForwardHorizontalVector().Normalized();
|
||||
var crossProduct = forward.Cross(direction);
|
||||
return crossProduct.Length()*Mathf.Sign(crossProduct.Y);
|
||||
}
|
||||
|
||||
public float ComputeHowMuchInputForward(Vector3 playerInput)
|
||||
{
|
||||
var forwardAngle = GetForwardHorizontalVector().AngleTo(playerInput);
|
||||
var forwardRemapped = Mathf.Remap(forwardAngle, 0, Mathf.Pi, -1, 1);
|
||||
return playerInput.Length() > 0 ? forwardRemapped : 0;
|
||||
}
|
||||
|
||||
public float ComputeHowMuchInputSideways(Vector3 playerInput)
|
||||
{
|
||||
var rightAngle = GetForwardHorizontalVector().Cross(Vector3.Up).Normalized().AngleTo(playerInput);
|
||||
var forwardRemapped = Mathf.Remap(rightAngle, 0, Mathf.Pi, -1, 1);
|
||||
return playerInput.Length() > 0 ? forwardRemapped : 0;
|
||||
}
|
||||
|
||||
public Vector3 GetForwardHorizontalVector()
|
||||
{
|
||||
return GetGlobalTransform().Basis.Z;
|
||||
}
|
||||
|
||||
public Vector3 GetGlobalLookRotation()
|
||||
{
|
||||
return new Vector3(
|
||||
_camera.Rotation.X,
|
||||
Rotation.Y,
|
||||
_camera.Rotation.Z);
|
||||
}
|
||||
|
||||
public void SetHeight(float height)
|
||||
{
|
||||
Position = new Vector3(Position.X, height, Position.Z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dtkdrnsmlwm67
|
||||
76
scenes/player_controller/components/head/fp_blend_tree.tres
Normal file
76
scenes/player_controller/components/head/fp_blend_tree.tres
Normal file
@@ -0,0 +1,76 @@
|
||||
[gd_resource type="AnimationNodeBlendTree" format=3 uid="uid://c26yvcyyyj811"]
|
||||
|
||||
[ext_resource type="AnimationNodeStateMachine" uid="uid://3r5oeg0ho0d4" path="res://scenes/player_controller/components/head/fp_state_machine.tres" id="1_knaxl"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_1hkum"]
|
||||
animation = &"die"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_knaxl"]
|
||||
animation = &"idle"
|
||||
|
||||
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_ao3u1"]
|
||||
filters = ["../..", "../../FPRig/Sword:position", "../../FPRig/Sword:rotation", "..:position", "..:rotation", ".:position", ".:rotation"]
|
||||
|
||||
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_1hkum"]
|
||||
|
||||
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_knaxl"]
|
||||
filter_enabled = true
|
||||
filters = ["..:position", "..:rotation"]
|
||||
|
||||
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_23rmc"]
|
||||
filter_enabled = true
|
||||
filters = ["..:position", "..:rotation"]
|
||||
|
||||
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_dlkjl"]
|
||||
filter_enabled = true
|
||||
filters = ["..:position", "..:rotation", "..:rotation:x", "..:rotation:z"]
|
||||
|
||||
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_lwjon"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_calte"]
|
||||
animation = &"parry"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_23rmc"]
|
||||
animation = &"hit1"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_dlkjl"]
|
||||
animation = &"jump_end"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ao3u1"]
|
||||
animation = &"jump_start"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_lwjon"]
|
||||
animation = &"mantle"
|
||||
|
||||
[resource]
|
||||
graph_offset = Vector2(-363.5551, -25.864124)
|
||||
nodes/output/position = Vector2(2020, -40)
|
||||
nodes/AnimationNodeStateMachine/node = ExtResource("1_knaxl")
|
||||
nodes/AnimationNodeStateMachine/position = Vector2(-560, 180)
|
||||
nodes/Idle/node = SubResource("AnimationNodeAnimation_knaxl")
|
||||
nodes/Idle/position = Vector2(-100, -20)
|
||||
nodes/OnHit/node = SubResource("AnimationNodeOneShot_1hkum")
|
||||
nodes/OnHit/position = Vector2(1240, -60)
|
||||
nodes/hit1/node = SubResource("AnimationNodeAnimation_23rmc")
|
||||
nodes/hit1/position = Vector2(1080, 320)
|
||||
nodes/OnJumpStart/node = SubResource("AnimationNodeOneShot_23rmc")
|
||||
nodes/OnJumpStart/position = Vector2(140, 0)
|
||||
nodes/OnJumpEnd/node = SubResource("AnimationNodeOneShot_knaxl")
|
||||
nodes/OnJumpEnd/position = Vector2(560, -20)
|
||||
nodes/jump_start/node = SubResource("AnimationNodeAnimation_ao3u1")
|
||||
nodes/jump_start/position = Vector2(-120, 320)
|
||||
nodes/jump_end/node = SubResource("AnimationNodeAnimation_dlkjl")
|
||||
nodes/jump_end/position = Vector2(300, 340)
|
||||
nodes/OnMantle/node = SubResource("AnimationNodeOneShot_dlkjl")
|
||||
nodes/OnMantle/position = Vector2(900, -60)
|
||||
nodes/mantle/node = SubResource("AnimationNodeAnimation_lwjon")
|
||||
nodes/mantle/position = Vector2(640, 320)
|
||||
nodes/OnDie/node = SubResource("AnimationNodeOneShot_ao3u1")
|
||||
nodes/OnDie/position = Vector2(1500, -60)
|
||||
nodes/Die/node = SubResource("AnimationNodeAnimation_1hkum")
|
||||
nodes/Die/position = Vector2(1280, 340)
|
||||
nodes/OnParry/node = SubResource("AnimationNodeOneShot_lwjon")
|
||||
nodes/OnParry/position = Vector2(1780, -40)
|
||||
nodes/Parry/node = SubResource("AnimationNodeAnimation_calte")
|
||||
nodes/Parry/position = Vector2(1600, 300)
|
||||
node_connections = [&"output", 0, &"OnParry", &"OnHit", 0, &"OnMantle", &"OnHit", 1, &"hit1", &"OnJumpStart", 0, &"Idle", &"OnJumpStart", 1, &"jump_start", &"OnJumpEnd", 0, &"OnJumpStart", &"OnJumpEnd", 1, &"jump_end", &"OnMantle", 0, &"OnJumpEnd", &"OnMantle", 1, &"mantle", &"OnDie", 0, &"OnHit", &"OnDie", 1, &"Die", &"OnParry", 0, &"OnDie", &"OnParry", 1, &"Parry"]
|
||||
@@ -0,0 +1,14 @@
|
||||
[gd_resource type="AnimationNodeStateMachine" format=3 uid="uid://3r5oeg0ho0d4"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_73q32"]
|
||||
animation = &"idle"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_adm0b"]
|
||||
advance_mode = 2
|
||||
|
||||
[resource]
|
||||
states/Start/position = Vector2(100, 91)
|
||||
states/idle/node = SubResource("AnimationNodeAnimation_73q32")
|
||||
states/idle/position = Vector2(331, 91)
|
||||
transitions = ["Start", "idle", SubResource("AnimationNodeStateMachineTransition_adm0b")]
|
||||
graph_offset = Vector2(-82, -9)
|
||||
735
scenes/player_controller/components/head/head_system.tscn
Normal file
735
scenes/player_controller/components/head/head_system.tscn
Normal file
@@ -0,0 +1,735 @@
|
||||
[gd_scene format=3 uid="uid://0ysqmqphq6mq"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dtkdrnsmlwm67" path="res://scenes/player_controller/components/head/HeadSystem.cs" id="1_8abgy"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://ckr26s4e3fj1m" path="res://assets/meshes/swords/resources/fp_sword23.tres" id="2_c5qep"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://dogiv0piqfmfu" path="res://assets/meshes/swords/resources/fp_sword20.tres" id="3_1ay6d"]
|
||||
[ext_resource type="AnimationNodeBlendTree" uid="uid://c26yvcyyyj811" path="res://scenes/player_controller/components/head/fp_blend_tree.tres" id="3_r0h40"]
|
||||
[ext_resource type="Script" uid="uid://dnlxsrumw6ygp" path="res://addons/shaker/src/Vector3/shaker_component3D.gd" id="3_ubhf8"]
|
||||
[ext_resource type="Script" uid="uid://0tu2q57qqu4s" path="res://addons/shaker/data/Vector3/BaseShakerType3D.gd" id="4_1ay6d"]
|
||||
[ext_resource type="Script" uid="uid://ptaespkh1sk2" path="res://addons/shaker/data/Vector3/ShakerTypeNoiseShake3D.gd" id="5_sdjj3"]
|
||||
[ext_resource type="Script" uid="uid://mlwdmecg12xd" path="res://addons/shaker/data/Vector3/ShakerPreset3D.gd" id="6_ll12k"]
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_ubhf8"]
|
||||
frequency = 0.15
|
||||
fractal_octaves = 1
|
||||
|
||||
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_1ay6d"]
|
||||
noise = SubResource("FastNoiseLite_ubhf8")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_sdjj3"]
|
||||
script = ExtResource("5_sdjj3")
|
||||
noise_texture = SubResource("NoiseTexture3D_1ay6d")
|
||||
amplitude = Vector3(0.1, 0.1, 0.1)
|
||||
metadata/_custom_type_script = "uid://ptaespkh1sk2"
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_sdjj3"]
|
||||
frequency = 0.1
|
||||
|
||||
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_ll12k"]
|
||||
noise = SubResource("FastNoiseLite_sdjj3")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_dvot2"]
|
||||
script = ExtResource("5_sdjj3")
|
||||
noise_texture = SubResource("NoiseTexture3D_ll12k")
|
||||
amplitude = Vector3(0.02, 0.02, 0.02)
|
||||
metadata/_custom_type_script = "uid://ptaespkh1sk2"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_60ouj"]
|
||||
script = ExtResource("6_ll12k")
|
||||
PositionShake = Array[ExtResource("4_1ay6d")]([SubResource("Resource_sdjj3")])
|
||||
RotationShake = Array[ExtResource("4_1ay6d")]([SubResource("Resource_dvot2")])
|
||||
metadata/_custom_type_script = "uid://mlwdmecg12xd"
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_1ay6d"]
|
||||
frequency = 0.02
|
||||
fractal_octaves = 1
|
||||
|
||||
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_sdjj3"]
|
||||
noise = SubResource("FastNoiseLite_1ay6d")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ll12k"]
|
||||
script = ExtResource("5_sdjj3")
|
||||
noise_texture = SubResource("NoiseTexture3D_sdjj3")
|
||||
amplitude = Vector3(0.2, 0, 0)
|
||||
metadata/_custom_type_script = "uid://ptaespkh1sk2"
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_ll12k"]
|
||||
frequency = 0.02
|
||||
fractal_octaves = 1
|
||||
|
||||
[sub_resource type="NoiseTexture3D" id="NoiseTexture3D_se3kf"]
|
||||
noise = SubResource("FastNoiseLite_ll12k")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_0k6hv"]
|
||||
script = ExtResource("5_sdjj3")
|
||||
noise_texture = SubResource("NoiseTexture3D_se3kf")
|
||||
amplitude = Vector3(0.1, 0.2, 0.1)
|
||||
metadata/_custom_type_script = "uid://ptaespkh1sk2"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_se3kf"]
|
||||
script = ExtResource("6_ll12k")
|
||||
PositionShake = Array[ExtResource("4_1ay6d")]([SubResource("Resource_ll12k")])
|
||||
RotationShake = Array[ExtResource("4_1ay6d")]([SubResource("Resource_0k6hv")])
|
||||
metadata/_custom_type_script = "uid://mlwdmecg12xd"
|
||||
|
||||
[sub_resource type="Animation" id="Animation_urko7"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("../../FPRig/Sword:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.53640664, -0.7880347, -1.9288678)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("../../FPRig/Sword:rotation")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.083978735, -1.136043, 0.19867715)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("../../FPRig/Sword:scale")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(1.0000001, 1.0000001, 1.0000005)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("..:rotation")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0.00011616433)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("..:position")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("../../FPRig/Parry:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.22145952, -0.19867475, -1.3653086)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("../../FPRig/Parry:rotation")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.9350104, 3.0957325, -1.9789876)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("../../FPRig/Parry:visible")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
tracks/8/type = "bezier"
|
||||
tracks/8/imported = false
|
||||
tracks/8/enabled = true
|
||||
tracks/8/path = NodePath("../../FPRig/Parry:rotation:x")
|
||||
tracks/8/interp = 1
|
||||
tracks/8/loop_wrap = true
|
||||
tracks/8/keys = {
|
||||
"handle_modes": PackedInt32Array(0),
|
||||
"points": PackedFloat32Array(0.9350104, -0.15, 0, 0.15, 0),
|
||||
"times": PackedFloat32Array(0)
|
||||
}
|
||||
tracks/9/type = "bezier"
|
||||
tracks/9/imported = false
|
||||
tracks/9/enabled = true
|
||||
tracks/9/path = NodePath("../../FPRig/Parry:rotation:y")
|
||||
tracks/9/interp = 1
|
||||
tracks/9/loop_wrap = true
|
||||
tracks/9/keys = {
|
||||
"handle_modes": PackedInt32Array(0),
|
||||
"points": PackedFloat32Array(3.0957325, -0.15, 0, 0.15, 0),
|
||||
"times": PackedFloat32Array(0)
|
||||
}
|
||||
tracks/10/type = "bezier"
|
||||
tracks/10/imported = false
|
||||
tracks/10/enabled = true
|
||||
tracks/10/path = NodePath("../../FPRig/Parry:rotation:z")
|
||||
tracks/10/interp = 1
|
||||
tracks/10/loop_wrap = true
|
||||
tracks/10/keys = {
|
||||
"handle_modes": PackedInt32Array(0),
|
||||
"points": PackedFloat32Array(-1.9789876, -0.15, 0, 0.15, 0),
|
||||
"times": PackedFloat32Array(0)
|
||||
}
|
||||
tracks/11/type = "value"
|
||||
tracks/11/imported = false
|
||||
tracks/11/enabled = true
|
||||
tracks/11/path = NodePath("../../FPRig/Parry:scale")
|
||||
tracks/11/interp = 1
|
||||
tracks/11/loop_wrap = true
|
||||
tracks/11/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector3(1.2, 1.2, 1.2)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_sdjj3"]
|
||||
resource_name = "die"
|
||||
length = 1.0000033
|
||||
tracks/0/type = "method"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("../..")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(1),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"values": [{
|
||||
"args": [],
|
||||
"method": &"OnDeathAnimationFinished"
|
||||
}]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("../../FPRig/Sword:position")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.20000002, 0.4, 0.53333336, 0.8000001),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.53640664, -0.7880347, -1.9288678), Vector3(0.1057997, -0.21274538, -0.63147813), Vector3(0.53640664, 1.0949166, -1.9288678), Vector3(0.13969281, 3.1670854, 0.20333667), Vector3(0.14, -1.255, 0)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("../../FPRig/Sword:rotation")
|
||||
tracks/2/interp = 2
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.20000002, 0.4, 0.53333336, 0.8000001),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.083978735, -1.136043, 0.19867715), Vector3(-1.113491, -0.31576312, -0.983999), Vector3(-0.7104627, -0.98405164, -0.17152688), Vector3(0.111641094, -0.3489763, -2.955844), Vector3(0.11164107, -0.34897622, -2.955844)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("..:position")
|
||||
tracks/3/interp = 2
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.20000002, 0.6333333),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0), Vector3(0, -0.35507536, 0.32742357), Vector3(0.219, -1.5, 1.166)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("..:rotation")
|
||||
tracks/4/interp = 2
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0, 0.20000002, 0.6333333),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0.00011616433), Vector3(0, 0, -0.092299014), Vector3(0, 0, 1.2653637)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("../../FPRig/Parry:position")
|
||||
tracks/5/interp = 2
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.22145952, -0.19867475, -1.3653086), Vector3(-1.3323143, -0.19867463, -1.7020192)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("../../FPRig/Parry:rotation")
|
||||
tracks/6/interp = 2
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.9350104, 3.0957325, -1.9789876), Vector3(0.5242357, 2.32568, -3.0527115)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("../../FPRig/Parry:visible")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 1,
|
||||
"values": [true, false]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_r0h40"]
|
||||
resource_name = "hit1"
|
||||
length = 0.30000168
|
||||
step = 0.016666668
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("../../FPRig/Sword:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.11666667, 0.15, 0.21666667, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.53640664, -0.7880347, -1.9288678), Vector3(0.4045868, -0.4412415, -1.5352597), Vector3(-0.4799922, -0.5403832, -1.6861614), Vector3(-0.46995986, -0.53766656, -1.3638693), Vector3(-0.49520528, -0.5369735, -1.3145388), Vector3(-0.4048354, -0.5878634, -1.2836416)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("../../FPRig/Sword:rotation")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.11666667, 0.15, 0.21666667, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.083978735, -1.136043, 0.19867715), Vector3(-0.7788485, -2.0049822, -0.2951485), Vector3(-0.94931036, -0.5881021, -0.61733377), Vector3(-1.3252386, -0.102411434, 0.58406436), Vector3(-1.2938086, -0.18945412, 0.7334958), Vector3(-1.1484056, -0.2900904, 0.6867544)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("../../FPRig/Sword:scale")
|
||||
tracks/2/interp = 2
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.11666667, 0.15, 0.21666667, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(1.0000001, 1.0000001, 1.0000005), Vector3(1, 1.0004268, 1.0000002), Vector3(0.99999994, 1.2493719, 0.99999976), Vector3(1.0000001, 1.1750004, 1.0000004), Vector3(0.99999994, 0.99999994, 0.99999994), Vector3(1.0000001, 0.9999999, 1)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("..:rotation")
|
||||
tracks/3/interp = 2
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.083333336, 0.11666667, 0.2, 0.23333333, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0.00011616433), Vector3(0, -0.02617994, -0.02617994), Vector3(0, 0.02617994, 0.02617994), Vector3(0, 0, 0)]
|
||||
}
|
||||
tracks/4/type = "method"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("../..")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0.083333336, 0.23333333),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"values": [{
|
||||
"args": [],
|
||||
"method": &"OnHitboxActivated"
|
||||
}, {
|
||||
"args": [],
|
||||
"method": &"OnHitboxDeactivated"
|
||||
}]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("../../FPRig/Parry:position")
|
||||
tracks/5/interp = 2
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0, 0.033333335, 0.083333336, 0.16666667, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.22145952, -0.19867475, -1.3653086), Vector3(-0.0715476, -0.16325326, -0.8197592), Vector3(-0.36483923, -0.26392323, -1.3945884), Vector3(-0.8528395, -0.26392323, -1.2049117), Vector3(-0.8528395, -0.26392323, -1.2049117)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_0hyrq"]
|
||||
resource_name = "idle"
|
||||
length = 2.0
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("../../FPRig/Sword:position")
|
||||
tracks/0/interp = 2
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.3, 0.6, 1, 1.4),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.53640664, -0.7880347, -1.9288678), Vector3(0.53640664, -0.83580256, -1.9288678), Vector3(0.53640664, -0.86088884, -1.9288678), Vector3(0.53640664, -0.8256072, -1.9288678), Vector3(0.53640664, -0.7880347, -1.9288678)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("../../FPRig/Sword:rotation")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.3, 0.6, 1, 1.4),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.083978735, -1.136043, 0.19867715), Vector3(-0.06987281, -1.1365474, 0.20524277), Vector3(-0.05990464, -1.1368362, 0.20987195), Vector3(-0.06303402, -1.1367121, 0.2084137), Vector3(-0.083978735, -1.136043, 0.19867715)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("../../FPRig/Parry:position")
|
||||
tracks/2/interp = 2
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.3, 0.8000001),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.22145952, -0.19867475, -1.3653086), Vector3(-0.221, -0.211, -1.365), Vector3(-0.221, -0.16, -1.365)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("../../FPRig/Parry:rotation")
|
||||
tracks/3/interp = 2
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.3, 0.8000001),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.9350104, 3.0957325, -1.9789876), Vector3(0.93194425, 3.0397656, -2.0486145), Vector3(0.9362563, 3.1298003, -1.9366695)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_1ay6d"]
|
||||
resource_name = "jump_end"
|
||||
length = 0.26667002
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("..:rotation")
|
||||
tracks/0/interp = 2
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.13333334, 0.26666668),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0.00011616433), Vector3(-0.08726646, 0, 0), Vector3(0, 0, 0)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("..:position")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.26666668),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0), Vector3(0, -0.05, 0), Vector3(0, 0, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ubhf8"]
|
||||
resource_name = "jump_start"
|
||||
length = 0.26667002
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("..:position")
|
||||
tracks/0/interp = 2
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.26666668),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("..:rotation")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.13333334, 0.26666668),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0.00011616433), Vector3(-0.08726646, 0, 0), Vector3(0, 0, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_8abgy"]
|
||||
resource_name = "mantle"
|
||||
length = 0.3
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("..:rotation")
|
||||
tracks/0/interp = 2
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0.00011616433), Vector3(-0.5235988, 0, 0), Vector3(0, 0, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ll12k"]
|
||||
resource_name = "parry"
|
||||
length = 0.3
|
||||
step = 0.016666668
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("../../FPRig/Parry:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.083333336, 0.13333334, 0.16666667, 0.20000002, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.22145952, -0.19867475, -1.3653086), Vector3(0.08582078, -0.10871372, -0.57329714), Vector3(0.23993218, -0.07025133, -0.8836378), Vector3(0.2783246, -0.07025109, -0.9678366), Vector3(0.2897812, -0.07025109, -0.8572479), Vector3(-0.22145952, -0.19867475, -1.3653086)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("../../FPRig/Sword:position")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.15, 0.21666668, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0.53640664, -0.7880347, -1.9288678), Vector3(0.35144368, -0.7880347, -0.88497114), Vector3(0.87958574, -0.7880347, -1.4807583), Vector3(0.87958574, -0.7880347, -1.4807583), Vector3(0.53640664, -0.7880347, -1.9288678)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("../../FPRig/Sword:rotation")
|
||||
tracks/2/interp = 2
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.06666667, 0.15, 0.21666668, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(-0.083978735, -1.136043, 0.19867715), Vector3(0.012032291, -1.1376454, 0.24317425), Vector3(0.012032287, -1.8018653, 0.24317427), Vector3(0.012032287, -1.8018653, 0.24317427), Vector3(-0.083978735, -1.136043, 0.19867715)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("..:rotation")
|
||||
tracks/3/interp = 2
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.016666666, 0.1, 0.16666667, 0.2, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0.05235988), Vector3(0, -0.05235988, -0.10471976), Vector3(0, 0.02617994, 0.05235988), Vector3(0, 0, 0)]
|
||||
}
|
||||
tracks/4/type = "method"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("../..")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0.06666667, 0.18333334),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"values": [{
|
||||
"args": [],
|
||||
"method": &"OnParryboxActivated"
|
||||
}, {
|
||||
"args": [],
|
||||
"method": &"OnParryboxDeactivated"
|
||||
}]
|
||||
}
|
||||
tracks/5/type = "bezier"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("../../FPRig/Parry:rotation:x")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"handle_modes": PackedInt32Array(0, 0, 2, 2, 2, 0),
|
||||
"points": PackedFloat32Array(0.9350104, -0.15, 0, 0.033333335, 0.17374629, 0.98194534, -0.01666667, 0.016720235, 0, 0, 1.4891908, -0.03333334, -0.06340563, 0, 0, 1.5010982, -0.005555555, 0, 0, 0, 1.3694806, -0.008333336, 0.021936258, 0, 0, 0.9350104, -0.03333333, 0.17374629, 0.033333335, 0.17374629),
|
||||
"times": PackedFloat32Array(0, 0.083333336, 0.13333334, 0.16666667, 0.21666668, 0.3)
|
||||
}
|
||||
tracks/6/type = "bezier"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("../../FPRig/Parry:rotation:y")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"handle_modes": PackedInt32Array(0, 0, 2, 2, 2, 0),
|
||||
"points": PackedFloat32Array(3.0957325, -0.15, 0, 0.05, -0.045176744, 2.8761902, -0.033333335, 0.30117726, 0, 0, 2.9792244, -0.03333334, -0.25362277, 0, 0, 2.9158187, -0.016666666, 0.11096001, 0, 0, 2.8365617, -0.01666668, -0.18834376, 0, 0, 3.0957325, -0.050000012, -0.21161652, 0.05, -0.045176744),
|
||||
"times": PackedFloat32Array(0, 0.083333336, 0.13333334, 0.16666667, 0.21666668, 0.3)
|
||||
}
|
||||
tracks/7/type = "bezier"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("../../FPRig/Parry:rotation:z")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"handle_modes": PackedInt32Array(0, 0, 2, 2, 2, 0),
|
||||
"points": PackedFloat32Array(-1.9789876, -0.15, 0, 0.016666668, 0.6069969, -1.5225792, -0.01666667, 0.26527464, 0, 0, -0.9026986, -0.011111112, -0.101292565, 0, 0, -0.90269864, -0.005555555, 9.934108e-09, 0, 0, -1.642684, -0.008333336, 0.1233309, 0, 0, -1.9789876, -0.050000012, 0.13937998, 0.016666668, 0.6069969),
|
||||
"times": PackedFloat32Array(0, 0.083333336, 0.13333334, 0.16666667, 0.21666668, 0.3)
|
||||
}
|
||||
tracks/8/type = "value"
|
||||
tracks/8/imported = false
|
||||
tracks/8/enabled = true
|
||||
tracks/8/path = NodePath("../../FPRig/Parry:scale")
|
||||
tracks/8/interp = 2
|
||||
tracks/8/loop_wrap = true
|
||||
tracks/8/keys = {
|
||||
"times": PackedFloat32Array(0, 0.083333336, 0.13333334, 0.16666667, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector3(1, 1, 1), Vector3(1.2, 1.2, 1.2), Vector3(1.65, 1, 1), Vector3(1, 1, 1), Vector3(1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_0hyrq"]
|
||||
_data = {
|
||||
&"RESET": SubResource("Animation_urko7"),
|
||||
&"die": SubResource("Animation_sdjj3"),
|
||||
&"hit1": SubResource("Animation_r0h40"),
|
||||
&"idle": SubResource("Animation_0hyrq"),
|
||||
&"jump_end": SubResource("Animation_1ay6d"),
|
||||
&"jump_start": SubResource("Animation_ubhf8"),
|
||||
&"mantle": SubResource("Animation_8abgy"),
|
||||
&"parry": SubResource("Animation_ll12k")
|
||||
}
|
||||
|
||||
[node name="HeadSystem" type="Node3D" unique_id=2067407038]
|
||||
script = ExtResource("1_8abgy")
|
||||
WeaponMoveRotation = 20.0
|
||||
DisplacedWeaponSway = 1.0
|
||||
DisplacedWeaponAdjustmentSpeed = 8.0
|
||||
|
||||
[node name="FPRig" type="Node3D" parent="." unique_id=922968399]
|
||||
transform = Transform3D(0.9999998, 0, 0, 0, 1.0000002, 0, 0, 0, 1.0000002, 0, 0, 0)
|
||||
|
||||
[node name="Sword" type="Node3D" parent="FPRig" unique_id=1946191657]
|
||||
transform = Transform3D(0.42791694, -0.008550272, -0.9037781, 0.19667713, 0.9768738, 0.0838801, 0.88215953, -0.2136461, 0.41970265, 0.53640664, -0.7880347, -1.9288678)
|
||||
|
||||
[node name="SwordMesh" type="MeshInstance3D" parent="FPRig/Sword" unique_id=1887561286]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.99999994, 0, 0, 0, 1, 0, 0, 0)
|
||||
cast_shadow = 0
|
||||
mesh = ExtResource("2_c5qep")
|
||||
|
||||
[node name="Parry" type="Node3D" parent="FPRig" unique_id=1218775403]
|
||||
transform = Transform3D(0.43521196, -1.1178209, 0.03266725, -0.65402746, -0.2828554, -0.96552634, 0.9071047, 0.33236945, -0.711823, -0.22145952, -0.19867475, -1.3653086)
|
||||
|
||||
[node name="ParryMesh" type="MeshInstance3D" parent="FPRig/Parry" unique_id=1993291456]
|
||||
mesh = ExtResource("3_1ay6d")
|
||||
|
||||
[node name="CameraSmooth" type="Node3D" parent="." unique_id=2072010960]
|
||||
transform = Transform3D(0.9999998, -0.00011616429, 0, 0.00011616431, 0.99999964, 0, 0, 0, 0.99999976, 0, 0, 0)
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="CameraSmooth" unique_id=544372058]
|
||||
transform = Transform3D(1, 0, 0, 0, 1.0000002, 0, 0, 0, 1.0000001, 0, 0, 0)
|
||||
current = true
|
||||
fov = 90.0
|
||||
|
||||
[node name="OnGetHitShaker" type="Node3D" parent="CameraSmooth/Camera3D" unique_id=1644568585]
|
||||
transform = Transform3D(1, 0, 0, -7.275958e-12, 0.99999976, 0, 0, 0, 0.99999976, 0, 1.8626451e-09, 3.7252903e-09)
|
||||
script = ExtResource("3_ubhf8")
|
||||
intensity = 1.2
|
||||
duration = 0.5
|
||||
fade_in = 0.06470415
|
||||
fade_out = 0.46651623
|
||||
shakerPreset = SubResource("Resource_60ouj")
|
||||
metadata/_custom_type_script = "uid://dnlxsrumw6ygp"
|
||||
|
||||
[node name="OnHitShaker" type="Node3D" parent="CameraSmooth/Camera3D" unique_id=1445921461]
|
||||
transform = Transform3D(1, 0, 0, -7.275958e-12, 0.99999976, 0, 0, 0, 0.99999976, 0, 1.8626451e-09, 3.7252903e-09)
|
||||
script = ExtResource("3_ubhf8")
|
||||
duration = 0.3
|
||||
fade_in = 0.041234624
|
||||
fade_out = 0.5547845
|
||||
shakerPreset = SubResource("Resource_se3kf")
|
||||
metadata/_custom_type_script = "uid://dnlxsrumw6ygp"
|
||||
|
||||
[node name="CameraAnchor" type="Marker3D" parent="." unique_id=1554357312]
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1831491746]
|
||||
root_node = NodePath("../CameraSmooth/Camera3D")
|
||||
libraries/ = SubResource("AnimationLibrary_0hyrq")
|
||||
|
||||
[node name="AnimationTree" type="AnimationTree" parent="." unique_id=1817901670]
|
||||
root_node = NodePath("../CameraSmooth/Camera3D")
|
||||
tree_root = ExtResource("3_r0h40")
|
||||
anim_player = NodePath("../AnimationPlayer")
|
||||
parameters/OnHit/active = false
|
||||
parameters/OnHit/internal_active = false
|
||||
parameters/OnHit/request = 0
|
||||
parameters/OnJumpStart/active = false
|
||||
parameters/OnJumpStart/internal_active = false
|
||||
parameters/OnJumpStart/request = 0
|
||||
parameters/OnJumpEnd/active = false
|
||||
parameters/OnJumpEnd/internal_active = false
|
||||
parameters/OnJumpEnd/request = 0
|
||||
parameters/OnMantle/active = false
|
||||
parameters/OnMantle/internal_active = false
|
||||
parameters/OnMantle/request = 0
|
||||
parameters/OnDie/active = false
|
||||
parameters/OnDie/internal_active = false
|
||||
parameters/OnDie/request = 0
|
||||
parameters/OnParry/active = false
|
||||
parameters/OnParry/internal_active = false
|
||||
parameters/OnParry/request = 0
|
||||
|
||||
[connection signal="GotHit" from="." to="CameraSmooth/Camera3D/OnGetHitShaker" method="play_shake"]
|
||||
[connection signal="HitTarget" from="." to="CameraSmooth/Camera3D/OnHitShaker" method="play_shake"]
|
||||
114
scenes/player_controller/components/mantle/MantleSystem.cs
Normal file
114
scenes/player_controller/components/mantle/MantleSystem.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Godot;
|
||||
using RustyOptions;
|
||||
|
||||
namespace Movementtests.systems;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_follower.png")]
|
||||
public partial class MantleSystem: Node3D
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,2,0.01,suffix:m,or_greater")]
|
||||
public float MantleEndLocationDistanceFromWall { get; set; } = 1f;
|
||||
[Export(PropertyHint.Range, "0,10,0.1,suffix:m,or_greater")]
|
||||
public float MantleHeightCastStart { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0,10,0.01,suffix:m,or_greater")]
|
||||
public float MaxStepHeight = 0.5f;
|
||||
|
||||
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 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 void Init()
|
||||
{
|
||||
_wallInFrontCast3D = GetNode<ShapeCast3D>("WallInFrontCast3D");
|
||||
_mantleCast3D = GetNode<ShapeCast3D>("MantleCast3D");
|
||||
|
||||
_inAirWallDetect = GetNode<ShapeCast3D>("InAirWallDetect");
|
||||
_groundedWallDetect = GetNode<ShapeCast3D>("GroundedWallDetect");
|
||||
for (int i = 0; i < _wallProfileShapecasts.Length; i++)
|
||||
{
|
||||
_wallProfileShapecasts[i] = GetNode<ShapeCast3D>($"WallProfileShapeCasts/ShapeCast{i + 1}");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCastsEnabled(bool enabled)
|
||||
{
|
||||
foreach (var wallProfileShapecast in _wallProfileShapecasts)
|
||||
{
|
||||
wallProfileShapecast.SetEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMantle(bool isGrounded)
|
||||
{
|
||||
_inAirWallDetect.SetEnabled(!isGrounded);
|
||||
_groundedWallDetect.SetEnabled(isGrounded);
|
||||
var isColliding = _inAirWallDetect.IsColliding() || _groundedWallDetect.IsColliding();
|
||||
SetCastsEnabled(isColliding);
|
||||
|
||||
// Reset state
|
||||
IsMantlePossible = false;
|
||||
EndedOnOtherSideOfWall = false;
|
||||
FoundGround = false;
|
||||
if (!isColliding) return;
|
||||
|
||||
// Check if face something wall-like that should be climbable
|
||||
var collisionNormal = isGrounded ? _groundedWallDetect.GetCollisionNormal(0) : _inAirWallDetect.GetCollisionNormal(0);
|
||||
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
|
||||
if (!wallProfileShapecast.IsColliding() && !hasFirstProfileHit) continue;
|
||||
|
||||
var globalTargetPosition = wallProfileShapecast.GlobalPosition + wallProfileShapecast.TargetPosition;
|
||||
|
||||
// Got to the other side of the wall, we stop there
|
||||
if (!wallProfileShapecast.IsColliding())
|
||||
{
|
||||
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(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
|
||||
if (!hasFirstProfileHit) FirstMantleProfilePoint = centerOfShape;
|
||||
hasFirstProfileHit = true;
|
||||
previousProfilePoint = centerOfShape;
|
||||
MantleCurve.AddPoint(ToLocal(centerOfShape));
|
||||
}
|
||||
if (MantleCurve.PointCount == 1) return;
|
||||
|
||||
IsMantlePossible = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bja6tis1vaysu
|
||||
@@ -0,0 +1,4 @@
|
||||
[gd_resource type="SphereShape3D" format=3 uid="uid://dp2p8v7demb5j"]
|
||||
|
||||
[resource]
|
||||
radius = 0.25
|
||||
104
scenes/player_controller/components/mantle/mantle_system.tscn
Normal file
104
scenes/player_controller/components/mantle/mantle_system.tscn
Normal file
@@ -0,0 +1,104 @@
|
||||
[gd_scene format=3 uid="uid://wq1okogkhc5l"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bja6tis1vaysu" path="res://scenes/player_controller/components/mantle/MantleSystem.cs" id="1_2oobp"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_4coqe"]
|
||||
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
|
||||
|
||||
[node name="MantleSystem" type="Node3D" unique_id=1117790260]
|
||||
script = ExtResource("1_2oobp")
|
||||
MantleEndLocationDistanceFromWall = 0.2
|
||||
MantleHeightCastStart = 3.0
|
||||
|
||||
[node name="MantleCast3D" type="ShapeCast3D" parent="." unique_id=977434819]
|
||||
visible = false
|
||||
shape = SubResource("CapsuleShape3D_4coqe")
|
||||
target_position = Vector3(0, 0, 0)
|
||||
max_results = 1
|
||||
collision_mask = 256
|
||||
debug_shape_custom_color = Color(1, 0, 0, 1)
|
||||
|
||||
[node name="WallInFrontCast3D" type="ShapeCast3D" parent="." unique_id=774357590]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
visible = false
|
||||
shape = SubResource("SphereShape3D_2oobp")
|
||||
target_position = Vector3(0, 0, -1.5)
|
||||
max_results = 1
|
||||
collision_mask = 256
|
||||
debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1)
|
||||
|
||||
[node name="InAirWallDetect" type="ShapeCast3D" parent="." unique_id=276043236]
|
||||
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 = 256
|
||||
|
||||
[node name="GroundedWallDetect" type="ShapeCast3D" parent="." unique_id=1673208243]
|
||||
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 = 256
|
||||
|
||||
[node name="WallProfileShapeCasts" type="Node3D" parent="." unique_id=857147957]
|
||||
|
||||
[node name="ShapeCast1" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=1271662121]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
|
||||
[node name="ShapeCast2" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=147611166]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
|
||||
[node name="ShapeCast3" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=1248645023]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
|
||||
[node name="ShapeCast4" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=839558141]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
|
||||
[node name="ShapeCast5" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=886271592]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
|
||||
[node name="ShapeCast6" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=1927435390]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
|
||||
[node name="ShapeCast7" type="ShapeCast3D" parent="WallProfileShapeCasts" unique_id=2112972214]
|
||||
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.125, 0)
|
||||
collision_mask = 256
|
||||
196
scenes/player_controller/components/weapon/WeaponSystem.cs
Normal file
196
scenes/player_controller/components/weapon/WeaponSystem.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using Godot;
|
||||
using GodotStateCharts;
|
||||
using Movementtests.interfaces;
|
||||
using Movementtests.systems.damage;
|
||||
|
||||
namespace Movementtests.systems;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png")]
|
||||
public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
||||
{
|
||||
[Signal]
|
||||
public delegate void WeaponThrownEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void WeaponRetrievedEventHandler();
|
||||
|
||||
[Export]
|
||||
public RDamage RDamage { get; set; }
|
||||
[Export(PropertyHint.Range, "0,100,1,or_greater")]
|
||||
public float ThrowForce { get; set; } = 1f;
|
||||
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
|
||||
public float StraightThrowDuration { get; set; } = 0.1f;
|
||||
|
||||
private StateChart _weaponState;
|
||||
public StateChartState InHandState;
|
||||
public StateChartState FlyingState;
|
||||
public StateChartState PlantedState;
|
||||
|
||||
private ShapeCast3D _dashCast3D;
|
||||
|
||||
private Transform3D _startTransform;
|
||||
private Vector3 _startMeshRotation;
|
||||
|
||||
private Vector3 _throwDirection;
|
||||
public Vector3 PlantLocation { get; set; }
|
||||
public Vector3 PlantNormal { get; set; }
|
||||
public Node PlantObject { get; set; }
|
||||
|
||||
public MeshInstance3D WeaponLocationIndicator { get; set; }
|
||||
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; }
|
||||
public MeshInstance3D WeaponMesh { get; set; }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_weaponState = StateChart.Of(GetNode("StateChart"));
|
||||
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
|
||||
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying"));
|
||||
PlantedState = StateChartState.Of(GetNode("StateChart/Root/Planted"));
|
||||
|
||||
WeaponLocationIndicator = GetNode<MeshInstance3D>("WeaponLocationIndicator");
|
||||
WeaponLocationIndicator.Visible = false;
|
||||
WeaponLocationIndicatorMaterial = WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D;
|
||||
|
||||
WeaponMesh = GetNode<MeshInstance3D>("Weapon");
|
||||
_startMeshRotation = WeaponMesh.Rotation;
|
||||
|
||||
_startTransform = Transform;
|
||||
Freeze = true;
|
||||
Visible = false;
|
||||
|
||||
BodyEntered += OnThrownWeaponReachesGround;
|
||||
|
||||
InHandState.StateExited += WeaponLeft;
|
||||
InHandState.StateEntered += WeaponBack;
|
||||
}
|
||||
|
||||
public void WeaponLeft()
|
||||
{
|
||||
Visible = true;
|
||||
// WeaponLocationIndicator.Visible = true;
|
||||
EmitSignalWeaponThrown();
|
||||
}
|
||||
|
||||
public void WeaponBack()
|
||||
{
|
||||
Visible = false;
|
||||
// WeaponLocationIndicator.Visible = false;
|
||||
EmitSignalWeaponRetrieved();
|
||||
}
|
||||
|
||||
public void PlaceWeaponForTutorial(Vector3 location)
|
||||
{
|
||||
_weaponState.SendEvent("plant");
|
||||
Freeze = true;
|
||||
GlobalPosition = location;
|
||||
PlantLocation = location;
|
||||
}
|
||||
|
||||
public void ThrowWeapon(Vector3 end, bool hasHit, Vector3 collisionLocation, Vector3 collisionNormal, Node collidedObject)
|
||||
{
|
||||
_weaponState.SendEvent("throw");
|
||||
|
||||
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 1f, 1f);
|
||||
|
||||
_throwDirection = (end - GlobalPosition).Normalized();
|
||||
PlantLocation = collisionLocation;
|
||||
PlantNormal = collisionNormal;
|
||||
LookAt(end);
|
||||
|
||||
|
||||
var tween = GetTree().CreateTween();
|
||||
tween.SetParallel(true);
|
||||
tween.TweenProperty(this, "global_position", end, StraightThrowDuration);
|
||||
if (hasHit)
|
||||
{
|
||||
PlantObject = collidedObject;
|
||||
tween.Finished += PlantWeaponInWall;
|
||||
}
|
||||
else
|
||||
tween.Finished += ThrowWeaponOnCurve;
|
||||
}
|
||||
|
||||
public void PlantInEnemy(Node3D enemy)
|
||||
{
|
||||
GetTree().GetRoot().CallDeferred(Node.MethodName.RemoveChild, this);
|
||||
enemy.CallDeferred(Node.MethodName.AddChild, this);
|
||||
|
||||
if (enemy is IDamageable damageable)
|
||||
{
|
||||
damageable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
|
||||
}
|
||||
}
|
||||
|
||||
public void RethrowWeapon()
|
||||
{
|
||||
_weaponState.SendEvent("throw");
|
||||
_throwDirection = Vector3.Up;
|
||||
ThrowWeaponOnCurve();
|
||||
}
|
||||
|
||||
public void ThrowWeaponOnCurve()
|
||||
{
|
||||
Freeze = false;
|
||||
ApplyImpulse(_throwDirection * ThrowForce);
|
||||
}
|
||||
|
||||
public void PlantWeaponInWall()
|
||||
{
|
||||
_weaponState.SendEvent("plant");
|
||||
|
||||
Freeze = true;
|
||||
WeaponMesh.Rotation = _startMeshRotation;
|
||||
|
||||
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
|
||||
if (PlantObject is Node3D node)
|
||||
{
|
||||
PlantInEnemy(node);
|
||||
}
|
||||
CallDeferred(Node3D.MethodName.SetGlobalPosition, PlantLocation);
|
||||
CallDeferred(Node3D.MethodName.LookAt, GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
|
||||
}
|
||||
|
||||
public void OnThrownWeaponReachesGround(Node other)
|
||||
{
|
||||
PlantObject = other;
|
||||
PlantWeaponInWall();
|
||||
}
|
||||
|
||||
public void ResetWeapon()
|
||||
{
|
||||
_weaponState.SendEvent("recover");
|
||||
Transform = _startTransform;
|
||||
Freeze = true;
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
public override void _IntegrateForces(PhysicsDirectBodyState3D state)
|
||||
{
|
||||
base._IntegrateForces(state);
|
||||
|
||||
if (!Freeze && state.GetContactCount() > 0)
|
||||
{
|
||||
PlantLocation = state.GetContactLocalPosition(0);
|
||||
PlantNormal = state.GetContactLocalNormal(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!FlyingState.Active) return;
|
||||
|
||||
WeaponMesh.Rotation = new Vector3(WeaponMesh.Rotation.X, WeaponMesh.Rotation.Y + (float) delta * 100, WeaponMesh.Rotation.Z);
|
||||
//LookAt(GlobalTransform.Origin + LinearVelocity.Normalized(), Vector3.Up, false);
|
||||
}
|
||||
|
||||
public bool IsPlantedUnderPlatform()
|
||||
{
|
||||
return PlantedState.Active && GlobalRotation.X > 1 && Math.Abs(GlobalRotation.Y) > 1;
|
||||
}
|
||||
|
||||
public bool IsPlantedInWall()
|
||||
{
|
||||
return PlantedState.Active && Math.Abs(GlobalRotation.X) + Math.Abs(GlobalRotation.Z) < 0.3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://iii3wfto4t5b
|
||||
@@ -0,0 +1,5 @@
|
||||
extends MeshInstance3D
|
||||
|
||||
|
||||
func _on_weapon_retrieved_body_entered(body: Node3D) -> void:
|
||||
visible = false
|
||||
@@ -0,0 +1 @@
|
||||
uid://v4nnql2laqdn
|
||||
13
scenes/player_controller/components/weapon/weapon.tres
Normal file
13
scenes/player_controller/components/weapon/weapon.tres
Normal file
@@ -0,0 +1,13 @@
|
||||
[gd_resource type="CylinderMesh" format=3 uid="uid://b7vt0nk2htpo4"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jv82r"]
|
||||
use_z_clip_scale = true
|
||||
z_clip_scale = 0.9
|
||||
use_fov_override = true
|
||||
fov_override = 70.0
|
||||
|
||||
[resource]
|
||||
material = SubResource("StandardMaterial3D_jv82r")
|
||||
top_radius = 0.0
|
||||
bottom_radius = 0.05
|
||||
height = 1.0
|
||||
109
scenes/player_controller/components/weapon/weapon.tscn
Normal file
109
scenes/player_controller/components/weapon/weapon.tscn
Normal file
@@ -0,0 +1,109 @@
|
||||
[gd_scene format=3 uid="uid://ckm3d6k08a72u"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://iii3wfto4t5b" path="res://scenes/player_controller/components/weapon/WeaponSystem.cs" id="1_csqwk"]
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="2_m0v1h"]
|
||||
[ext_resource type="Script" uid="uid://couw105c3bde4" path="res://addons/godot_state_charts/state_chart.gd" id="3_5owyf"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://cho5fixitrbds" path="res://assets/meshes/swords/resources/sword23.tres" id="3_svc06"]
|
||||
[ext_resource type="Script" uid="uid://jk2jm1g6q853" path="res://addons/godot_state_charts/compound_state.gd" id="4_svc06"]
|
||||
[ext_resource type="Script" uid="uid://cytafq8i1y8qm" path="res://addons/godot_state_charts/atomic_state.gd" id="5_m0v1h"]
|
||||
[ext_resource type="Script" uid="uid://cf1nsco3w0mf6" path="res://addons/godot_state_charts/transition.gd" id="6_jpdh0"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_jpdh0"]
|
||||
script = ExtResource("2_m0v1h")
|
||||
DamageDealt = 2.0
|
||||
metadata/_custom_type_script = "uid://jitubgv6judn"
|
||||
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_avini"]
|
||||
height = 1.0
|
||||
radius = 0.1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_svc06"]
|
||||
render_priority = 1
|
||||
transparency = 1
|
||||
no_depth_test = true
|
||||
shading_mode = 0
|
||||
grow_amount = 0.1
|
||||
stencil_mode = 3
|
||||
stencil_flags = 1
|
||||
stencil_compare = 5
|
||||
metadata/_stencil_owned = true
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m0v1h"]
|
||||
next_pass = SubResource("StandardMaterial3D_svc06")
|
||||
transparency = 1
|
||||
albedo_color = Color(1, 1, 1, 0)
|
||||
z_clip_scale = 0.1
|
||||
stencil_mode = 2
|
||||
stencil_flags = 2
|
||||
stencil_color = Color(1, 1, 1, 1)
|
||||
stencil_outline_thickness = 0.1
|
||||
|
||||
[sub_resource type="SphereMesh" id="SphereMesh_jpdh0"]
|
||||
material = SubResource("StandardMaterial3D_m0v1h")
|
||||
|
||||
[node name="Weapon" type="RigidBody3D" unique_id=831063023]
|
||||
collision_layer = 65536
|
||||
collision_mask = 304
|
||||
continuous_cd = true
|
||||
contact_monitor = true
|
||||
max_contacts_reported = 1
|
||||
script = ExtResource("1_csqwk")
|
||||
RDamage = SubResource("Resource_jpdh0")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=884463982]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
|
||||
shape = SubResource("CylinderShape3D_avini")
|
||||
|
||||
[node name="Weapon" type="MeshInstance3D" parent="." unique_id=1970473659]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0.8673003)
|
||||
mesh = ExtResource("3_svc06")
|
||||
|
||||
[node name="WeaponLocationIndicator" type="MeshInstance3D" parent="." unique_id=406396593]
|
||||
mesh = SubResource("SphereMesh_jpdh0")
|
||||
|
||||
[node name="StateChart" type="Node" parent="." unique_id=1135887603]
|
||||
script = ExtResource("3_5owyf")
|
||||
metadata/_custom_type_script = "uid://couw105c3bde4"
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart" unique_id=1816439862]
|
||||
script = ExtResource("4_svc06")
|
||||
initial_state = NodePath("InHand")
|
||||
|
||||
[node name="ToPlanted" type="Node" parent="StateChart/Root" unique_id=357013486]
|
||||
script = ExtResource("6_jpdh0")
|
||||
to = NodePath("../Planted")
|
||||
event = &"plant"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="InHand" type="Node" parent="StateChart/Root" unique_id=1828871728]
|
||||
script = ExtResource("5_m0v1h")
|
||||
|
||||
[node name="ToFlying" type="Node" parent="StateChart/Root/InHand" unique_id=1644664016]
|
||||
script = ExtResource("6_jpdh0")
|
||||
to = NodePath("../../Flying")
|
||||
event = &"throw"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Flying" type="Node" parent="StateChart/Root" unique_id=861606667]
|
||||
script = ExtResource("5_m0v1h")
|
||||
|
||||
[node name="ToHand" type="Node" parent="StateChart/Root/Flying" unique_id=1236392249]
|
||||
script = ExtResource("6_jpdh0")
|
||||
to = NodePath("../../InHand")
|
||||
event = &"recover"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Planted" type="Node" parent="StateChart/Root" unique_id=1036062749]
|
||||
script = ExtResource("5_m0v1h")
|
||||
|
||||
[node name="ToFlying" type="Node" parent="StateChart/Root/Planted" unique_id=1472568793]
|
||||
script = ExtResource("6_jpdh0")
|
||||
to = NodePath("../../Flying")
|
||||
event = &"throw"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="ToHand" type="Node" parent="StateChart/Root/Planted" unique_id=627081934]
|
||||
script = ExtResource("6_jpdh0")
|
||||
to = NodePath("../../InHand")
|
||||
event = &"recover"
|
||||
delay_in_seconds = "0.0"
|
||||
11
scenes/player_controller/components/weapon/weapon_tuto.tres
Normal file
11
scenes/player_controller/components/weapon/weapon_tuto.tres
Normal file
@@ -0,0 +1,11 @@
|
||||
[gd_resource type="CylinderMesh" format=3 uid="uid://bhkbwvuft1bpg"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_f5qr4"]
|
||||
z_clip_scale = 0.9
|
||||
fov_override = 70.0
|
||||
|
||||
[resource]
|
||||
material = SubResource("StandardMaterial3D_f5qr4")
|
||||
top_radius = 0.0
|
||||
bottom_radius = 0.05
|
||||
height = 1.0
|
||||
Reference in New Issue
Block a user