complete project reorganization
This commit is contained in:
31
scenes/components/damage/CDamageable.cs
Normal file
31
scenes/components/damage/CDamageable.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_skull.png")]
|
||||
public partial class CDamageable : Node, IDamageable
|
||||
{
|
||||
public event Action<IDamageable, DamageRecord> DamageTaken;
|
||||
|
||||
[Export]
|
||||
public RDamageModifier[] DamageModifiers { get; set; }
|
||||
|
||||
|
||||
public DamageRecord TakeDamage(DamageRecord damageRecord)
|
||||
{
|
||||
var finalDamage = 0f;
|
||||
foreach (var damageable in DamageModifiers.ToIDamageables())
|
||||
finalDamage += damageable.TakeDamage(damageRecord).Damage.DamageDealt;
|
||||
var finalDamageRecord = damageRecord with { Damage = new RDamage(finalDamage, damageRecord.Damage.DamageType) };
|
||||
DamageTaken?.Invoke(this, finalDamageRecord);
|
||||
return finalDamageRecord;
|
||||
}
|
||||
|
||||
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||
{
|
||||
var finalDamage = 0f;
|
||||
foreach (var damageable in DamageModifiers.ToIDamageables())
|
||||
finalDamage += damageable.ComputeDamage(damageRecord).Damage.DamageDealt;
|
||||
return damageRecord with { Damage = new RDamage(finalDamage, damageRecord.Damage.DamageType) };
|
||||
}
|
||||
}
|
||||
1
scenes/components/damage/CDamageable.cs.uid
Normal file
1
scenes/components/damage/CDamageable.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b0u23nkpaimyc
|
||||
6
scenes/components/damage/CDamageable.tscn
Normal file
6
scenes/components/damage/CDamageable.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://hpsg4fqwrx1u"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="1_qp8bd"]
|
||||
|
||||
[node name="CDamageable" type="Node" unique_id=482221079]
|
||||
script = ExtResource("1_qp8bd")
|
||||
9
scenes/components/damage/EDamageTypes.cs
Normal file
9
scenes/components/damage/EDamageTypes.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Movementtests.systems.damage;
|
||||
|
||||
public enum EDamageTypes
|
||||
{
|
||||
Normal,
|
||||
Fire,
|
||||
Ice,
|
||||
Explosion,
|
||||
}
|
||||
1
scenes/components/damage/EDamageTypes.cs.uid
Normal file
1
scenes/components/damage/EDamageTypes.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dubmiwfuunxmu
|
||||
20
scenes/components/damage/RDamage.cs
Normal file
20
scenes/components/damage/RDamage.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.systems.damage;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_skull.png")]
|
||||
public partial class RDamage : Resource
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float DamageDealt { get; set;}
|
||||
|
||||
[Export]
|
||||
public EDamageTypes DamageType { get; set;}
|
||||
|
||||
public RDamage() : this(1.0f, EDamageTypes.Normal) {}
|
||||
public RDamage(float damageDealt, EDamageTypes damageType)
|
||||
{
|
||||
DamageDealt = damageDealt;
|
||||
DamageType = damageType;
|
||||
}
|
||||
}
|
||||
1
scenes/components/damage/RDamage.cs.uid
Normal file
1
scenes/components/damage/RDamage.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://jitubgv6judn
|
||||
43
scenes/components/damage/RDamageModifier.cs
Normal file
43
scenes/components/damage/RDamageModifier.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
using Movementtests.systems.damage;
|
||||
|
||||
[Icon("res://assets/ui/IconGodotNode/white/icon_freeze.png")]
|
||||
[GlobalClass]
|
||||
public partial class RDamageModifier : Resource, IDamageable
|
||||
{
|
||||
public event Action<IDamageable, DamageRecord> DamageTaken;
|
||||
|
||||
[Export]
|
||||
public EDamageTypes DamageType { get; set;}
|
||||
[Export]
|
||||
public float Modifier { get; set;}
|
||||
|
||||
public RDamageModifier() : this(EDamageTypes.Normal, 1.0f) {}
|
||||
public RDamageModifier(EDamageTypes damageType, float modifier)
|
||||
{
|
||||
Modifier = modifier;
|
||||
DamageType = damageType;
|
||||
}
|
||||
|
||||
public DamageRecord TakeDamage(DamageRecord damageRecord)
|
||||
{
|
||||
if (damageRecord.Damage.DamageType != DamageType)
|
||||
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
|
||||
|
||||
var finalDamage = damageRecord.Damage.DamageDealt * Modifier;
|
||||
var finalDamageRecord = damageRecord with { Damage = new RDamage(finalDamage, damageRecord.Damage.DamageType) };
|
||||
DamageTaken?.Invoke(this, finalDamageRecord);
|
||||
return finalDamageRecord;
|
||||
}
|
||||
|
||||
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||
{
|
||||
if (damageRecord.Damage.DamageType != DamageType)
|
||||
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
|
||||
|
||||
var finalDamage = damageRecord.Damage.DamageDealt * Modifier;
|
||||
return damageRecord with { Damage = new RDamage(finalDamage, damageRecord.Damage.DamageType) };
|
||||
}
|
||||
}
|
||||
1
scenes/components/damage/RDamageModifier.cs.uid
Normal file
1
scenes/components/damage/RDamageModifier.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b6y3ugfydvch0
|
||||
35
scenes/components/health/CHealth.cs
Normal file
35
scenes/components/health/CHealth.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_heart.png")]
|
||||
public partial class CHealth : Node, IHealthable
|
||||
{
|
||||
public event Action<IHealthable, HealthChangedRecord> HealthChanged;
|
||||
public event Action<IHealthable> HealthDepleted;
|
||||
|
||||
[Export]
|
||||
public RHealth RHealth { get; set; }
|
||||
|
||||
public float CurrentHealth { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
CurrentHealth = RHealth.StartingHealth;
|
||||
}
|
||||
|
||||
public HealthChangedRecord ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
||||
{
|
||||
var previousHealth = CurrentHealth;
|
||||
CurrentHealth -= damageRecord.Damage.DamageDealt;
|
||||
var record = new HealthChangedRecord(CurrentHealth, previousHealth, RHealth.StartingHealth);
|
||||
HealthChanged?.Invoke(this, record);
|
||||
|
||||
if (CurrentHealth <= 0)
|
||||
{
|
||||
CurrentHealth = 0;
|
||||
HealthDepleted?.Invoke(this);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
}
|
||||
1
scenes/components/health/CHealth.cs.uid
Normal file
1
scenes/components/health/CHealth.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bjwrpv3jpsc1e
|
||||
6
scenes/components/health/CHealth.tscn
Normal file
6
scenes/components/health/CHealth.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://c4ikbhojckpnc"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://scenes/components/health/CHealth.cs" id="1_75uyt"]
|
||||
|
||||
[node name="CHealth" type="Node" unique_id=1940090217]
|
||||
script = ExtResource("1_75uyt")
|
||||
14
scenes/components/health/CHealthbar.cs
Normal file
14
scenes/components/health/CHealthbar.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_heart.png")]
|
||||
public partial class CHealthbar : Sprite3D
|
||||
{
|
||||
private Healthbar _healthbar;
|
||||
public Healthbar Healthbar => _healthbar;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_healthbar = GetNode<Healthbar>("%Healthbar");
|
||||
}
|
||||
}
|
||||
1
scenes/components/health/CHealthbar.cs.uid
Normal file
1
scenes/components/health/CHealthbar.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://chfb3cjo6exga
|
||||
32
scenes/components/health/CHealthbar.tscn
Normal file
32
scenes/components/health/CHealthbar.tscn
Normal file
@@ -0,0 +1,32 @@
|
||||
[gd_scene format=3 uid="uid://bwx2um43k0ou4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://chfb3cjo6exga" path="res://scenes/components/health/CHealthbar.cs" id="1_w5itk"]
|
||||
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar/healthbar.tscn" id="2_w5itk"]
|
||||
|
||||
[sub_resource type="ViewportTexture" id="ViewportTexture_jkj2g"]
|
||||
viewport_path = NodePath("SubViewport")
|
||||
|
||||
[node name="CHealthBar" type="Sprite3D" unique_id=1527974573]
|
||||
billboard = 1
|
||||
double_sided = false
|
||||
no_depth_test = true
|
||||
texture = SubResource("ViewportTexture_jkj2g")
|
||||
script = ExtResource("1_w5itk")
|
||||
|
||||
[node name="SubViewport" type="SubViewport" parent="." unique_id=791051331]
|
||||
transparent_bg = true
|
||||
size = Vector2i(520, 20)
|
||||
|
||||
[node name="Healthbar" parent="SubViewport" unique_id=739464079 instance=ExtResource("2_w5itk")]
|
||||
unique_name_in_owner = true
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -120.0
|
||||
offset_top = -4.0
|
||||
offset_right = 120.0
|
||||
offset_bottom = 4.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
12
scenes/components/health/RDeathEffect.cs
Normal file
12
scenes/components/health/RDeathEffect.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_thunder.png")]
|
||||
public partial class RDeathEffect : Resource, IKillable
|
||||
{
|
||||
public void Kill(IHealthable source)
|
||||
{
|
||||
GD.Print($"Death Effect triggered on {source}");
|
||||
}
|
||||
}
|
||||
1
scenes/components/health/RDeathEffect.cs.uid
Normal file
1
scenes/components/health/RDeathEffect.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b4cwruitopcee
|
||||
16
scenes/components/health/RHealth.cs
Normal file
16
scenes/components/health/RHealth.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_heart.png")]
|
||||
public partial class RHealth : Resource
|
||||
{
|
||||
[Export]
|
||||
public float StartingHealth { get; set;}
|
||||
|
||||
public RHealth() : this(100.0f) {}
|
||||
public RHealth(float startingHealth)
|
||||
{
|
||||
StartingHealth = startingHealth;
|
||||
}
|
||||
}
|
||||
1
scenes/components/health/RHealth.cs.uid
Normal file
1
scenes/components/health/RHealth.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://baiapod3csndf
|
||||
26
scenes/components/knockback/CKnockback.cs
Normal file
26
scenes/components/knockback/CKnockback.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_wind.png")]
|
||||
public partial class CKnockback : Node3D, IKnockbackable
|
||||
{
|
||||
[Export] public RKnockback RKnockback { get; set;}
|
||||
|
||||
private KnockbackRecord _knockbackRecord = null;
|
||||
|
||||
public void RegisterKnockback(KnockbackRecord knockbackRecord)
|
||||
{
|
||||
_knockbackRecord = knockbackRecord;
|
||||
}
|
||||
|
||||
public Vector3 ComputeKnockback()
|
||||
{
|
||||
if (_knockbackRecord == null) return Vector3.Zero;
|
||||
|
||||
var knockbackDirection = GlobalPosition - _knockbackRecord.DamageRecord.SourceLocation;
|
||||
var finalKnockback = knockbackDirection.Normalized() * RKnockback.Modifier * _knockbackRecord.ForceMultiplier;
|
||||
_knockbackRecord = null;
|
||||
return finalKnockback;
|
||||
}
|
||||
}
|
||||
1
scenes/components/knockback/CKnockback.cs.uid
Normal file
1
scenes/components/knockback/CKnockback.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b8dprpcjeac7e
|
||||
13
scenes/components/knockback/CKnockback.tscn
Normal file
13
scenes/components/knockback/CKnockback.tscn
Normal file
@@ -0,0 +1,13 @@
|
||||
[gd_scene format=3 uid="uid://bctpe34ddamg5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b8dprpcjeac7e" path="res://scenes/components/knockback/CKnockback.cs" id="1_ix2yg"]
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="2_uqiml"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_gbu2d"]
|
||||
script = ExtResource("2_uqiml")
|
||||
Modifier = 1.0
|
||||
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
||||
|
||||
[node name="CKnockback" type="Node3D" unique_id=303705317]
|
||||
script = ExtResource("1_ix2yg")
|
||||
RKnockback = SubResource("Resource_gbu2d")
|
||||
16
scenes/components/knockback/RKnockback.cs
Normal file
16
scenes/components/knockback/RKnockback.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_wind.png")]
|
||||
public partial class RKnockback : Resource
|
||||
{
|
||||
[Export]
|
||||
public float Modifier { get; set;}
|
||||
|
||||
public RKnockback() : this(1.0f) {}
|
||||
public RKnockback(float modifier)
|
||||
{
|
||||
Modifier = modifier;
|
||||
}
|
||||
}
|
||||
1
scenes/components/knockback/RKnockback.cs.uid
Normal file
1
scenes/components/knockback/RKnockback.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b44cse62qru7j
|
||||
62
scenes/components/movement/CFlyingMovement.cs
Normal file
62
scenes/components/movement/CFlyingMovement.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Godot;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
namespace Movementtests.scenes.movement;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_path_follow.png")]
|
||||
public partial class CFlyingMovement : Node3D, IMoveable
|
||||
{
|
||||
[Export] public RMovement RMovement { get; set; }
|
||||
|
||||
[Export(PropertyHint.Layers3DPhysics)]
|
||||
public uint TerrainCollision { get; set; } = 1;
|
||||
|
||||
private bool _movingToDesiredHeight = true;
|
||||
private Vector3 _randomDirection;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_randomDirection = new Vector3(GD.RandRange(-1, 1), 1, GD.RandRange(-1, 1)).Normalized();
|
||||
}
|
||||
|
||||
public Vector3 ComputeVelocity(MovementInputs inputs)
|
||||
{
|
||||
var velocity = inputs.Velocity;
|
||||
var spaceState = GetWorld3D().DirectSpaceState;
|
||||
var target = inputs.TargetLocation;
|
||||
var direction = (target - GlobalPosition).Normalized();
|
||||
// Check if we have a direct line of sight to the player
|
||||
if (!_movingToDesiredHeight)
|
||||
{
|
||||
velocity = velocity.Lerp(direction * RMovement.Speed, (float) inputs.delta * RMovement.Acceleration);
|
||||
|
||||
var query = PhysicsRayQueryParameters3D.Create(GlobalPosition, target, TerrainCollision);
|
||||
var result = spaceState.IntersectRay(query);
|
||||
if (result.Count > 0)
|
||||
{
|
||||
_movingToDesiredHeight = true;
|
||||
_randomDirection = new Vector3(GD.RandRange(-1, 1), 1, GD.RandRange(-1, 1)).Normalized();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity = velocity.Lerp(_randomDirection * RMovement.Speed, (float) inputs.delta * RMovement.Acceleration);
|
||||
|
||||
var groundQuery = PhysicsRayQueryParameters3D.Create(GlobalPosition, GlobalPosition+Vector3.Down*RMovement.TargetHeight, TerrainCollision);
|
||||
var groundResult = spaceState.IntersectRay(groundQuery);
|
||||
if (groundResult.Count == 0)
|
||||
{
|
||||
velocity.Y = 0;
|
||||
|
||||
var query = PhysicsRayQueryParameters3D.Create(GlobalPosition, target, TerrainCollision);
|
||||
var result = spaceState.IntersectRay(query);
|
||||
if (result.Count == 0)
|
||||
{
|
||||
_movingToDesiredHeight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return velocity;
|
||||
}
|
||||
}
|
||||
1
scenes/components/movement/CFlyingMovement.cs.uid
Normal file
1
scenes/components/movement/CFlyingMovement.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cps1rbkxs3nvq
|
||||
6
scenes/components/movement/CFlyingMovement.tscn
Normal file
6
scenes/components/movement/CFlyingMovement.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://dmw5ibwrb483f"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cps1rbkxs3nvq" path="res://scenes/components/movement/CFlyingMovement.cs" id="1_i26q2"]
|
||||
|
||||
[node name="CFlyingMovement" type="Node3D" unique_id=138989060]
|
||||
script = ExtResource("1_i26q2")
|
||||
35
scenes/components/movement/CGroundedMovement.cs
Normal file
35
scenes/components/movement/CGroundedMovement.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Godot;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
namespace Movementtests.scenes.movement;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_path_follow.png")]
|
||||
public partial class CGroundedMovement : Node3D, IMoveable
|
||||
{
|
||||
[Export] public RMovement RMovement { get; set; }
|
||||
|
||||
[Export]
|
||||
public RayCast3D WallInFrontRayCast { get; set; }
|
||||
|
||||
|
||||
public Vector3 ComputeVelocity(MovementInputs inputs)
|
||||
{
|
||||
var velocity = inputs.Velocity;
|
||||
var target = inputs.TargetLocation;
|
||||
var direction = (target - GlobalPosition).Normalized();
|
||||
|
||||
var targetPlane = new Vector3(target.X, GlobalPosition.Y, target.Z);
|
||||
LookAt(targetPlane);
|
||||
float xAcc = (float) Mathf.Lerp(velocity.X, direction.X * RMovement.Speed, inputs.delta * RMovement.Acceleration);
|
||||
float zAcc = (float) Mathf.Lerp(velocity.Z, direction.Z * RMovement.Speed, inputs.delta * RMovement.Acceleration);
|
||||
velocity.X = xAcc;
|
||||
velocity.Z = zAcc;
|
||||
|
||||
if (WallInFrontRayCast.IsColliding())
|
||||
velocity.Y = RMovement.Speed;
|
||||
else if (!inputs.isOnFloor)
|
||||
velocity += inputs.gravity * (float)inputs.delta * RMovement.GravityModifier;
|
||||
|
||||
return velocity;
|
||||
}
|
||||
}
|
||||
1
scenes/components/movement/CGroundedMovement.cs.uid
Normal file
1
scenes/components/movement/CGroundedMovement.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bdag2eeixw2lt
|
||||
6
scenes/components/movement/CGroundedMovement.tscn
Normal file
6
scenes/components/movement/CGroundedMovement.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://dbr7ioio158ew"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bdag2eeixw2lt" path="res://scenes/components/movement/CGroundedMovement.cs" id="1_e0agf"]
|
||||
|
||||
[node name="CGroundedMovement" type="Node3D" unique_id=1833494224]
|
||||
script = ExtResource("1_e0agf")
|
||||
25
scenes/components/movement/RMovement.cs
Normal file
25
scenes/components/movement/RMovement.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_path_follow.png")]
|
||||
public partial class RMovement : Resource
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float Speed { get; set;}
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float Acceleration { get; set;}
|
||||
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
||||
public float GravityModifier { get; set;}
|
||||
|
||||
[Export(PropertyHint.Range, "0,20,1,or_greater")]
|
||||
public float TargetHeight { get; set;}
|
||||
|
||||
public RMovement() : this(1.0f, 0.0f, 0.0f, 0.0f) {}
|
||||
public RMovement(float speed, float acceleration, float gravityModifier, float targetHeight)
|
||||
{
|
||||
Speed = speed;
|
||||
Acceleration = acceleration;
|
||||
GravityModifier = gravityModifier;
|
||||
TargetHeight = targetHeight;
|
||||
}
|
||||
}
|
||||
1
scenes/components/movement/RMovement.cs.uid
Normal file
1
scenes/components/movement/RMovement.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dtpxijlnb2c5
|
||||
@@ -1,16 +1,16 @@
|
||||
[gd_scene format=3 uid="uid://cmlud1hwkd6sv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bn7sc6id7n166" path="res://scenes/enemies/Enemy.cs" id="1_q8l7o"]
|
||||
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://components/damage/RDamageModifier.cs" id="2_1bsgx"]
|
||||
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://scenes/components/damage/RDamageModifier.cs" id="2_1bsgx"]
|
||||
[ext_resource type="Resource" uid="uid://dg1xbjhyhgnnk" path="res://scenes/enemies/flying_enemy/flying_enemy_health.tres" id="2_ma2bq"]
|
||||
[ext_resource type="Resource" uid="uid://dgo65k2ceqfvy" path="res://scenes/enemies/flying_enemy/flying_enemy_damage.tres" id="2_on7rt"]
|
||||
[ext_resource type="Resource" uid="uid://bwqjaom4k7rc3" path="res://scenes/enemies/flying_enemy/flying_enemy_movement.tres" id="4_dejyg"]
|
||||
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://components/health/CHealth.cs" id="4_ys4jv"]
|
||||
[ext_resource type="PackedScene" uid="uid://dmw5ibwrb483f" path="res://components/movement/CFlyingMovement.tscn" id="7_vaeds"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://components/health/CHealthbar.tscn" id="7_ykkxn"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="8_on7rt"]
|
||||
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://components/damage/CDamageable.cs" id="8_uotso"]
|
||||
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://components/knockback/CKnockback.tscn" id="10_dejyg"]
|
||||
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://scenes/components/health/CHealth.cs" id="4_ys4jv"]
|
||||
[ext_resource type="PackedScene" uid="uid://dmw5ibwrb483f" path="res://scenes/components/movement/CFlyingMovement.tscn" id="7_vaeds"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_ykkxn"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="8_on7rt"]
|
||||
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="8_uotso"]
|
||||
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_dejyg"]
|
||||
[ext_resource type="Resource" uid="uid://dt7a1io5o0b8s" path="res://scenes/enemies/flying_enemy/flying_enemy_knockback.tres" id="11_mpa2u"]
|
||||
|
||||
[sub_resource type="ViewportTexture" id="ViewportTexture_ykkxn"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RDamage" format=3 uid="uid://dgo65k2ceqfvy"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://components/damage/RDamage.cs" id="1_h6law"]
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="1_h6law"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_h6law")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RHealth" format=3 uid="uid://dg1xbjhyhgnnk"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://components/health/RHealth.cs" id="1_jht15"]
|
||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="1_jht15"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_jht15")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RKnockback" format=3 uid="uid://dt7a1io5o0b8s"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://components/knockback/RKnockback.cs" id="1_yq03x"]
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="1_yq03x"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_yq03x")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RMovement" format=3 uid="uid://bwqjaom4k7rc3"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="1_3yq0a"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="1_3yq0a"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_3yq0a")
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://bn7sc6id7n166" path="res://scenes/enemies/Enemy.cs" id="1_r6506"]
|
||||
[ext_resource type="Resource" uid="uid://otfc2snh8umc" path="res://scenes/enemies/grounded_enemy/grounded_enemy_damage.tres" id="2_bn56u"]
|
||||
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://components/health/CHealth.cs" id="2_gsmti"]
|
||||
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://components/damage/RDamageModifier.cs" id="2_r3cnf"]
|
||||
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://scenes/components/health/CHealth.cs" id="2_gsmti"]
|
||||
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://scenes/components/damage/RDamageModifier.cs" id="2_r3cnf"]
|
||||
[ext_resource type="Resource" uid="uid://bohbojc68j7y1" path="res://scenes/enemies/grounded_enemy/grounded_enemy_health.tres" id="2_w4lm8"]
|
||||
[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="4_na24f"]
|
||||
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://components/damage/CDamageable.cs" id="7_1tw73"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://components/health/CHealthbar.tscn" id="7_18xwy"]
|
||||
[ext_resource type="PackedScene" uid="uid://dbr7ioio158ew" path="res://components/movement/CGroundedMovement.tscn" id="7_qyswd"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="8_6d4gl"]
|
||||
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://components/knockback/CKnockback.tscn" id="10_jqqi6"]
|
||||
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="7_1tw73"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_18xwy"]
|
||||
[ext_resource type="PackedScene" uid="uid://dbr7ioio158ew" path="res://scenes/components/movement/CGroundedMovement.tscn" id="7_qyswd"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="8_6d4gl"]
|
||||
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_jqqi6"]
|
||||
[ext_resource type="Resource" uid="uid://cektf6waf4s04" path="res://scenes/enemies/grounded_enemy/grounded_enemy_knockback.tres" id="11_8k3xb"]
|
||||
|
||||
[sub_resource type="ViewportTexture" id="ViewportTexture_18xwy"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RDamage" format=3 uid="uid://otfc2snh8umc"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://components/damage/RDamage.cs" id="1_y415a"]
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="1_y415a"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_y415a")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RHealth" format=3 uid="uid://bohbojc68j7y1"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://components/health/RHealth.cs" id="1_h6jgd"]
|
||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="1_h6jgd"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_h6jgd")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RKnockback" format=3 uid="uid://cektf6waf4s04"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://components/knockback/RKnockback.cs" id="1_vdia8"]
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="1_vdia8"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_vdia8")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="RMovement" format=3 uid="uid://bqq6uukbdfysr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="1_hsy8g"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="1_hsy8g"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_hsy8g")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[gd_scene format=3 uid="uid://duju3atqgltkg"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cnlu64l7oxvv3" path="res://scenes/explosion/Explosion.cs" id="1_82hkh"]
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://components/damage/RDamage.cs" id="2_hys74"]
|
||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="2_hys74"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ffdh3"]
|
||||
script = ExtResource("2_hys74")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://qup00a7x2sji"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c10qfkvmrm6uq" path="res://scenes/FixedDashTarget/FixedDashthroughTarget.cs" id="1_r0j7a"]
|
||||
[ext_resource type="Script" uid="uid://c10qfkvmrm6uq" path="res://scenes/fixed_dash_target/FixedDashthroughTarget.cs" id="1_r0j7a"]
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_nkm8n"]
|
||||
radius = 1.0
|
||||
42
scenes/lift/lift.gd
Normal file
42
scenes/lift/lift.gd
Normal file
@@ -0,0 +1,42 @@
|
||||
extends Node3D
|
||||
|
||||
var lift_already_used : bool = false
|
||||
|
||||
@export var end_location : Vector3 = Vector3.ZERO
|
||||
@export var lift_time : float = 1.0
|
||||
|
||||
@onready var button: MeshInstance3D = $Cylinder_001
|
||||
|
||||
var player : CharacterBody3D
|
||||
|
||||
func finished_climbing() -> void:
|
||||
player.SetAllowedInputsAll()
|
||||
|
||||
func start_climbing() -> void:
|
||||
var player_start_location = player.global_position
|
||||
var height_difference = end_location - global_position
|
||||
|
||||
var elevator_tween = get_tree().create_tween()
|
||||
elevator_tween.set_parallel(true)
|
||||
elevator_tween.set_ease(Tween.EASE_IN_OUT)
|
||||
elevator_tween.set_trans(Tween.TRANS_CUBIC)
|
||||
elevator_tween.tween_property(self, "global_position", end_location, lift_time)
|
||||
elevator_tween.tween_property(player, "global_position", player_start_location + height_difference, lift_time)
|
||||
elevator_tween.tween_callback(finished_climbing)
|
||||
|
||||
|
||||
func _on_area_3d_body_entered(body: Node3D) -> void:
|
||||
if lift_already_used:
|
||||
return
|
||||
|
||||
if is_instance_of(body, CharacterBody3D):
|
||||
player = body
|
||||
player.SetAllowedInputsMoveCamera()
|
||||
|
||||
lift_already_used = true
|
||||
|
||||
var button_tween = get_tree().create_tween()
|
||||
var button_final_pos = button.global_position + Vector3.DOWN * 0.35
|
||||
button_tween.tween_property(button, "global_position", button_final_pos, 0.3)
|
||||
button_tween.tween_callback(start_climbing)
|
||||
|
||||
1
scenes/lift/lift.gd.uid
Normal file
1
scenes/lift/lift.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c1w84vh3bqijr
|
||||
BIN
scenes/lift/lift.glb
Normal file
BIN
scenes/lift/lift.glb
Normal file
Binary file not shown.
42
scenes/lift/lift.glb.import
Normal file
42
scenes/lift/lift.glb.import
Normal file
@@ -0,0 +1,42 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cc2vcuaulfks3"
|
||||
path="res://.godot/imported/lift.glb-eca964bf25659b43c2944795be070692.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://scenes/lift/lift.glb"
|
||||
dest_files=["res://.godot/imported/lift.glb-eca964bf25659b43c2944795be070692.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
46
scenes/lift/lift.tscn
Normal file
46
scenes/lift/lift.tscn
Normal file
File diff suppressed because one or more lines are too long
21
scenes/player_controller/LICENSE
Normal file
21
scenes/player_controller/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 PolarBears studio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
1133
scenes/player_controller/PlayerController.tscn
Normal file
1133
scenes/player_controller/PlayerController.tscn
Normal file
File diff suppressed because it is too large
Load Diff
73
scenes/player_controller/PlayerUi.cs
Normal file
73
scenes/player_controller/PlayerUi.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
|
||||
public partial class PlayerUi : Control
|
||||
{
|
||||
private TextureRect[] _dashIcons = new TextureRect[3];
|
||||
private TextureRect _enemyTarget;
|
||||
private Healthbar _healthbar;
|
||||
|
||||
public enum TargetState
|
||||
{
|
||||
NoTarget,
|
||||
TargetWouldNotKill,
|
||||
TargetWouldKill
|
||||
}
|
||||
|
||||
public record TargetProperties(TargetState State, Vector2 Position);
|
||||
|
||||
[Export]
|
||||
public Color WouldKillColor { get; set; } = new Color("009c8f");
|
||||
[Export]
|
||||
public Color WouldNotKillColor { get; set; } = new Color("fc001c");
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_dashIcons[0] = GetNode<TextureRect>("%Dash1");
|
||||
_dashIcons[1] = GetNode<TextureRect>("%Dash2");
|
||||
_dashIcons[2] = GetNode<TextureRect>("%Dash3");
|
||||
|
||||
_enemyTarget = GetNode<TextureRect>("%EnemyTarget");
|
||||
_healthbar = GetNode<Healthbar>("%Healthbar");
|
||||
}
|
||||
|
||||
public void Initialize(float initialHealth)
|
||||
{
|
||||
_healthbar.Initialize(initialHealth);
|
||||
}
|
||||
|
||||
public void SetEnemyTargetProperties(TargetProperties targetProperties)
|
||||
{
|
||||
var (state, position) = targetProperties;
|
||||
|
||||
var visible = state != TargetState.NoTarget;
|
||||
|
||||
var modulation = state switch
|
||||
{
|
||||
TargetState.TargetWouldNotKill => WouldNotKillColor,
|
||||
TargetState.TargetWouldKill => WouldKillColor,
|
||||
_ => WouldNotKillColor
|
||||
};
|
||||
_enemyTarget.SetVisible(visible);
|
||||
_enemyTarget.SetPosition(position - _enemyTarget.Size / 2);
|
||||
_enemyTarget.SetModulate(modulation);
|
||||
}
|
||||
|
||||
|
||||
public void SetNumberOfDashesLeft(int numberOfDashes)
|
||||
{
|
||||
int index = 1;
|
||||
foreach (var dashIcon in _dashIcons)
|
||||
{
|
||||
dashIcon.SetVisible(index <= numberOfDashes);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnHealthChanged(IHealthable healthable, HealthChangedRecord healthChanged)
|
||||
{
|
||||
_healthbar.CurrentHealth = healthChanged.CurrentHealth;
|
||||
}
|
||||
}
|
||||
1
scenes/player_controller/PlayerUi.cs.uid
Normal file
1
scenes/player_controller/PlayerUi.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bhuwv2nlcrunt
|
||||
119
scenes/player_controller/audio/InteractiveSFX.tres
Normal file
119
scenes/player_controller/audio/InteractiveSFX.tres
Normal file
@@ -0,0 +1,119 @@
|
||||
[gd_resource type="AudioStreamInteractive" format=3 uid="uid://clfggn87oeg1s"]
|
||||
|
||||
[ext_resource type="AudioStream" uid="uid://dedx5ronjavvh" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Run 1.ogg" id="1_tkpjh"]
|
||||
[ext_resource type="AudioStream" uid="uid://gihwx3xm7qoq" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Run 2.ogg" id="2_npc7y"]
|
||||
[ext_resource type="AudioStream" uid="uid://qr5qyql01rf5" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Run 3.ogg" id="3_xfjxc"]
|
||||
[ext_resource type="AudioStream" uid="uid://blbvci0fvniy3" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Run 4.ogg" id="4_ycvo6"]
|
||||
[ext_resource type="AudioStream" uid="uid://d01n6qtsadqvm" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Run 5.ogg" id="5_5bvpy"]
|
||||
[ext_resource type="AudioStream" uid="uid://2joty7h4guqs" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Jump.ogg" id="6_w27l5"]
|
||||
[ext_resource type="AudioStream" uid="uid://d0pwtd271fukd" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Land.ogg" id="7_5j00h"]
|
||||
[ext_resource type="AudioStream" uid="uid://co335a0d00667" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Attack 1.ogg" id="8_r7v0u"]
|
||||
[ext_resource type="AudioStream" uid="uid://dtl4blkueud3n" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Attack 2.ogg" id="9_l756u"]
|
||||
[ext_resource type="AudioStream" uid="uid://bd8n4slwggxrq" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Attack 3.ogg" id="10_7b65l"]
|
||||
[ext_resource type="AudioStream" uid="uid://jwy682rlwm2v" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Impact Hit 1.ogg" id="11_447ch"]
|
||||
[ext_resource type="AudioStream" uid="uid://cn6j83octlmg1" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Impact Hit 2.ogg" id="12_1yt5p"]
|
||||
[ext_resource type="AudioStream" uid="uid://buqmqota12r4g" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Impact Hit 3.ogg" id="13_t5u7s"]
|
||||
[ext_resource type="AudioStream" uid="uid://cm4332loplxmb" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Blocked 1.ogg" id="14_qnngs"]
|
||||
[ext_resource type="AudioStream" uid="uid://dhw1imlbuu7nl" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Blocked 2.ogg" id="15_3j1dm"]
|
||||
[ext_resource type="AudioStream" uid="uid://bis0qp2jqrwl7" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Attacks/Sword Attacks Hits and Blocks/Sword Blocked 3.ogg" id="16_hln0b"]
|
||||
[ext_resource type="AudioStream" uid="uid://dka35ab4pudfn" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Footsteps/Dirt/Dirt Chain Jump.ogg" id="17_npc7y"]
|
||||
[ext_resource type="AudioStream" uid="uid://4rhskycj4qqp" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Spells/Fireball 1.ogg" id="18_ycvo6"]
|
||||
[ext_resource type="AudioStream" uid="uid://bk03bbt0bbdu4" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Waterfalls Rivers and Streams/Waterfall Loop.ogg" id="19_5bvpy"]
|
||||
[ext_resource type="AudioStream" uid="uid://dn04ssm4qonxs" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Spells/Fireball 2.ogg" id="19_5j00h"]
|
||||
[ext_resource type="AudioStream" uid="uid://bsb2crsm8gkmc" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Spells/Fireball 3.ogg" id="20_r7v0u"]
|
||||
[ext_resource type="AudioStream" uid="uid://4mx3c0ercvu1" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Spells/Rock Wall 1.ogg" id="21_r7v0u"]
|
||||
[ext_resource type="AudioStream" uid="uid://bg4ujtrihj1jl" path="res://assets/audio/sfx/Free Fantasy SFX Pack By TomMusic/OGG Files/SFX/Spells/Rock Wall 2.ogg" id="22_l756u"]
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_rs8q3"]
|
||||
random_pitch = 1.1
|
||||
streams_count = 5
|
||||
stream_0/stream = ExtResource("1_tkpjh")
|
||||
stream_1/stream = ExtResource("2_npc7y")
|
||||
stream_2/stream = ExtResource("3_xfjxc")
|
||||
stream_3/stream = ExtResource("4_ycvo6")
|
||||
stream_4/stream = ExtResource("5_5bvpy")
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_r7v0u"]
|
||||
random_pitch = 1.0999973
|
||||
streams_count = 3
|
||||
stream_0/stream = ExtResource("14_qnngs")
|
||||
stream_1/stream = ExtResource("15_3j1dm")
|
||||
stream_2/stream = ExtResource("16_hln0b")
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_i5yri"]
|
||||
random_pitch = 1.1
|
||||
streams_count = 3
|
||||
stream_0/stream = ExtResource("8_r7v0u")
|
||||
stream_1/stream = ExtResource("9_l756u")
|
||||
stream_2/stream = ExtResource("10_7b65l")
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_5cmm3"]
|
||||
random_pitch = 1.1
|
||||
streams_count = 3
|
||||
stream_0/stream = ExtResource("11_447ch")
|
||||
stream_1/stream = ExtResource("12_1yt5p")
|
||||
stream_2/stream = ExtResource("13_t5u7s")
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_jjm4g"]
|
||||
random_pitch = 1.1
|
||||
streams_count = 3
|
||||
stream_0/stream = ExtResource("14_qnngs")
|
||||
stream_1/stream = ExtResource("15_3j1dm")
|
||||
stream_2/stream = ExtResource("16_hln0b")
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_l756u"]
|
||||
random_pitch = 1.1
|
||||
streams_count = 3
|
||||
stream_0/stream = ExtResource("18_ycvo6")
|
||||
stream_1/stream = ExtResource("19_5j00h")
|
||||
stream_2/stream = ExtResource("20_r7v0u")
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_7b65l"]
|
||||
random_pitch = 1.1
|
||||
streams_count = 2
|
||||
stream_0/stream = ExtResource("21_r7v0u")
|
||||
stream_1/stream = ExtResource("22_l756u")
|
||||
|
||||
[resource]
|
||||
clip_count = 11
|
||||
clip_0/name = &"footsteps"
|
||||
clip_0/stream = SubResource("AudioStreamRandomizer_rs8q3")
|
||||
clip_0/auto_advance = 0
|
||||
clip_1/name = &"jump"
|
||||
clip_1/stream = ExtResource("6_w27l5")
|
||||
clip_1/auto_advance = 0
|
||||
clip_2/name = &"land"
|
||||
clip_2/stream = ExtResource("7_5j00h")
|
||||
clip_2/auto_advance = 0
|
||||
clip_3/name = &"mantle"
|
||||
clip_3/stream = ExtResource("17_npc7y")
|
||||
clip_3/auto_advance = 0
|
||||
clip_4/name = &"attacks"
|
||||
clip_4/stream = SubResource("AudioStreamRandomizer_i5yri")
|
||||
clip_4/auto_advance = 0
|
||||
clip_5/name = &"hits"
|
||||
clip_5/stream = SubResource("AudioStreamRandomizer_5cmm3")
|
||||
clip_5/auto_advance = 0
|
||||
clip_6/name = &"damage_taken"
|
||||
clip_6/stream = SubResource("AudioStreamRandomizer_jjm4g")
|
||||
clip_6/auto_advance = 0
|
||||
clip_7/name = &"dash"
|
||||
clip_7/stream = SubResource("AudioStreamRandomizer_l756u")
|
||||
clip_7/auto_advance = 0
|
||||
clip_8/name = &"slam"
|
||||
clip_8/stream = SubResource("AudioStreamRandomizer_7b65l")
|
||||
clip_8/auto_advance = 0
|
||||
clip_9/name = &"glide"
|
||||
clip_9/stream = ExtResource("19_5bvpy")
|
||||
clip_9/auto_advance = 0
|
||||
clip_10/name = &"parry"
|
||||
clip_10/stream = SubResource("AudioStreamRandomizer_r7v0u")
|
||||
clip_10/auto_advance = 0
|
||||
_transitions = {
|
||||
Vector2i(-1, -1): {
|
||||
"fade_beats": 1.0,
|
||||
"fade_mode": 4,
|
||||
"from_time": 0,
|
||||
"to_time": 1
|
||||
}
|
||||
}
|
||||
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
|
||||
4
scenes/player_controller/resources/PlayerShape.tres
Normal file
4
scenes/player_controller/resources/PlayerShape.tres
Normal file
@@ -0,0 +1,4 @@
|
||||
[gd_resource type="CapsuleShape3D" format=3 uid="uid://keseacdcooot"]
|
||||
|
||||
[resource]
|
||||
height = 1.7
|
||||
7
scenes/player_controller/resources/player_health.tres
Normal file
7
scenes/player_controller/resources/player_health.tres
Normal file
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="Resource" script_class="RHealth" format=3 uid="uid://bjyd801wvverk"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="1_tv6ah"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_tv6ah")
|
||||
metadata/_custom_type_script = "uid://baiapod3csndf"
|
||||
8
scenes/player_controller/resources/player_knockback.tres
Normal file
8
scenes/player_controller/resources/player_knockback.tres
Normal file
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="Resource" script_class="RKnockback" format=3 uid="uid://bs8b0oojixm4q"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="1_dthjm"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_dthjm")
|
||||
Modifier = 30.0
|
||||
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="Resource" script_class="RDamageModifier" format=3 uid="uid://dyru7mxo121w6"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://scenes/components/damage/RDamageModifier.cs" id="1_7i47t"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_7i47t")
|
||||
metadata/_custom_type_script = "uid://b6y3ugfydvch0"
|
||||
9
scenes/player_controller/scripts/AnimationPlayer.cs
Normal file
9
scenes/player_controller/scripts/AnimationPlayer.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class AnimationPlayer : Godot.AnimationPlayer
|
||||
{
|
||||
public void PlayCameraRotationOnDeath()
|
||||
{
|
||||
Play(Constants.PLAYERS_HEAD_ANIMATION_ON_DYING);
|
||||
}
|
||||
}
|
||||
1
scenes/player_controller/scripts/AnimationPlayer.cs.uid
Normal file
1
scenes/player_controller/scripts/AnimationPlayer.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bt8flen3mi28r
|
||||
48
scenes/player_controller/scripts/Bobbing.cs
Normal file
48
scenes/player_controller/scripts/Bobbing.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class Bobbing: Node3D
|
||||
{
|
||||
[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;
|
||||
|
||||
private Camera3D _camera;
|
||||
|
||||
public void Init(Camera3D cam)
|
||||
{
|
||||
_camera = cam;
|
||||
}
|
||||
|
||||
public struct CameraBobbingParams
|
||||
{
|
||||
public float Delta;
|
||||
public bool IsOnFloorCustom;
|
||||
public Vector3 Velocity;
|
||||
public float SettingsMultiplier;
|
||||
}
|
||||
|
||||
private float _bobbingAccumulator; // Constantly increases when player moves in X or/and Z axis
|
||||
|
||||
public void PerformCameraBobbing(CameraBobbingParams parameters)
|
||||
{
|
||||
if (parameters.IsOnFloorCustom)
|
||||
{
|
||||
// Head bob
|
||||
_bobbingAccumulator += parameters.Delta * parameters.Velocity.Length();
|
||||
|
||||
Vector3 newPositionForCamera = Vector3.Zero;
|
||||
|
||||
// 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 * parameters.SettingsMultiplier;
|
||||
newPositionForCamera.X = Mathf.Cos(_bobbingAccumulator * BobbingFrequency / 2.0f) * BobbingAmplitude * parameters.SettingsMultiplier;
|
||||
|
||||
_camera.Position = newPositionForCamera;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scenes/player_controller/scripts/Bobbing.cs.uid
Normal file
1
scenes/player_controller/scripts/Bobbing.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://g8idirw62qe0
|
||||
52
scenes/player_controller/scripts/CapsuleCollider.cs
Normal file
52
scenes/player_controller/scripts/CapsuleCollider.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class CapsuleCollider : CollisionShape3D
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,5.0,0.01,suffix:m,or_greater")]
|
||||
public float CapsuleDefaultHeight { get; set; } = 2.0f;
|
||||
[Export(PropertyHint.Range, "0,5.0,0.01,suffix:m,or_greater")]
|
||||
public float CapsuleCrouchHeight { get; set; } = 1.0f;
|
||||
|
||||
public float GetCurrentHeight() { return _shape.Height; }
|
||||
public float GetDefaultHeight() { return CapsuleDefaultHeight; }
|
||||
|
||||
private CapsuleShape3D _shape;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_shape = Shape as CapsuleShape3D;
|
||||
_shape.Height = CapsuleDefaultHeight;
|
||||
}
|
||||
|
||||
public bool IsCapsuleHeightLessThanNormal()
|
||||
{
|
||||
return _shape.Height < CapsuleDefaultHeight;
|
||||
}
|
||||
|
||||
public bool IsBetweenCrouchingAndNormalHeight()
|
||||
{
|
||||
return _shape.Height > CapsuleCrouchHeight && _shape.Height < CapsuleDefaultHeight;
|
||||
}
|
||||
|
||||
public bool IsDefaultHeight()
|
||||
{
|
||||
return Mathf.IsEqualApprox(_shape.Height, CapsuleDefaultHeight);
|
||||
}
|
||||
|
||||
public bool IsCrouchingHeight()
|
||||
{
|
||||
return Mathf.IsEqualApprox(_shape.Height, CapsuleCrouchHeight);
|
||||
}
|
||||
|
||||
public void Crouch()
|
||||
{
|
||||
_shape.Height = CapsuleCrouchHeight;
|
||||
}
|
||||
|
||||
public void Uncrouch()
|
||||
{
|
||||
_shape.Height = CapsuleDefaultHeight;
|
||||
}
|
||||
}
|
||||
1
scenes/player_controller/scripts/CapsuleCollider.cs.uid
Normal file
1
scenes/player_controller/scripts/CapsuleCollider.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dd1yrt7eiiyf4
|
||||
45
scenes/player_controller/scripts/FieldOfView.cs
Normal file
45
scenes/player_controller/scripts/FieldOfView.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class FieldOfView: Node3D
|
||||
{
|
||||
[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;
|
||||
|
||||
private Camera3D _camera;
|
||||
|
||||
public void Init(Camera3D cam)
|
||||
{
|
||||
_camera = cam;
|
||||
}
|
||||
|
||||
public struct FovParameters
|
||||
{
|
||||
public bool IsCrouchingHeight;
|
||||
public float Delta;
|
||||
public float SprintSpeed;
|
||||
public Vector3 Velocity;
|
||||
public float FOVMultiplier;
|
||||
}
|
||||
|
||||
public void PerformFovAdjustment(FovParameters parameters)
|
||||
{
|
||||
float velocityClamped = Mathf.Clamp(
|
||||
Mathf.Abs(parameters.Velocity.X) + Mathf.Abs(parameters.Velocity.Z),
|
||||
0.5f,
|
||||
parameters.SprintSpeed * 2.0f);
|
||||
|
||||
float targetFov = BaseFov + FovChangeFactor * velocityClamped * parameters.FOVMultiplier;
|
||||
|
||||
if (parameters.IsCrouchingHeight){
|
||||
targetFov = BaseFov - FovChangeFactor * velocityClamped * parameters.FOVMultiplier;
|
||||
}
|
||||
|
||||
_camera.Fov = Mathf.Lerp(_camera.Fov, targetFov, parameters.Delta * FovChangeSpeed);
|
||||
}
|
||||
}
|
||||
1
scenes/player_controller/scripts/FieldOfView.cs.uid
Normal file
1
scenes/player_controller/scripts/FieldOfView.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b6k73aj5povgv
|
||||
23
scenes/player_controller/scripts/Global.cs
Normal file
23
scenes/player_controller/scripts/Global.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public class Constants
|
||||
{
|
||||
// Shaders' parameters
|
||||
public const string DISTORTION_SHADER_SCREEN_DARKNESS = "screen_darkness";
|
||||
public const string DISTORTION_SHADER_DARKNESS_PROGRESSION = "darkness_progression";
|
||||
public const string DISTORTION_SHADER_UV_OFFSET = "uv_offset";
|
||||
public const string DISTORTION_SHADER_SIZE = "size";
|
||||
|
||||
public const string VIGNETTE_SHADER_MULTIPLIER = "multiplier";
|
||||
public const string VIGNETTE_SHADER_SOFTNESS = "softness";
|
||||
|
||||
public const string BLUR_SHADER_LIMIT = "limit";
|
||||
public const string BLUR_SHADER_BLUR = "blur";
|
||||
|
||||
// Animation
|
||||
public const string PLAYERS_HEAD_ANIMATION_ON_DYING = "players_head_on_dying";
|
||||
|
||||
// Math
|
||||
public const float ACCEPTABLE_TOLERANCE = 0.01f;
|
||||
}
|
||||
|
||||
1
scenes/player_controller/scripts/Global.cs.uid
Normal file
1
scenes/player_controller/scripts/Global.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://yrcg34scpt5k
|
||||
32
scenes/player_controller/scripts/Gravity.cs
Normal file
32
scenes/player_controller/scripts/Gravity.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class Gravity: Node3D
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float Weight { get; set; } = 3.0f;
|
||||
[Export(PropertyHint.Range, "0,2,0.01,or_greater")]
|
||||
public float StartVelocity { get; set; } = 1.0f;
|
||||
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
|
||||
public float DoubleJumpSpeedFactor { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
|
||||
public float JumpFromDashSpeedFactor { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
|
||||
public float JumpFromWallSpeedFactor { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float AdditionalGravityPower { get; set; } = 1f;
|
||||
|
||||
private float _gravity;
|
||||
|
||||
public void Init(float gravitySetting)
|
||||
{
|
||||
_gravity = gravitySetting;
|
||||
}
|
||||
|
||||
public float CalculateJumpForce() => _gravity * (StartVelocity / AdditionalGravityPower);
|
||||
public float CalculateJumpFromDashForce() => CalculateJumpForce() * JumpFromDashSpeedFactor;
|
||||
public float CalculateJumpFromWallForce() => CalculateJumpForce() * JumpFromWallSpeedFactor;
|
||||
public float CalculateDoubleJumpForce() => CalculateJumpForce() * DoubleJumpSpeedFactor;
|
||||
public float CalculateGravityForce() => _gravity * Weight;
|
||||
}
|
||||
1
scenes/player_controller/scripts/Gravity.cs.uid
Normal file
1
scenes/player_controller/scripts/Gravity.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bt0xv2q8iv1vn
|
||||
470
scenes/player_controller/scripts/HealthSystem.cs
Normal file
470
scenes/player_controller/scripts/HealthSystem.cs
Normal file
@@ -0,0 +1,470 @@
|
||||
using System;
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class HealthSystem : Node3D
|
||||
{
|
||||
new enum Rotation
|
||||
{
|
||||
NoRotation = 0,
|
||||
CameraRotationTriggered = 1,
|
||||
RotatingOnZAxis = 2,
|
||||
ReturningBack = 3,
|
||||
}
|
||||
|
||||
[ExportGroup("Health Metrics")]
|
||||
[ExportSubgroup("Amounts")]
|
||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
||||
public float MaxHealth { get; set; } = 100.0f;
|
||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
||||
public float CurrentHealth { get; set; } = 100.0f;
|
||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
||||
public float MinimalDamageUnit { get; set; } = 25.0f;
|
||||
[Export(PropertyHint.Range, "-100,0,0.1,or_smaller")]
|
||||
public float ThresholdVelYForDamage { get; set; } = -15.0f;
|
||||
[ExportSubgroup("Regeneration")]
|
||||
[Export(PropertyHint.Range, "0,10,0.01,suffix:s,or_greater")]
|
||||
public float SecondsBeforeRegeneration { get; set; } = 5.5f;
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float RegenerationSpeed { get; set; } = 10.0f;
|
||||
|
||||
[ExportGroup("Damage Camera Effects")]
|
||||
[ExportSubgroup("Camera Shake")]
|
||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
||||
public float RotationSpeed { get; set; } = 9.0f;
|
||||
[Export(PropertyHint.Range, "0,180,0.1,degrees")]
|
||||
public float RotationDegree { get; set; } = 14.0f;
|
||||
[ExportSubgroup("Visual Distortion")]
|
||||
// Screen darkness controls how dark the screen will be, where 0.0 - natural
|
||||
// color of the screen(unaltered) and 1.0 - black screen
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float ScreenDarknessMin { get; set; } = 0.0f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float ScreenDarknessMax { get; set; } = 0.3f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float DistortionSpeedMin { get; set; } = 0.0f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float DistortionSpeedMax { get; set; } = 0.6f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float DistortionSizeMin { get; set; } = 0.0f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float DistortionSizeMax { get; set; } = 1.0f;
|
||||
[ExportSubgroup("Vignetting")]
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float ActiveZoneMultiplierMin { get; set; } = 0.45f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float ActiveZoneMultiplierMax { get; set; } = 0.475f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01,or_greater")]
|
||||
public float MultiplierDeltaForAnimation { get; set; } = 0.066f;
|
||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
||||
public float Softness { get; set; } = 1.0f;
|
||||
[Export(PropertyHint.Range, "0.0,10,0.01")]
|
||||
public float SpeedMin { get; set; } = 2.95f;
|
||||
[Export(PropertyHint.Range, "0.0,10,0.01")]
|
||||
public float SpeedMax { get; set; } = 4.0f;
|
||||
|
||||
// Death / GameOver
|
||||
[ExportGroup("Death")]
|
||||
[ExportSubgroup("Before Fade Out")]
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_less,or_greater")]
|
||||
public float BlurLimitValueToStartFadeOut { get; set; } = 0.3f;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float BlurValueToStartFadeOut { get; set; } = 3.376f;
|
||||
[ExportSubgroup("Speeds")]
|
||||
[Export(PropertyHint.Range, "0.1,20.0,0.1,or_greater")]
|
||||
public float CameraDropSpeedOnDeath { get; set; } = 18.0f;
|
||||
[Export(PropertyHint.Range, "0.01,5.0,0.01,or_greater")]
|
||||
public float FadeOutSpeed { get; set; } = 0.11f;
|
||||
|
||||
[Export(PropertyHint.Range, "0.1,10,0.01,or_greater")]
|
||||
public float BlurLimitSpeedOnDeath { get; set; } = 0.9f;
|
||||
[Export(PropertyHint.Range, "0.1,10,0.01,or_greater")]
|
||||
public float BlurSpeedOnDeath { get; set; } = 1.5f;
|
||||
|
||||
[ExportSubgroup("Target values")]
|
||||
[Export(PropertyHint.Range, "0,5.0,0.01,suffix:m,or_greater")]
|
||||
public float CameraHeightOnDeath { get; set; } = 0.68f;
|
||||
[Export(PropertyHint.Range, "0,5.0,0.01,suffix:m,or_greater")]
|
||||
public float FadeOutTargetValue { get; set; } = 4.0f;
|
||||
|
||||
// TODO: add setter: BlurLimitValueToStartFadeOut should always be less than BlurLimitTargetValue
|
||||
// (control it in editor)
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float BlurLimitTargetValue { get; set; } = 0.5f;
|
||||
|
||||
// TODO: add setter: BlurValueToStartFadeOut should always be less than BlurTargetValue
|
||||
// (control it in editor)
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float BlurTargetValue { get; set; } = 7.0f;
|
||||
|
||||
[ExportSubgroup("Other")]
|
||||
[Export(PropertyHint.Range, "0.0,4.0,0.01,suffix:s,or_greater")]
|
||||
public float ScreenDarknessToReloadScene { get; set; } = 1.74f;
|
||||
|
||||
|
||||
// Required to hide Vignette effect
|
||||
private float _currentHealthInPrevFrame;
|
||||
|
||||
private float _currentVelocityYInAir;
|
||||
|
||||
private CharacterBody3D _characterBody3D;
|
||||
|
||||
private Camera3D _camera;
|
||||
private float _cameraInitialRotationZ;
|
||||
private float _targetRotationZAxis;
|
||||
private Rotation _cameraRotation = Rotation.NoRotation;
|
||||
private float _progressOnCamRotation;
|
||||
|
||||
private Vector2 _uvOffset = Vector2.Zero;
|
||||
private float _offsetResetThreshold = 5.0f;
|
||||
|
||||
private ShaderMaterial _distortionMaterial;
|
||||
|
||||
private float _timeAccumulator;
|
||||
|
||||
private float _currentSpeed;
|
||||
|
||||
private const float InitialMultiplierMidVal = 0.6f;
|
||||
private const float MultiplierMidValToHideVignette = 0.8f;
|
||||
private float _currentMultiplierMidValue;
|
||||
|
||||
private ShaderMaterial _vignetteMaterial;
|
||||
|
||||
private bool _deathAnimationPlayed;
|
||||
private float _screenDarknessOnDeath;
|
||||
private float _currentBlurLimit;
|
||||
private float _currentBlur;
|
||||
private float _currentScreenDarkness;
|
||||
|
||||
private bool _dead;
|
||||
private Node3D _head;
|
||||
private ShaderMaterial _blurMaterial;
|
||||
|
||||
public struct HealthSystemInitParams
|
||||
{
|
||||
public CharacterBody3D Parent;
|
||||
public Camera3D Camera;
|
||||
public Node3D Head;
|
||||
}
|
||||
|
||||
public void Init(HealthSystemInitParams initParams)
|
||||
{
|
||||
_currentHealthInPrevFrame = CurrentHealth;
|
||||
_currentMultiplierMidValue = InitialMultiplierMidVal;
|
||||
|
||||
_currentSpeed = SpeedMin;
|
||||
|
||||
_characterBody3D = initParams.Parent;
|
||||
_camera = initParams.Camera;
|
||||
|
||||
_head = initParams.Head;
|
||||
|
||||
// Resetting shaders' parameters
|
||||
|
||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_MULTIPLIER, 1.0f);
|
||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_SOFTNESS, 1.0f);
|
||||
|
||||
_distortionMaterial.SetShaderParameter(Constants.DISTORTION_SHADER_SCREEN_DARKNESS, 0.0f);
|
||||
_distortionMaterial.SetShaderParameter(Constants.DISTORTION_SHADER_DARKNESS_PROGRESSION, 0.0f);
|
||||
|
||||
_distortionMaterial.SetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_UV_OFFSET, new Vector2(0.0f, 0.0f));
|
||||
|
||||
_distortionMaterial.SetShaderParameter(Constants.DISTORTION_SHADER_SIZE, 0.0);
|
||||
|
||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_LIMIT, 0.0f);
|
||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_BLUR, 0.0f);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
float deltaConverted = (float)delta;
|
||||
|
||||
HandleDeath(deltaConverted);
|
||||
|
||||
HandleVignetteShader(deltaConverted);
|
||||
HandleDistortionShader(deltaConverted);
|
||||
|
||||
HandleCameraRotationOnHit(deltaConverted);
|
||||
HandleDamageOnFall();
|
||||
|
||||
HandleHealthRegeneration(deltaConverted);
|
||||
}
|
||||
|
||||
public void TakeDamage(float amount)
|
||||
{
|
||||
if (_dead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cameraRotation == Rotation.NoRotation)
|
||||
{
|
||||
_cameraRotation = Rotation.CameraRotationTriggered;
|
||||
}
|
||||
|
||||
CurrentHealth -= amount;
|
||||
CurrentHealth = Mathf.Clamp(CurrentHealth, 0, MaxHealth);
|
||||
|
||||
if (CurrentHealth == 0)
|
||||
{
|
||||
_dead = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_lastHitTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public float GetCurrentHealth() { return CurrentHealth; }
|
||||
|
||||
#if DEBUG
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (@event is InputEventKey eventKey)
|
||||
|
||||
if (eventKey.Pressed && eventKey.Keycode == Key.H)
|
||||
TakeDamage(MinimalDamageUnit);
|
||||
}
|
||||
#endif
|
||||
|
||||
public bool IsDead() { return _dead; }
|
||||
|
||||
private void HandleDeath(float delta)
|
||||
{
|
||||
if (!_dead) { return; }
|
||||
|
||||
if (!_deathAnimationPlayed)
|
||||
{
|
||||
_deathAnimationPlayed = true;
|
||||
}
|
||||
|
||||
Vector3 newPosition = _head.Position;
|
||||
newPosition.Y = Mathf.Lerp(newPosition.Y, CameraHeightOnDeath, CameraDropSpeedOnDeath * delta);
|
||||
|
||||
if (newPosition.Y < CameraHeightOnDeath) { newPosition.Y = CameraHeightOnDeath; }
|
||||
|
||||
_head.Position = newPosition;
|
||||
|
||||
_currentBlurLimit = Mathf.Lerp(
|
||||
_currentBlurLimit, BlurLimitTargetValue, BlurLimitSpeedOnDeath * delta);
|
||||
|
||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_LIMIT, _currentBlurLimit);
|
||||
|
||||
_currentBlur = Mathf.Lerp(_currentBlur, BlurTargetValue, BlurSpeedOnDeath * delta);
|
||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_BLUR, _currentBlur);
|
||||
|
||||
if (_currentBlurLimit >= BlurLimitValueToStartFadeOut && _currentBlur >= BlurValueToStartFadeOut)
|
||||
{
|
||||
float currentScreenDarknessVariant = (float)_distortionMaterial.GetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_SCREEN_DARKNESS);
|
||||
|
||||
_screenDarknessOnDeath = Mathf.Lerp(
|
||||
currentScreenDarknessVariant, FadeOutTargetValue, FadeOutSpeed * delta);
|
||||
|
||||
_distortionMaterial.SetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_SCREEN_DARKNESS, _screenDarknessOnDeath);
|
||||
|
||||
if (_screenDarknessOnDeath >= ScreenDarknessToReloadScene)
|
||||
{
|
||||
GD.Print("reload");
|
||||
// Reload the current scene
|
||||
GetTree().ReloadCurrentScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleVignetteShader(float delta)
|
||||
{
|
||||
if (Mathf.IsEqualApprox(CurrentHealth, MaxHealth))
|
||||
{
|
||||
_currentHealthInPrevFrame = CurrentHealth;
|
||||
_currentMultiplierMidValue = InitialMultiplierMidVal;
|
||||
_timeAccumulator = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
float healthNormalized = CurrentHealth / MaxHealth;
|
||||
float healthReverted = 1.0f - healthNormalized;
|
||||
|
||||
float newAnimationSpeed = Mathf.Lerp(SpeedMin, SpeedMax, healthReverted);
|
||||
_currentSpeed = Mathf.Lerp(_currentSpeed, newAnimationSpeed, delta);
|
||||
|
||||
float completeSinCycle = Mathf.Tau / _currentSpeed;
|
||||
|
||||
_timeAccumulator = Mathf.Wrap(_timeAccumulator + delta, 0.0f, completeSinCycle);
|
||||
|
||||
float rawAnimationWeight = Mathf.Sin(_timeAccumulator * _currentSpeed);
|
||||
|
||||
float animationWeight = Mathf.Abs(rawAnimationWeight);
|
||||
|
||||
float difference = _currentHealthInPrevFrame - CurrentHealth;
|
||||
|
||||
float newMultiplierMidValue;
|
||||
|
||||
if (difference < 0)
|
||||
{
|
||||
newMultiplierMidValue = Mathf.Lerp(
|
||||
MultiplierMidValToHideVignette, ActiveZoneMultiplierMin, healthReverted);
|
||||
} else
|
||||
{
|
||||
newMultiplierMidValue = Mathf.Lerp(
|
||||
ActiveZoneMultiplierMax, ActiveZoneMultiplierMin, healthReverted);
|
||||
}
|
||||
|
||||
_currentMultiplierMidValue = Mathf.Lerp(
|
||||
_currentMultiplierMidValue, newMultiplierMidValue, delta);
|
||||
|
||||
float multiplier = Mathf.Lerp(
|
||||
_currentMultiplierMidValue - MultiplierDeltaForAnimation,
|
||||
_currentMultiplierMidValue + MultiplierDeltaForAnimation,
|
||||
animationWeight * animationWeight
|
||||
);
|
||||
|
||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_MULTIPLIER, multiplier);
|
||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_SOFTNESS, Softness);
|
||||
|
||||
_currentHealthInPrevFrame = CurrentHealth;
|
||||
}
|
||||
|
||||
private void HandleDistortionShader(float delta)
|
||||
{
|
||||
if (Mathf.IsEqualApprox(CurrentHealth, MaxHealth))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float healthNormalized = CurrentHealth / MaxHealth;
|
||||
float healthReverted = 1 - healthNormalized;
|
||||
|
||||
_distortionMaterial.SetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_DARKNESS_PROGRESSION, healthReverted);
|
||||
|
||||
if (!_dead)
|
||||
{
|
||||
float screenDarkness = Mathf.Remap(
|
||||
healthReverted, 0, 1, ScreenDarknessMin, ScreenDarknessMax);
|
||||
|
||||
_distortionMaterial.SetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_SCREEN_DARKNESS, screenDarkness);
|
||||
}
|
||||
|
||||
float distortionSpeed = Mathf.Remap(
|
||||
healthReverted, 0.0f, 1.0f, DistortionSpeedMin, DistortionSpeedMax);
|
||||
|
||||
float offsetVal = delta * distortionSpeed;
|
||||
|
||||
_uvOffset += new Vector2(offsetVal, offsetVal);
|
||||
|
||||
_distortionMaterial.SetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_UV_OFFSET, _uvOffset);
|
||||
|
||||
if (_uvOffset.X > _offsetResetThreshold) { _uvOffset.X = 0.0f; _uvOffset.Y = 0.0f; }
|
||||
|
||||
float distortionSize = Mathf.Remap(
|
||||
healthReverted, 0.0f, 1.0f, DistortionSizeMin, DistortionSizeMax);
|
||||
|
||||
_distortionMaterial.SetShaderParameter(
|
||||
Constants.DISTORTION_SHADER_SIZE, distortionSize);
|
||||
}
|
||||
|
||||
private void RotateCameraOnZAxis(float delta, float targetAngleInRadians, Rotation rotationStateToSetOnFinish)
|
||||
{
|
||||
_progressOnCamRotation += delta * RotationSpeed;
|
||||
_progressOnCamRotation = Mathf.Clamp(_progressOnCamRotation, 0f, 1f);
|
||||
|
||||
float lerpedAngleZ = Mathf.LerpAngle(
|
||||
_camera.Rotation.Z,targetAngleInRadians, _progressOnCamRotation);
|
||||
|
||||
_camera.Rotation = new Vector3(_camera.Rotation.X, _camera.Rotation.Y, lerpedAngleZ);
|
||||
|
||||
float difference = Mathf.Abs(targetAngleInRadians - _camera.Rotation.Z);
|
||||
|
||||
if (difference < Constants.ACCEPTABLE_TOLERANCE)
|
||||
{
|
||||
_cameraRotation = rotationStateToSetOnFinish;
|
||||
_progressOnCamRotation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCameraRotationOnHit(float delta)
|
||||
{
|
||||
if (_cameraRotation == Rotation.NoRotation || _dead) return;
|
||||
|
||||
if (_cameraRotation == Rotation.CameraRotationTriggered)
|
||||
{
|
||||
if (GD.Randi() % 2 == 0)
|
||||
{
|
||||
_targetRotationZAxis = Mathf.DegToRad(RotationDegree * -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_targetRotationZAxis = Mathf.DegToRad(RotationDegree);
|
||||
}
|
||||
|
||||
_cameraRotation = Rotation.RotatingOnZAxis;
|
||||
}
|
||||
|
||||
if (_cameraRotation == Rotation.RotatingOnZAxis)
|
||||
{
|
||||
RotateCameraOnZAxis(delta, _targetRotationZAxis, Rotation.ReturningBack);
|
||||
}
|
||||
|
||||
if (_cameraRotation == Rotation.ReturningBack)
|
||||
{
|
||||
RotateCameraOnZAxis(delta, 0, Rotation.NoRotation);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDamageOnFall()
|
||||
{
|
||||
if (_dead) { return;}
|
||||
|
||||
if (!_characterBody3D.IsOnFloor())
|
||||
{
|
||||
_currentVelocityYInAir = _characterBody3D.Velocity.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_currentVelocityYInAir < ThresholdVelYForDamage && ThresholdVelYForDamage > 0)
|
||||
{
|
||||
float hit = Mathf.Remap(_currentVelocityYInAir,
|
||||
ThresholdVelYForDamage, ThresholdVelYForDamage - 9.0f,
|
||||
MinimalDamageUnit, MaxHealth);
|
||||
|
||||
GD.Print("Hit damage: ", hit);
|
||||
|
||||
TakeDamage(hit);
|
||||
}
|
||||
|
||||
_currentVelocityYInAir = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private DateTime? _lastHitTime;
|
||||
|
||||
private void HandleHealthRegeneration(float delta)
|
||||
{
|
||||
if (_lastHitTime == null || _dead) return;
|
||||
|
||||
DateTime lastHitTimeConverted = (DateTime)_lastHitTime;
|
||||
|
||||
double differenceInSeconds = (DateTime.UtcNow - lastHitTimeConverted).TotalSeconds;
|
||||
float differenceInSecondsConverted = (float)differenceInSeconds;
|
||||
|
||||
if (differenceInSecondsConverted < SecondsBeforeRegeneration)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Mathf.IsEqualApprox(CurrentHealth, MaxHealth))
|
||||
{
|
||||
CurrentHealth = MaxHealth;
|
||||
_lastHitTime = null;
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentHealth += delta * RegenerationSpeed;
|
||||
CurrentHealth = Mathf.Clamp(CurrentHealth, 0, MaxHealth);
|
||||
}
|
||||
}
|
||||
1
scenes/player_controller/scripts/HealthSystem.cs.uid
Normal file
1
scenes/player_controller/scripts/HealthSystem.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dv7v1ywmbvvcd
|
||||
41
scenes/player_controller/scripts/Mouse.cs
Normal file
41
scenes/player_controller/scripts/Mouse.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class Mouse : Node3D
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,0.1,0.001,or_greater")]
|
||||
public float Sensitivity { get; set; } = 0.004f;
|
||||
|
||||
private Node3D _head;
|
||||
private Camera3D _camera;
|
||||
|
||||
public delegate bool IsDead();
|
||||
|
||||
private IsDead _isPlayerDead;
|
||||
|
||||
public void Init(Node3D head, Camera3D cam, IsDead isDeadFunc)
|
||||
{
|
||||
Input.SetMouseMode(Input.MouseModeEnum.Captured);
|
||||
|
||||
_head = head;
|
||||
_camera = cam;
|
||||
_isPlayerDead = isDeadFunc;
|
||||
}
|
||||
|
||||
public void LookAround(Vector2 lookDir)
|
||||
{
|
||||
// Horizontal movement of head
|
||||
float angleForHorizontalRotation = lookDir.X * Sensitivity;
|
||||
_head.RotateY(angleForHorizontalRotation);
|
||||
|
||||
// Vertical movement of head
|
||||
Vector3 currentCameraRotation = _camera.Rotation;
|
||||
currentCameraRotation.X += Convert.ToSingle(lookDir.Y * Sensitivity);
|
||||
currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f));
|
||||
|
||||
_camera.Rotation = currentCameraRotation;
|
||||
}
|
||||
|
||||
}
|
||||
1
scenes/player_controller/scripts/Mouse.cs.uid
Normal file
1
scenes/player_controller/scripts/Mouse.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c6bx47wr7fbdm
|
||||
2225
scenes/player_controller/scripts/PlayerController.cs
Normal file
2225
scenes/player_controller/scripts/PlayerController.cs
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user