implemented player health, knockback, invicibility frames and hitstop
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Export (push) Successful in 9m56s

This commit is contained in:
2026-01-20 12:05:31 +01:00
parent 87a9fad005
commit 2e5fcb6a75
10 changed files with 206 additions and 39 deletions

View File

@@ -20,7 +20,6 @@ public partial class CHealth : Node, IHealthable
public void ReduceHealth(IDamageable source, DamageRecord damageRecord) public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
{ {
GD.Print(CurrentHealth);
CurrentHealth -= damageRecord.Damage.DamageDealt; CurrentHealth -= damageRecord.Damage.DamageDealt;
HealthChanged?.Invoke(this, CurrentHealth); HealthChanged?.Invoke(this, CurrentHealth);

View File

@@ -1,18 +1,22 @@
[gd_scene load_steps=52 format=3 uid="uid://bei4nhkf8lwdo"] [gd_scene load_steps=55 format=3 uid="uid://bei4nhkf8lwdo"]
[ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"] [ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"]
[ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"] [ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"]
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="3_cresl"] [ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="3_cresl"]
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://components/damage/CDamageable.cs" id="4_q7bng"] [ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://components/health/CHealth.tscn" id="3_q7bng"]
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://player_controller/resources/player_health.tres" id="4_m8gvy"]
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/base_mode/rotate_y.tres" id="4_rxwoh"] [ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"] [ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://components/damage/RDamageModifier.cs" id="5_q7bng"] [ext_resource type="PackedScene" uid="uid://hpsg4fqwrx1u" path="res://components/damage/CDamageable.tscn" id="5_jb43f"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://systems/inputs/base_mode/move_left.tres" id="5_q14ux"] [ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://systems/inputs/base_mode/move_left.tres" id="5_q14ux"]
[ext_resource type="Resource" uid="uid://dyru7mxo121w6" path="res://player_controller/resources/player_normal_damage_mod.tres" id="6_cmijs"]
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://systems/inputs/base_mode/move_right.tres" id="6_q7bng"] [ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://systems/inputs/base_mode/move_right.tres" id="6_q7bng"]
[ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://player_controller/Scripts/StairsSystem.cs" id="7_bmt5a"] [ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://player_controller/Scripts/StairsSystem.cs" id="7_bmt5a"]
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://systems/inputs/base_mode/move_front.tres" id="7_m8gvy"] [ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://systems/inputs/base_mode/move_front.tres" id="7_m8gvy"]
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://components/knockback/CKnockback.tscn" id="7_x835q"]
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://systems/inputs/base_mode/move_back.tres" id="8_jb43f"] [ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://systems/inputs/base_mode/move_back.tres" id="8_jb43f"]
[ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://systems/inputs/base_mode/aim_release.tres" id="8_lhb11"] [ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://systems/inputs/base_mode/aim_release.tres" id="8_lhb11"]
[ext_resource type="Resource" uid="uid://bs8b0oojixm4q" path="res://player_controller/resources/player_knockback.tres" id="8_m8gvy"]
[ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://systems/inputs/base_mode/aim_down.tres" id="8_obsfv"] [ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://systems/inputs/base_mode/aim_down.tres" id="8_obsfv"]
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="8_qu4wy"] [ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="8_qu4wy"]
[ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="9_nob5r"] [ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="9_nob5r"]
@@ -43,11 +47,6 @@
[ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://systems/dash/light-ring.jpg" id="32_lgpc8"] [ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://systems/dash/light-ring.jpg" id="32_lgpc8"]
[ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"] [ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"]
[sub_resource type="Resource" id="Resource_jb43f"]
script = ExtResource("5_q7bng")
Modifier = 3.0
metadata/_custom_type_script = "uid://b6y3ugfydvch0"
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
height = 1.7 height = 1.7
@@ -77,10 +76,9 @@ radius = 0.4
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"] [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"]
blend_mode = 1 blend_mode = 1
[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("CDamage")] [node name="Player" type="CharacterBody3D"]
collision_mask = 272 collision_mask = 272
script = ExtResource("1_poq2x") script = ExtResource("1_poq2x")
CDamage = NodePath("CDamageable")
WalkSpeed = 7.5 WalkSpeed = 7.5
AccelerationFloor = 4.0 AccelerationFloor = 4.0
DecelerationFloor = 3.0 DecelerationFloor = 3.0
@@ -118,10 +116,14 @@ WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 4.0 WallHugDownwardMaxSpeed = 4.0
WallHugHorizontalDeceleration = 1.0 WallHugHorizontalDeceleration = 1.0
[node name="CDamageable" type="Node" parent="."] [node name="CHealth" parent="." instance=ExtResource("3_q7bng")]
script = ExtResource("4_q7bng") RHealth = ExtResource("4_m8gvy")
DamageModifiers = Array[Object]([SubResource("Resource_jb43f")])
metadata/_custom_type_script = "uid://b0u23nkpaimyc" [node name="CDamageable" parent="." instance=ExtResource("5_jb43f")]
DamageModifiers = Array[Object]([ExtResource("6_cmijs")])
[node name="CKnockback" parent="." instance=ExtResource("7_x835q")]
RKnockback = ExtResource("8_m8gvy")
[node name="WallRunSnapper" type="RayCast3D" parent="."] [node name="WallRunSnapper" type="RayCast3D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
@@ -186,6 +188,7 @@ unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0)
collision_layer = 0 collision_layer = 0
collision_mask = 16 collision_mask = 16
monitoring = false
monitorable = false monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HeadSystem/WeaponHitbox"] [node name="CollisionShape3D" type="CollisionShape3D" parent="HeadSystem/WeaponHitbox"]
@@ -301,6 +304,13 @@ collision_mask = 256
target_position = Vector3(0, -2, 0) target_position = Vector3(0, -2, 0)
collision_mask = 256 collision_mask = 256
[node name="InvincibilityTime" type="Timer" parent="."]
one_shot = true
[node name="AttackCooldown" type="Timer" parent="."]
wait_time = 0.3
one_shot = true
[node name="DashCooldown" type="Timer" parent="."] [node name="DashCooldown" type="Timer" parent="."]
wait_time = 0.8 wait_time = 0.8
one_shot = true one_shot = true

View File

@@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Godot; using Godot;
using GodotStateCharts; using GodotStateCharts;
using Movementtests.addons.godot_state_charts.csharp; using Movementtests.addons.godot_state_charts.csharp;
@@ -9,7 +11,9 @@ using RustyOptions;
public partial class PlayerController : CharacterBody3D, public partial class PlayerController : CharacterBody3D,
IDamageable, IDamageable,
IDamageDealer IDamageDealer,
IHealthable,
IKnockbackable
{ {
// Enums // Enums
public enum AllowedInputs public enum AllowedInputs
@@ -68,8 +72,7 @@ public partial class PlayerController : CharacterBody3D,
[ExportGroup("Damage")] [ExportGroup("Damage")]
[Export] [Export]
public RDamage RDamage { get; set; } public RDamage RDamage { get; set; }
[Export] public Node CDamageable { get; set; }
public CDamageable CDamage { get; set; }
[ExportCategory("Movement")] [ExportCategory("Movement")]
[ExportGroup("Ground")] [ExportGroup("Ground")]
@@ -279,6 +282,8 @@ public partial class PlayerController : CharacterBody3D,
private Timer _simpleDashCooldownTimer; private Timer _simpleDashCooldownTimer;
private Timer _airborneDashCooldownTimer; private Timer _airborneDashCooldownTimer;
private Timer _powerCooldownTimer; private Timer _powerCooldownTimer;
private Timer _invincibilityTimer;
private Timer _attackCooldown;
// State chart // State chart
private StateChart _playerState; private StateChart _playerState;
@@ -317,6 +322,8 @@ public partial class PlayerController : CharacterBody3D,
private Transition _onGroundSlideJump; private Transition _onGroundSlideJump;
private Transition _onAirGlideDoubleJump; private Transition _onAirGlideDoubleJump;
private List<IDamageable> _hitEnemies = new List<IDamageable>();
public override void _Ready() public override void _Ready()
{ {
LoadSettings(); LoadSettings();
@@ -367,7 +374,28 @@ public partial class PlayerController : CharacterBody3D,
_playerHeight = playerShape!.Height; _playerHeight = playerShape!.Height;
_playerRadius = playerShape.Radius; _playerRadius = playerShape.Radius;
// Combat stuff
WeaponHitbox = GetNode<Area3D>("%WeaponHitbox"); WeaponHitbox = GetNode<Area3D>("%WeaponHitbox");
WeaponHitbox.Monitoring = false;
WeaponHitbox.BodyEntered += RegisterHitEnnemy;
CHealth = GetNode<Node>("CHealth");
if (CHealth is IHealthable healthable && RHealth != null)
{
healthable.RHealth = RHealth;
healthable.CurrentHealth = RHealth.StartingHealth;
}
CKnockback = GetNode<Node>("CKnockback");
if (CKnockback is IKnockbackable knockbackable && RKnockback != null) knockbackable.RKnockback = RKnockback;
CDamageable = GetNode<Node>("CDamageable");
if (CDamageable is IDamageable damageable)
{
damageable.DamageTaken += ReduceHealth;
damageable.DamageTaken += RegisterKnockback;
}
if (CHealth is IHealthable healthable2)
healthable2.HealthDepleted += Kill;
// State management // State management
_playerState = StateChart.Of(GetNode("StateChart")); _playerState = StateChart.Of(GetNode("StateChart"));
@@ -412,6 +440,8 @@ public partial class PlayerController : CharacterBody3D,
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir"); _timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
_simpleDashCooldownTimer = GetNode<Timer>("DashCooldown"); _simpleDashCooldownTimer = GetNode<Timer>("DashCooldown");
_airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown"); _airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown");
_invincibilityTimer = GetNode<Timer>("InvincibilityTime");
_attackCooldown = GetNode<Timer>("AttackCooldown");
/////////////////////////// ///////////////////////////
// Initialize components // // Initialize components //
@@ -419,6 +449,8 @@ public partial class PlayerController : CharacterBody3D,
// Camera stuff // Camera stuff
HeadSystem.Init(); HeadSystem.Init();
HeadSystem.HitboxActivated += OnHitboxActivated;
HeadSystem.HitboxDeactivated += OnHitboxDeactivated;
// Movement stuff // Movement stuff
// Getting universal setting from GODOT editor to be in sync // Getting universal setting from GODOT editor to be in sync
@@ -437,6 +469,9 @@ public partial class PlayerController : CharacterBody3D,
/////////////////////////// ///////////////////////////
// Signal setup /////////// // Signal setup ///////////
/////////////////////////// ///////////////////////////
_invincibilityTimer.Timeout += ResetInvincibility;
_attackCooldown.Timeout += ResetAttackCooldown;
_aiming.StatePhysicsProcessing += HandleAiming; _aiming.StatePhysicsProcessing += HandleAiming;
_aiming.StateEntered += OnAimingEntered; _aiming.StateEntered += OnAimingEntered;
_aiming.StateExited += ResetTimeScale; _aiming.StateExited += ResetTimeScale;
@@ -1267,6 +1302,7 @@ public partial class PlayerController : CharacterBody3D,
/////////////////////////// ///////////////////////////
private bool _isSlideInputDown = false; private bool _isSlideInputDown = false;
public void OnInputSlideStarted() public void OnInputSlideStarted()
{ {
_isSlideInputDown = true; _isSlideInputDown = true;
@@ -1701,6 +1737,7 @@ public partial class PlayerController : CharacterBody3D,
if (_currentInputBufferFrames > 0) _currentInputBufferFrames -= 1; if (_currentInputBufferFrames > 0) _currentInputBufferFrames -= 1;
LookAround(delta); LookAround(delta);
Velocity += ComputeKnockback();
MoveSlideAndHandleStairs((float) delta); MoveSlideAndHandleStairs((float) delta);
MantleSystem.ProcessMantle(_grounded.Active); MantleSystem.ProcessMantle(_grounded.Active);
@@ -1719,8 +1756,17 @@ public partial class PlayerController : CharacterBody3D,
public DamageRecord TakeDamage(DamageRecord damageRecord) public DamageRecord TakeDamage(DamageRecord damageRecord)
{ {
var finalDamage = CDamage.TakeDamage(damageRecord); if (CDamageable is not IDamageable damageable || _isInvincible)
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
var finalDamage = damageable.TakeDamage(damageRecord);
DamageTaken?.Invoke(this, finalDamage); DamageTaken?.Invoke(this, finalDamage);
TriggerHitstop();
_isInvincible = true;
_invincibilityTimer.Start();
return finalDamage; return finalDamage;
} }
@@ -1735,18 +1781,99 @@ public partial class PlayerController : CharacterBody3D,
} }
if (!WeaponSystem.InHandState.Active) return; if (!WeaponSystem.InHandState.Active) return;
if (!_canAttack) return;
_canAttack = false;
_attackCooldown.Start();
PerformHit(); PerformHit();
} }
public void ResetAttackCooldown()
{
_canAttack = true;
}
public void PerformHit() public void PerformHit()
{ {
HeadSystem.OnHit(); HeadSystem.OnHit();
}
var bodies = WeaponHitbox.GetOverlappingBodies(); public void OnHitboxActivated()
foreach (var body in bodies) {
WeaponHitbox.Monitoring = true;
}
public void OnHitboxDeactivated()
{
WeaponHitbox.Monitoring = false;
TriggerDamage();
}
public void RegisterHitEnnemy(Node3D body)
{
if (body is not IDamageable damageable) return;
_hitEnemies.Add(damageable);
}
public void TriggerDamage()
{
if (_hitEnemies.Count == 0) return;
foreach (var damageable in _hitEnemies)
{ {
if(body is IDamageable spawnable) damageable.TakeDamage(new DamageRecord(this, RDamage));
spawnable.TakeDamage(new DamageRecord(this, RDamage));
} }
_hitEnemies.Clear();
TriggerHitstop();
}
public void TriggerHitstop()
{
Engine.SetTimeScale(0.01);
var timer = GetTree().CreateTimer(0.1, true, false, true);
timer.Timeout += OnHitstopEnded;
}
public void OnHitstopEnded()
{
ResetTimeScale();
}
public Node CHealth { get; set; }
public Node CKnockback { get; set; }
public event Action<IHealthable, float> HealthChanged;
public event Action<IHealthable> HealthDepleted;
public RHealth RHealth { get; set; }
public float CurrentHealth { get; set; }
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
{
if (CHealth is not IHealthable healthable) return;
healthable.ReduceHealth(source, damageRecord);
HealthChanged?.Invoke(this, healthable.CurrentHealth);
}
public RKnockback RKnockback { get; set; }
public void RegisterKnockback(IDamageable source, DamageRecord damageRecord)
{
if (CKnockback is not IKnockbackable knockbackable) return;
knockbackable.RegisterKnockback(source, damageRecord);
}
public Vector3 ComputeKnockback()
{
if (CKnockback is not IKnockbackable knockbackable) return Vector3.Zero;
return knockbackable.ComputeKnockback();
}
public void Kill(IHealthable source)
{
GD.Print("Player died!");
}
private bool _isInvincible;
private bool _canAttack = true;
public void ResetInvincibility()
{
_isInvincible = false;
} }
} }

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="RHealth" load_steps=2 format=3 uid="uid://bjyd801wvverk"]
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://components/health/RHealth.cs" id="1_tv6ah"]
[resource]
script = ExtResource("1_tv6ah")
StartingHealth = 1.0
metadata/_custom_type_script = "uid://baiapod3csndf"

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="RKnockback" load_steps=2 format=3 uid="uid://bs8b0oojixm4q"]
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://components/knockback/RKnockback.cs" id="1_dthjm"]
[resource]
script = ExtResource("1_dthjm")
Modifier = 30.0
metadata/_custom_type_script = "uid://b44cse62qru7j"

