better healthbars and one for the player as well
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 42s
Create tag and build when new code gets to main / Test (push) Successful in 6m13s
Create tag and build when new code gets to main / Export (push) Successful in 7m5s

This commit is contained in:
2026-01-26 18:09:29 +01:00
parent 2fdc9c7ca8
commit ddf1bd019b
12 changed files with 190 additions and 49 deletions

View File

@@ -1,26 +1,14 @@
using Godot; using Godot;
using System; using System;
using Movementtests.interfaces;
[GlobalClass] [GlobalClass]
public partial class CHealthbar : Node3D public partial class CHealthbar : Sprite3D
{ {
private Sprite3D _currentHealth; private Healthbar _healthbar;
private float _initialXScale; public Healthbar Healthbar => _healthbar;
public override void _Ready() public override void _Ready()
{ {
Visible = false; _healthbar = GetNode<Healthbar>("%Healthbar");
_currentHealth = GetNode<Sprite3D>("Health");
_initialXScale = _currentHealth.Scale.X;
}
public void OnHealthChanged(HealthChangedRecord healthChanged)
{
if (healthChanged.MaxHealth == 0) return;
Visible = true;
var healthPercentage = healthChanged.CurrentHealth / healthChanged.MaxHealth;
_currentHealth.Scale = new Vector3(_initialXScale * healthPercentage, _currentHealth.Scale.Y, _currentHealth.Scale.Z);
} }
} }

View File

@@ -1 +1 @@
uid://dve6vg6yvg4y8 uid://chfb3cjo6exga

View File

