Add comprehensive UI system with action bar, unit frame, and character sheet

- Created UI system in level/ui/ folder
  - Action bar with 12 ability slots (Attack, Block, Dash, Jump + 8 expansion slots)
  - Unit frame showing player portrait with health bar
  - Character sheet/spellbook (toggle with Tab) displaying stats, weapons, and abilities
  - Tab hint indicator showing how to open character sheet
  - Custom theme with golden borders and dark backgrounds

- UI Components:
  - HUD Manager autoload handles all UI initialization and player connections
  - Ability buttons with cooldown overlay and keybind display
  - Real-time health and cooldown tracking via signals
  - Scrollable character sheet with two-page layout

- Player Integration:
  - Added UI signals: dash_cooldown_updated, attack_cooldown_updated, weapon_equipped_changed
  - Mouse capture system (Escape to toggle, click to recapture)
  - Synced attack cooldown from weapons to player for UI tracking

- Updated level.gd to connect local player to HUD Manager
- Updated CLAUDE.md with git commit guidelines
This commit is contained in:
2025-11-16 22:48:50 +00:00
parent d475c0abf9
commit 15865dd15f
24 changed files with 1386 additions and 58 deletions
+75
View File
@@ -0,0 +1,75 @@
[gd_scene load_steps=4 format=3 uid="uid://cq7xyb8n4h6yk"]
[ext_resource type="Script" path="res://level/ui/scripts/ability_button.gd" id="1_script"]
[ext_resource type="Theme" uid="uid://dvsh7tuhulnfm" path="res://level/ui/theme/wow_style.tres" id="2_theme"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_panel"]
bg_color = Color(0.15, 0.15, 0.15, 0.9)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.6, 0.5, 0.2, 1)
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
[node name="AbilityButton" type="PanelContainer"]
custom_minimum_size = Vector2(64, 64)
theme = ExtResource("2_theme")
theme_override_styles/panel = SubResource("StyleBoxFlat_panel")
script = ExtResource("1_script")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="Icon" type="TextureRect" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
expand_mode = 1
stretch_mode = 5
[node name="CooldownOverlay" type="ColorRect" parent="MarginContainer/VBoxContainer/Icon"]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0.7)
[node name="CooldownLabel" type="Label" parent="MarginContainer/VBoxContainer/Icon"]
visible = false
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -11.5
offset_right = 20.0
offset_bottom = 11.5
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 24
text = "3"
horizontal_alignment = 1
vertical_alignment = 1
[node name="KeybindLabel" type="Label" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 2
theme_override_font_sizes/font_size = 14
text = "1"
horizontal_alignment = 1
+64
View File
@@ -0,0 +1,64 @@
[gd_scene load_steps=3 format=3 uid="uid://b4h0p6nbcq35b"]
[ext_resource type="Script" path="res://level/ui/scripts/action_bar.gd" id="1_script"]
[ext_resource type="PackedScene" uid="uid://cq7xyb8n4h6yk" path="res://level/ui/scenes/ability_button.tscn" id="2_ability_button"]
[node name="ActionBar" type="Control"]
layout_mode = 3
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -400.0
offset_top = -100.0
offset_right = 400.0
grow_horizontal = 2
grow_vertical = 0
script = ExtResource("1_script")
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/separation = 4
alignment = 1
[node name="Slot1" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot2" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot3" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot4" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot5" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot6" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot7" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot8" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot9" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot10" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot11" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
[node name="Slot12" parent="HBoxContainer" instance=ExtResource("2_ability_button")]
layout_mode = 2
+129
View File
@@ -0,0 +1,129 @@
[gd_scene load_steps=4 format=3 uid="uid://cu2vkr5h5b8hb"]
[ext_resource type="Script" path="res://level/ui/scripts/character_sheet.gd" id="1_script"]
[ext_resource type="Theme" uid="uid://dvsh7tuhulnfm" path="res://level/ui/theme/wow_style.tres" id="2_theme"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_book"]
bg_color = Color(0.12, 0.1, 0.08, 0.95)
border_width_left = 4
border_width_top = 4
border_width_right = 4
border_width_bottom = 4
border_color = Color(0.6, 0.5, 0.2, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[node name="CharacterSheet" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("2_theme")
script = ExtResource("1_script")
[node name="DarkBackground" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0.7)
[node name="Panel" type="PanelContainer" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -450.0
offset_top = -300.0
offset_right = 450.0
offset_bottom = 300.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_book")
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="TitleLabel" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.8, 0, 1)
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 3
theme_override_font_sizes/font_size = 28
text = "CHARACTER SHEET"
horizontal_alignment = 1
[node name="HSeparator" type="HSeparator" parent="Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 5
[node name="HBoxContainer" type="HBoxContainer" parent="Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/separation = 20
[node name="LeftPage" type="PanelContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="ScrollContainer" type="ScrollContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/LeftPage"]
layout_mode = 2
horizontal_scroll_mode = 0
[node name="StatsContainer" type="VBoxContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/LeftPage/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 2
[node name="Divider" type="VSeparator" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
[node name="RightPage" type="PanelContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="ScrollContainer" type="ScrollContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/RightPage"]
layout_mode = 2
horizontal_scroll_mode = 0
[node name="ContentContainer" type="VBoxContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/RightPage/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 10
[node name="WeaponsContainer" type="VBoxContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/RightPage/ScrollContainer/ContentContainer"]
layout_mode = 2
theme_override_constants/separation = 2
[node name="Spacer" type="Control" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/RightPage/ScrollContainer/ContentContainer"]
custom_minimum_size = Vector2(0, 15)
layout_mode = 2
[node name="AbilitiesContainer" type="VBoxContainer" parent="Panel/MarginContainer/VBoxContainer/HBoxContainer/RightPage/ScrollContainer/ContentContainer"]
layout_mode = 2
theme_override_constants/separation = 2
[node name="CloseHint" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1)
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 1
theme_override_font_sizes/font_size = 14
text = "Press TAB to close"
horizontal_alignment = 2
+69
View File
@@ -0,0 +1,69 @@
[gd_scene load_steps=3 format=3 uid="uid://bjn6yfwqgp2n7"]
[ext_resource type="Script" path="res://level/ui/scripts/resource_bars.gd" id="1_script"]
[ext_resource type="Theme" uid="uid://dvsh7tuhulnfm" path="res://level/ui/theme/wow_style.tres" id="2_theme"]
[node name="ResourceBars" type="Control"]
layout_mode = 3
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -250.0
offset_top = -140.0
offset_right = 250.0
offset_bottom = -110.0
grow_horizontal = 2
grow_vertical = 0
theme = ExtResource("2_theme")
script = ExtResource("1_script")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/separation = 4
[node name="HealthBar" type="Control" parent="VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Background" type="ColorRect" parent="VBoxContainer/HealthBar"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.2, 0.2, 0.2, 0.8)
[node name="Fill" type="ColorRect" parent="VBoxContainer/HealthBar/Background"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 2.0
offset_top = 2.0
offset_right = -2.0
offset_bottom = -2.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0.8, 0, 1)
[node name="HealthText" type="Label" parent="VBoxContainer/HealthBar"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 2
theme_override_font_sizes/font_size = 18
text = "100 / 100 HP"
horizontal_alignment = 1
vertical_alignment = 1
+52
View File
@@ -0,0 +1,52 @@
[gd_scene load_steps=3 format=3 uid="uid://d2s8m3fy7ktjv"]
[ext_resource type="Theme" uid="uid://dvsh7tuhulnfm" path="res://level/ui/theme/wow_style.tres" id="1_theme"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hint"]
bg_color = Color(0.15, 0.15, 0.15, 0.85)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.6, 0.5, 0.2, 1)
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
[node name="TabHint" type="PanelContainer"]
offset_left = 20.0
offset_top = 150.0
offset_right = 180.0
offset_bottom = 220.0
theme = ExtResource("1_theme")
theme_override_styles/panel = SubResource("StyleBoxFlat_hint")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 5
[node name="KeyLabel" type="Label" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_color = Color(1, 0.8, 0, 1)
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 2
theme_override_font_sizes/font_size = 24
text = "TAB"
horizontal_alignment = 1
[node name="DescLabel" type="Label" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 1
theme_override_font_sizes/font_size = 14
text = "Character
Sheet"
horizontal_alignment = 1
+93
View File
@@ -0,0 +1,93 @@
[gd_scene load_steps=4 format=3 uid="uid://b7u8yhry4b74a"]
[ext_resource type="Script" path="res://level/ui/scripts/unit_frame.gd" id="1_script"]
[ext_resource type="Theme" uid="uid://dvsh7tuhulnfm" path="res://level/ui/theme/wow_style.tres" id="2_theme"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_frame"]
bg_color = Color(0.1, 0.1, 0.1, 0.85)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0.6, 0.5, 0.2, 1)
corner_radius_top_left = 6
corner_radius_top_right = 6
corner_radius_bottom_right = 6
corner_radius_bottom_left = 6
[node name="UnitFrame" type="PanelContainer"]
offset_left = 20.0
offset_top = 20.0
offset_right = 270.0
offset_bottom = 120.0
theme = ExtResource("2_theme")
theme_override_styles/panel = SubResource("StyleBoxFlat_frame")
script = ExtResource("1_script")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 6
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="LevelLabel" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 2
theme_override_font_sizes/font_size = 20
text = "Lv 1"
[node name="NameLabel" type="Label" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 2
theme_override_font_sizes/font_size = 22
text = "Player Name"
[node name="HealthBarContainer" type="Control" parent="MarginContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 30)
layout_mode = 2
[node name="Background" type="ColorRect" parent="MarginContainer/VBoxContainer/HealthBarContainer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.2, 0.2, 0.2, 0.9)
[node name="Fill" type="ColorRect" parent="MarginContainer/VBoxContainer/HealthBarContainer/Background"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 2.0
offset_top = 2.0
offset_right = -2.0
offset_bottom = -2.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0.8, 0, 1)
[node name="HealthText" type="Label" parent="MarginContainer/VBoxContainer/HealthBarContainer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 2
theme_override_font_sizes/font_size = 16
text = "100 / 100"
horizontal_alignment = 1
vertical_alignment = 1