View File

@@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="RDamageModifier" load_steps=2 format=3 uid="uid://dyru7mxo121w6"]
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://components/damage/RDamageModifier.cs" id="1_7i47t"]
[resource]
script = ExtResource("1_7i47t")
metadata/_custom_type_script = "uid://b6y3ugfydvch0"

View File

@@ -73,7 +73,6 @@ public partial class Enemy : CharacterBody3D,
public void SetupSignals() public void SetupSignals()
{ {
_damageBox.BodyEntered += OnDamageBoxTriggered;
if (CDamage is IDamageable damageable) if (CDamage is IDamageable damageable)
{ {
damageable.DamageTaken += ReduceHealth; damageable.DamageTaken += ReduceHealth;
@@ -84,6 +83,9 @@ public partial class Enemy : CharacterBody3D,
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
// Only trigger gameplay related effects 4 times per second
if(Engine.GetPhysicsFrames() % 15 == 0) ProcessGameplay(delta);
var targetPlanar = new Vector3(Target.GlobalPosition.X, GlobalPosition.Y, Target.GlobalPosition.Z); var targetPlanar = new Vector3(Target.GlobalPosition.X, GlobalPosition.Y, Target.GlobalPosition.Z);
LookAt(targetPlanar); LookAt(targetPlanar);
@@ -99,20 +101,22 @@ public partial class Enemy : CharacterBody3D,
MoveAndSlide(); MoveAndSlide();
} }
public void ProcessGameplay(double delta)
{
var bodies = _damageBox.GetOverlappingBodies();
foreach (var body in bodies)
{
if(body is IDamageable spawnable)
spawnable.TakeDamage(new DamageRecord(this, RDamage));
}
}
public Vector3 ComputeVelocity(MovementInputs inputs) public Vector3 ComputeVelocity(MovementInputs inputs)
{ {
if (CMovement is not IMoveable movement) return Vector3.Zero; if (CMovement is not IMoveable movement) return Vector3.Zero;
return movement!.ComputeVelocity(inputs); return movement!.ComputeVelocity(inputs);
} }
public void OnDamageBoxTriggered(Node3D body)
{
if (body is not IDamageable damageable) return;
var damageRecord = new DamageRecord(this, RDamage);
damageable.TakeDamage(damageRecord);
}
public DamageRecord TakeDamage(DamageRecord damageRecord) public DamageRecord TakeDamage(DamageRecord damageRecord)
{ {
if (CDamage is not IDamageable damageable) if (CDamage is not IDamageable damageable)
@@ -120,8 +124,6 @@ public partial class Enemy : CharacterBody3D,
var finalDamage = damageable.TakeDamage(damageRecord); var finalDamage = damageable.TakeDamage(damageRecord);
DamageTaken?.Invoke(this, finalDamage); DamageTaken?.Invoke(this, finalDamage);
GD.Print($"Received damage: {finalDamage.Damage.DamageDealt}");
return finalDamage; return finalDamage;
} }
@@ -129,6 +131,7 @@ public partial class Enemy : CharacterBody3D,
{ {
if (CHealth is not IHealthable healthable) return; if (CHealth is not IHealthable healthable) return;
healthable.ReduceHealth(source, damageRecord); healthable.ReduceHealth(source, damageRecord);
HealthChanged?.Invoke(this, healthable.CurrentHealth);
} }
public void Kill(IHealthable source) public void Kill(IHealthable source)

View File

@@ -4,5 +4,5 @@
[resource] [resource]
script = ExtResource("1_yq03x") script = ExtResource("1_yq03x")
Modifier = 10.0 Modifier = 20.0
metadata/_custom_type_script = "uid://b44cse62qru7j" metadata/_custom_type_script = "uid://b44cse62qru7j"

View File

@@ -4,5 +4,5 @@
[resource] [resource]
script = ExtResource("1_vdia8") script = ExtResource("1_vdia8")
Modifier = 10.0 Modifier = 30.0
metadata/_custom_type_script = "uid://b44cse62qru7j" metadata/_custom_type_script = "uid://b44cse62qru7j"

View File

@@ -6,6 +6,11 @@ namespace Movementtests.systems;
public partial class HeadSystem : Node3D public partial class HeadSystem : Node3D
{ {
[Signal]
public delegate void HitboxActivatedEventHandler();
[Signal]
public delegate void HitboxDeactivatedEventHandler();
public record CameraParameters( public record CameraParameters(
double Delta, double Delta,
Vector2 LookDir, Vector2 LookDir,
@@ -111,12 +116,12 @@ public partial class HeadSystem : Node3D
public void OnHitboxActivated() public void OnHitboxActivated()
{ {
GD.Print("Hitbox activated"); EmitSignalHitboxActivated();
} }
public void OnHitboxDeactivated() public void OnHitboxDeactivated()
{ {
GD.Print("Hitbox deactivated"); EmitSignalHitboxDeactivated();
} }
public void LookAround(CameraParameters inputs) public void LookAround(CameraParameters inputs)