@@ -1,27 +1,32 @@
[gd_scene load_steps=3 format=3 uid="uid://bwx2um43k0ou4"] [gd_scene load_steps=4 format=3 uid="uid://bwx2um43k0ou4"]
[ext_resource type="Texture2D" uid="uid://vpcxswwn1mt6" path="res://assets/ui/white-square-100px.png" id="1_jlvej"] [ext_resource type="Script" uid="uid://chfb3cjo6exga" path="res://components/health/CHealthbar.cs" id="1_w5itk"]
[ext_resource type="Script" uid="uid://dve6vg6yvg4y8" path="res://components/health/CHealthbar.cs" id="1_w5itk"] [ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar.tscn" id="2_w5itk"]
[node name="CHealthBar" type="Node3D"] [sub_resource type="ViewportTexture" id="ViewportTexture_jkj2g"]
viewport_path = NodePath("SubViewport")
[node name="CHealthBar" type="Sprite3D"]
billboard = 1
double_sided = false
no_depth_test = true
texture = SubResource("ViewportTexture_jkj2g")
script = ExtResource("1_w5itk") script = ExtResource("1_w5itk")
[node name="Bar" type="Sprite3D" parent="."] [node name="SubViewport" type="SubViewport" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.1, 0, 0, 0, 1, 0, 0, 0) transparent_bg = true
cast_shadow = 0 size = Vector2i(520, 20)
billboard = 1
transparent = false
double_sided = false
no_depth_test = true
texture = ExtResource("1_jlvej")
[node name="Health" type="Sprite3D" parent="."] [node name="Healthbar" parent="SubViewport" instance=ExtResource("2_w5itk")]
transform = Transform3D(0.99, 0, 0, 0, 0.09, 0, 0, 0, 1, 0, 0, 0) unique_name_in_owner = true
cast_shadow = 0 anchors_preset = 8
modulate = Color(0.7191989, 0.19340843, 1.92523e-07, 1) anchor_left = 0.5
billboard = 1 anchor_top = 0.5
transparent = false anchor_right = 0.5
double_sided = false anchor_bottom = 0.5
no_depth_test = true offset_left = -120.0
render_priority = 10 offset_top = -4.0
texture = ExtResource("1_jlvej") offset_right = 120.0
offset_bottom = 4.0
grow_horizontal = 2
grow_vertical = 2

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=67 format=3 uid="uid://bei4nhkf8lwdo"] [gd_scene load_steps=68 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"]
@@ -52,6 +52,7 @@
[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"]
[ext_resource type="Texture2D" uid="uid://buu21kg4kkhiw" path="res://guide_examples/shared/fireball/fireball.svg" id="42_cmijs"] [ext_resource type="Texture2D" uid="uid://buu21kg4kkhiw" path="res://guide_examples/shared/fireball/fireball.svg" id="42_cmijs"]
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar.tscn" id="47_76kmc"]
[sub_resource type="Resource" id="Resource_cb2lu"] [sub_resource type="Resource" id="Resource_cb2lu"]
script = ExtResource("2_x835q") script = ExtResource("2_x835q")
@@ -510,6 +511,21 @@ grow_vertical = 2
texture = ExtResource("42_cmijs") texture = ExtResource("42_cmijs")
expand_mode = 1 expand_mode = 1
[node name="Healthbar" parent="UI" instance=ExtResource("47_76kmc")]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -120.0
offset_top = -80.0
offset_right = 119.99963
offset_bottom = -71.99939
grow_horizontal = 2
grow_vertical = 0
[node name="StateChart" type="Node" parent="."] [node name="StateChart" type="Node" parent="."]
script = ExtResource("25_wv70j") script = ExtResource("25_wv70j")
metadata/_custom_type_script = "uid://couw105c3bde4" metadata/_custom_type_script = "uid://couw105c3bde4"

View File

@@ -1,10 +1,12 @@
using Godot; using Godot;
using System; using System;
using Movementtests.interfaces;
public partial class PlayerUi : Control public partial class PlayerUi : Control
{ {
private TextureRect[] _dashIcons = new TextureRect[3]; private TextureRect[] _dashIcons = new TextureRect[3];
private TextureRect _enemyTarget; private TextureRect _enemyTarget;
private Healthbar _healthbar;
public enum TargetState public enum TargetState
{ {
@@ -30,6 +32,12 @@ public partial class PlayerUi : Control
_dashIcons[2] = GetNode<TextureRect>("%Dash3"); _dashIcons[2] = GetNode<TextureRect>("%Dash3");
_enemyTarget = GetNode<TextureRect>("%EnemyTarget"); _enemyTarget = GetNode<TextureRect>("%EnemyTarget");
_healthbar = GetNode<Healthbar>("%Healthbar");
}
public void Initialize(float initialHealth)
{
_healthbar.Initialize(initialHealth);
} }
public void SetEnemyTargetProperties(TargetProperties targetProperties) public void SetEnemyTargetProperties(TargetProperties targetProperties)
@@ -60,4 +68,9 @@ public partial class PlayerUi : Control
index++; index++;
} }
} }
public void OnHealthChanged(IHealthable healthable, HealthChangedRecord healthChanged)
{
_healthbar.CurrentHealth = healthChanged.CurrentHealth;
}
} }

View File

@@ -430,8 +430,10 @@ public partial class PlayerController : CharacterBody3D,
} }
if (RKnockback != null) CKnockback!.RKnockback = RKnockback; if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
PlayerUi.Initialize(CHealth.CurrentHealth);
CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record); CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
CDamageable.DamageTaken += (damageable, record) => RegisterKnockback(new KnockbackRecord(record)); CDamageable.DamageTaken += (damageable, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthChanged += PlayerUi.OnHealthChanged;
CHealth.HealthDepleted += Kill; CHealth.HealthDepleted += Kill;
// State management // State management

View File

@@ -57,7 +57,7 @@ public partial class Enemy : CharacterBody3D,
// Private stuff // Private stuff
private Area3D _damageBox; private Area3D _damageBox;
private Node3D _target; private Node3D _target;
private CHealthbar _healthbar; private Healthbar _healthbar;
public override void _Ready() public override void _Ready()
{ {
@@ -79,7 +79,7 @@ public partial class Enemy : CharacterBody3D,
if (CHealth is null) GD.PrintErr("This node needs a 'CHealth' child of type IHealthable!"); if (CHealth is null) GD.PrintErr("This node needs a 'CHealth' child of type IHealthable!");
if (CKnockback is null) GD.PrintErr("This node needs a 'CKnockback' child of type IKnockbackable!"); if (CKnockback is null) GD.PrintErr("This node needs a 'CKnockback' child of type IKnockbackable!");
_healthbar = GetNode<CHealthbar>("CHealthBar"); _healthbar = GetNode<CHealthbar>("CHealthBar").Healthbar;
if (RMovement != null) CMovement!.RMovement = RMovement; if (RMovement != null) CMovement!.RMovement = RMovement;
if (RHealth != null) if (RHealth != null)
@@ -88,6 +88,7 @@ public partial class Enemy : CharacterBody3D,
CHealth.CurrentHealth = RHealth.StartingHealth; CHealth.CurrentHealth = RHealth.StartingHealth;
} }
if (RKnockback != null) CKnockback!.RKnockback = RKnockback; if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
_healthbar.Initialize(CHealth!.CurrentHealth);
} }
public void SetupSignals() public void SetupSignals()
@@ -96,7 +97,7 @@ public partial class Enemy : CharacterBody3D,
CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record); CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
CDamageable.DamageTaken += (source, record) => RegisterKnockback(new KnockbackRecord(record)); CDamageable.DamageTaken += (source, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthDepleted += Kill; CHealth.HealthDepleted += Kill;
HealthChanged += (source, record) => _healthbar.OnHealthChanged(record); HealthChanged += (source, record) => _healthbar.SetHealth(record.CurrentHealth);
} }
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://cmlud1hwkd6sv"] [gd_scene load_steps=22 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://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://components/damage/RDamageModifier.cs" id="2_1bsgx"]
@@ -13,6 +13,9 @@
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://components/knockback/CKnockback.tscn" id="10_dejyg"] [ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://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"] [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"]
viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_jnv07"] [sub_resource type="Resource" id="Resource_jnv07"]
script = ExtResource("2_1bsgx") script = ExtResource("2_1bsgx")
metadata/_custom_type_script = "uid://b6y3ugfydvch0" metadata/_custom_type_script = "uid://b6y3ugfydvch0"
@@ -62,7 +65,8 @@ RHealth = ExtResource("2_ma2bq")
metadata/_custom_type_script = "uid://bjwrpv3jpsc1e" metadata/_custom_type_script = "uid://bjwrpv3jpsc1e"
[node name="CHealthBar" parent="." instance=ExtResource("7_ykkxn")] [node name="CHealthBar" parent="." instance=ExtResource("7_ykkxn")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.70000005, 0) transform = Transform3D(0.3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.70000005, 0)
texture = SubResource("ViewportTexture_ykkxn")
[node name="CDamageable" type="Node" parent="."] [node name="CDamageable" type="Node" parent="."]
script = ExtResource("8_uotso") script = ExtResource("8_uotso")

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://dxt0e2ugmttqq"] [gd_scene load_steps=22 format=3 uid="uid://dxt0e2ugmttqq"]
[ext_resource type="Script" uid="uid://bn7sc6id7n166" path="res://scenes/enemies/Enemy.cs" id="1_r6506"] [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="Resource" uid="uid://otfc2snh8umc" path="res://scenes/enemies/grounded_enemy/grounded_enemy_damage.tres" id="2_bn56u"]
@@ -13,6 +13,9 @@
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://components/knockback/CKnockback.tscn" id="10_jqqi6"] [ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://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"] [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"]
viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_qj0ob"] [sub_resource type="Resource" id="Resource_qj0ob"]
script = ExtResource("2_r3cnf") script = ExtResource("2_r3cnf")
Modifier = 1.0 Modifier = 1.0
@@ -62,7 +65,8 @@ RHealth = ExtResource("2_w4lm8")
metadata/_custom_type_script = "uid://bjwrpv3jpsc1e" metadata/_custom_type_script = "uid://bjwrpv3jpsc1e"
[node name="CHealthBar" parent="." instance=ExtResource("7_18xwy")] [node name="CHealthBar" parent="." instance=ExtResource("7_18xwy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0) transform = Transform3D(0.4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0)
texture = SubResource("ViewportTexture_18xwy")
[node name="CDamageable" type="Node" parent="."] [node name="CDamageable" type="Node" parent="."]
script = ExtResource("7_1tw73") script = ExtResource("7_1tw73")

58
scenes/ui/Healthbar.cs Normal file
View File

@@ -0,0 +1,58 @@
using Godot;
using System;
[GlobalClass]
public partial class Healthbar : ProgressBar
{
private Timer _damageCatchUpTimer;
private ProgressBar _damagedHealth;
private float _currentHealth;
public float CurrentHealth
{
get => _currentHealth;
set => SetHealth(value);
}
public override void _Ready()
{
_damageCatchUpTimer = GetNode<Timer>("DamageCatchUp");
_damagedHealth = GetNode<ProgressBar>("Damagebar");
_damageCatchUpTimer.Timeout += OnDamageCatchUp;
Visible = false;
}
public void Initialize(float initialHealth)
{
_currentHealth = initialHealth;
MaxValue = initialHealth;
Value = initialHealth;
_damagedHealth.MaxValue = initialHealth;
_damagedHealth.Value = initialHealth;
}
public void SetHealth(float newHealth)
{
var previousHealth = _currentHealth;
_currentHealth = Mathf.Min(newHealth, (float) MaxValue);
_currentHealth = newHealth;
Value = _currentHealth;
Visible = _currentHealth < MaxValue;
if (_currentHealth < previousHealth)
{
_damageCatchUpTimer.Start();
}
else
{
_damagedHealth.Value = _currentHealth;
}
}
public void OnDamageCatchUp()
{
_damagedHealth.Value = _currentHealth;
}
}

View File

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

49
scenes/ui/healthbar.tscn Normal file
View File

@@ -0,0 +1,49 @@
[gd_scene load_steps=6 format=3 uid="uid://cyw8p0p6a78tl"]
[ext_resource type="Script" uid="uid://l5cjcaehyssk" path="res://scenes/ui/Healthbar.cs" id="1_0k5hr"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0sgot"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0k5hr"]
bg_color = Color(0.698864, 0.047356047, 0, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0sgot"]
bg_color = Color(0.14767182, 0.14767182, 0.14767176, 1)
expand_margin_left = 2.0
expand_margin_top = 2.0
expand_margin_right = 2.0
expand_margin_bottom = 2.0
shadow_color = Color(0, 0, 0, 0.27450982)
shadow_offset = Vector2(0, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kl70x"]
bg_color = Color(0.8862616, 0.88626146, 0.8862615, 1)
[node name="Healthbar" type="ProgressBar"]
z_index = 10
custom_minimum_size = Vector2(512, 12)
offset_right = 512.0
offset_bottom = 12.0
theme_override_styles/background = SubResource("StyleBoxEmpty_0sgot")
theme_override_styles/fill = SubResource("StyleBoxFlat_0k5hr")
value = 60.0
show_percentage = false
script = ExtResource("1_0k5hr")
[node name="Damagebar" type="ProgressBar" parent="."]
z_index = -10
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/background = SubResource("StyleBoxFlat_0sgot")
theme_override_styles/fill = SubResource("StyleBoxFlat_kl70x")
value = 80.0
show_percentage = false
[node name="DamageCatchUp" type="Timer" parent="."]
wait_time = 0.8
one_shot = true
ignore_time_scale = true