Skip to content

Commit dc7446a

Browse files
committed
Refactor building and vehicle HUDs for modular details
Reworked the UI system to use dynamic content containers and UXML templates for building details, enabling modular and extensible HUD panels for Main Station, Hangar, and Energy Tower. Updated building and vehicle classes to expose relevant status properties, and refactored controller logic to support the new UI structure. Improved null checks and event handling in input and HUD controllers for robustness.
1 parent 50f07a3 commit dc7446a

File tree

16 files changed

+220
-93
lines changed

16 files changed

+220
-93
lines changed

Red Strike/Assets/BuildingPlacement/Buildings/Building.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ public class Building : MonoBehaviour
88
public Building buildingData;
99
public ParticleSystem[] buildEffects;
1010

11-
private float health;
11+
protected float health;
1212
private float maxHealth = 100f;
13+
public float CurrentHealth => health;
14+
public string BuildingName => buildingData != null ? buildingData.name : gameObject.name;
1315

1416
private void Start()
1517
{
@@ -30,11 +32,6 @@ private void OnCollisionEnter(Collision collision)
3032
// Burada hasar hesaplaması yapılabilir.
3133
}
3234
}
33-
34-
public (string, float) GetBuildingStatus()
35-
{
36-
return (gameObject.name, health);
37-
}
3835
}
3936

4037
public enum PlayerType
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
using UnityEngine;
22
using BuildingPlacement;
33

4-
public class EnergyTower : BuildingPlacement.Buildings.Building
4+
namespace BuildingPlacement.Buildings
55
{
6+
public class EnergyTower : Building
7+
{
8+
// TEST
9+
public float CurrentCapacity = 500f;
10+
public float Density = 0.8f;
11+
}
612
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
using UnityEngine;
22

3-
public class Hangar : BuildingPlacement.Buildings.Building
3+
namespace BuildingPlacement.Buildings
44
{
5+
public class Hangar : Building
6+
{
7+
// TEST
8+
public bool IsReady = true;
9+
public string InProductionUnitName = "Tank";
10+
}
511
}
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
using UnityEngine;
22

3-
public class MainStation : BuildingPlacement.Buildings.Building
3+
namespace BuildingPlacement.Buildings
44
{
5-
public Transform radarTransform;
6-
public float radarRotationSpeed = 20f;
7-
8-
private void Update()
5+
public class MainStation : Building
96
{
10-
radarTransform.Rotate(Vector3.up, radarRotationSpeed * Time.deltaTime);
7+
public Transform radarTransform;
8+
public float radarRotationSpeed = 20f;
9+
public float ShieldAmount = 100f; // TEST
10+
11+
private void Update()
12+
{
13+
radarTransform.Rotate(Vector3.up, radarRotationSpeed * Time.deltaTime);
14+
}
15+
16+
public (string, float) GetBuildingStatus()
17+
{
18+
return (buildingData.name, health);
19+
}
1120
}
1221
}

Red Strike/Assets/InputController/InputController.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,21 @@ private void SelectObject()
107107
switch (hitInfo.collider.tag)
108108
{
109109
case "Build":
110-
BuildingPlacement.Buildings.Building building = hitInfo.collider.GetComponent<BuildingPlacement.Buildings.Building>();
111-
buildingHUDController.ShowBuildingDetails(building);
112-
vehiclesHUDController.HideVehicleDetails();
110+
BuildingPlacement.Buildings.Building clickedBuilding = hitInfo.collider.GetComponent<BuildingPlacement.Buildings.Building>();
111+
112+
if (clickedBuilding != null)
113+
{
114+
buildingHUDController.ShowBuildingDetails(clickedBuilding);
115+
if (vehiclesHUDController != null) vehiclesHUDController.HideVehicleDetails();
116+
}
113117
break;
118+
114119
case "Vehicle":
115120
Vehicle clickedVehicle = hitInfo.collider.GetComponent<Vehicle>();
116-
vehiclesHUDController.ShowVehicleDetails(clickedVehicle);
121+
if (vehiclesHUDController != null) vehiclesHUDController.ShowVehicleDetails(clickedVehicle);
117122
buildingHUDController.HideBuildingDetails();
118123
break;
124+
119125
default:
120126
DeselectAll();
121127
break;
@@ -129,7 +135,7 @@ private void SelectObject()
129135

130136
private void DeselectAll()
131137
{
132-
vehiclesHUDController.HideVehicleDetails();
138+
if (vehiclesHUDController != null) vehiclesHUDController.HideVehicleDetails();
133139
buildingHUDController.HideBuildingDetails();
134140
}
135141

Lines changed: 90 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using ExitGames.Client.Photon.StructWrapping;
21
using UnityEngine;
32
using UnityEngine.UIElements;
43
using BuildingPlacement.Buildings;
@@ -7,103 +6,136 @@ namespace UISystem
76
{
87
public class BuildingHUDController : GameHUDController
98
{
10-
private Button mainStationButton;
11-
private Button hangarButton;
12-
private Button energyTowerButton;
13-
14-
15-
#region Main Station Details
16-
private VisualElement mainStationDetailsPanel;
17-
private Label mainStationNameLabel;
18-
private Label mainStationHealthLabel;
9+
[Header("Templates (UXML)")]
10+
public VisualTreeAsset mainStationTemplate;
11+
public VisualTreeAsset hangarTemplate;
12+
public VisualTreeAsset energyTowerTemplate;
13+
14+
private VisualElement buildingDetailsPanel;
15+
private Label sharedBuildTypeLabel;
16+
private Label sharedHealthLabel;
17+
18+
// Main Station
19+
private Label msShieldLabel;
20+
21+
// Hangar
22+
private Label hIsReadyLabel;
23+
private Label hProductionLabel;
24+
25+
// Energy Tower
26+
private Label etCapacityLabel;
27+
private Label etDensityLabel;
1928

2029
private Building currentlySelectedBuilding;
21-
#endregion
2230

2331
protected override void OnEnable()
2432
{
2533
base.OnEnable();
2634

27-
mainStationDetailsPanel = root.Q<VisualElement>("main-station-details-panel");
28-
mainStationNameLabel = mainStationDetailsPanel.Q<Label>("build-type-label");
29-
mainStationHealthLabel = mainStationDetailsPanel.Q<Label>("building-health-label");
35+
buildingDetailsPanel = root.Q<VisualElement>("building-details-panel");
36+
sharedBuildTypeLabel = root.Q<Label>("shared-build-type-label");
37+
sharedHealthLabel = root.Q<Label>("shared-health-label");
3038

31-
mainStationButton = root.Q<Button>("main-station-button");
32-
hangarButton = root.Q<Button>("hangar-button");
33-
energyTowerButton = root.Q<Button>("energy-tower-button");
39+
var mainStationBtn = root.Q<Button>("main-station-button");
40+
var hangarBtn = root.Q<Button>("hangar-button");
41+
var energyTowerBtn = root.Q<Button>("energy-tower-button");
3442

35-
mainStationButton.clicked += OnMainStationClicked;
36-
hangarButton.clicked += OnHangarClicked;
37-
energyTowerButton.clicked += OnEnergyTowerClicked;
43+
if(mainStationBtn != null) mainStationBtn.clicked += () => OnBuildingButtonClicked("Main Station");
44+
if(hangarBtn != null) hangarBtn.clicked += () => OnBuildingButtonClicked("Hangar");
45+
if(energyTowerBtn != null) energyTowerBtn.clicked += () => OnBuildingButtonClicked("Energy Tower");
3846

3947
HideBuildingDetails();
4048
}
4149

42-
protected override void OnDisable()
43-
{
44-
base.OnDisable();
45-
46-
mainStationButton.clicked -= OnMainStationClicked;
47-
hangarButton.clicked -= OnHangarClicked;
48-
energyTowerButton.clicked -= OnEnergyTowerClicked;
49-
}
50-
5150
protected override void Update()
5251
{
5352
base.Update();
5453

55-
if (currentlySelectedBuilding != null)
54+
if (currentlySelectedBuilding != null && buildingDetailsPanel.style.display == DisplayStyle.Flex)
5655
{
57-
RefreshVehicleDetails();
56+
UpdateBuildingData();
5857
}
5958
}
6059

61-
private void RefreshVehicleDetails()
60+
public void ShowBuildingDetails(Building building)
6261
{
63-
var status = currentlySelectedBuilding.GetBuildingStatus();
64-
string buildingName = status.Item1;
65-
string health = status.Item2.ToString("F1");
66-
mainStationNameLabel.text = buildingName;
67-
mainStationHealthLabel.text = "Health: " + health;
62+
if (building == null) return;
63+
64+
currentlySelectedBuilding = building;
65+
66+
sharedBuildTypeLabel.text = building.BuildingName;
67+
68+
buildingDynamicContentContainer.Clear();
69+
70+
if (building is MainStation)
71+
{
72+
InstantiateTemplate(mainStationTemplate);
73+
msShieldLabel = buildingDynamicContentContainer.Q<Label>("shield-label");
74+
}
75+
else if (building is Hangar)
76+
{
77+
InstantiateTemplate(hangarTemplate);
78+
hIsReadyLabel = buildingDynamicContentContainer.Q<Label>("is-ready-label");
79+
hProductionLabel = buildingDynamicContentContainer.Q<Label>("in-production-label");
80+
}
81+
else if (building is EnergyTower)
82+
{
83+
InstantiateTemplate(energyTowerTemplate);
84+
etCapacityLabel = buildingDynamicContentContainer.Q<Label>("capacity-label");
85+
etDensityLabel = buildingDynamicContentContainer.Q<Label>("density-label");
86+
}
87+
88+
buildingDetailsPanel.style.display = DisplayStyle.Flex;
6889
}
6990

7091
public void HideBuildingDetails()
7192
{
7293
currentlySelectedBuilding = null;
73-
mainStationDetailsPanel.style.display = DisplayStyle.None;
94+
if(buildingDetailsPanel != null)
95+
buildingDetailsPanel.style.display = DisplayStyle.None;
7496
}
7597

76-
public void ShowBuildingDetails(Building buildingToShow)
98+
private void UpdateBuildingData()
7799
{
78-
currentlySelectedBuilding = buildingToShow;
79-
mainStationDetailsPanel.style.display = DisplayStyle.Flex;
80-
}
100+
sharedHealthLabel.text = $"Health: {currentlySelectedBuilding.CurrentHealth:F0}";
81101

82-
private void OnBuildingButtonClicked(string buildingName)
83-
{
84-
if (inputController != null)
102+
if (currentlySelectedBuilding is MainStation ms)
85103
{
86-
inputController.SelectBuildingToPlace(buildingName);
104+
if (msShieldLabel != null)
105+
msShieldLabel.text = $"Shield: {ms.ShieldAmount:F0}%";
87106
}
88-
else
107+
else if (currentlySelectedBuilding is Hangar hg)
89108
{
90-
Debug.LogError("InputController referansı GameHUDController'da atanmamış!");
109+
if (hIsReadyLabel != null)
110+
hIsReadyLabel.text = $"Is Ready: {hg.IsReady}";
111+
if (hProductionLabel != null)
112+
hProductionLabel.text = $"Prod: {hg.InProductionUnitName}";
113+
}
114+
else if (currentlySelectedBuilding is EnergyTower et)
115+
{
116+
if (etCapacityLabel != null)
117+
etCapacityLabel.text = $"Capacity: {et.CurrentCapacity}";
118+
if (etDensityLabel != null)
119+
etDensityLabel.text = $"Density: {et.Density}";
91120
}
92121
}
93122

94-
private void OnMainStationClicked()
95-
{
96-
OnBuildingButtonClicked("Main Station");
97-
}
98-
99-
private void OnHangarClicked()
123+
private void InstantiateTemplate(VisualTreeAsset template)
100124
{
101-
OnBuildingButtonClicked("Hangar");
125+
if (template != null)
126+
{
127+
template.CloneTree(buildingDynamicContentContainer);
128+
}
129+
else
130+
{
131+
Debug.LogWarning("İstenen yapı için UXML Template atanmamış!");
132+
}
102133
}
103134

104-
private void OnEnergyTowerClicked()
135+
private void OnBuildingButtonClicked(string buildingName)
105136
{
106-
OnBuildingButtonClicked("Energy Tower");
137+
if (inputController != null)
138+
inputController.SelectBuildingToPlace(buildingName);
107139
}
108140
}
109-
}
141+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
2+
<Style src="project://database/Assets/UISystem/GameHUDStyles.uss?fileID=7433441132597879392&amp;guid=76481a45a761bb147acf1059658d7ddd&amp;type=3#GameHUDStyles" />
3+
<ui:VisualElement name="root-container" style="flex-grow: 1;">
4+
<ui:VisualElement name="energy-tower-content" class="info-panel">
5+
<ui:Label text="Capacity:" name="capacity-label" class="details-text" />
6+
<ui:Label text="Density:" name="density-label" class="details-text" />
7+
</ui:VisualElement>
8+
</ui:VisualElement>
9+
</ui:UXML>

Red Strike/Assets/UISystem/EnergyTowerDetailsContent.uxml.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Red Strike/Assets/UISystem/GameHUD.uxml

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,29 @@
33
<ui:VisualElement name="root-container" style="width: 100%; height: 100%; justify-content: space-between; align-items: stretch;">
44
<ui:VisualElement name="top-bar-container" style="height: 30px; background-color: rgba(20, 20, 20, 0.9);" />
55
<ui:VisualElement name="middle-content" style="flex-grow: 1;" />
6+
67
<ui:VisualElement name="left-panel" class="side-panel">
78
<ui:Button text="Main Station" name="main-station-button" class="build-button" />
89
<ui:Button text="Hangar" name="hangar-button" class="build-button" />
910
<ui:Button text="Energy Tower" name="energy-tower-button" class="build-button" />
1011
</ui:VisualElement>
11-
<ui:VisualElement name="details-panel" class="info-panel" visible="false" >
12-
<ui:Label text="Vehicle:" name="vehicle-name-label" class="details-title" />
13-
<ui:Label text="Fuel Level:" name="fuel-label" class="details-text" />
14-
<ui:Label text="Ammunition:" name="ammo-label" class="details-text" />
15-
<ui:Label text="Target:" name="target-label" class="details-text" />
12+
13+
<ui:VisualElement name="building-details-panel" class="info-panel" visible="false">
14+
<ui:Label text="Build Type:" name="shared-build-type-label" class="details-title" />
15+
<ui:Label text="Health:" name="shared-health-label" class="details-text" />
16+
17+
<ui:VisualElement name="building-dynamic-content-container" />
1618
</ui:VisualElement>
17-
<ui:VisualElement name="main-station-details-panel" class="info-panel" visible="false" >
18-
<ui:Label text="Build Type:" name="build-type-label" class="details-title" />
19-
<ui:Label text="Health:" name="building-health-label" class="details-text" />
19+
20+
<ui:VisualElement name="vehicle-details-panel" class="info-panel" visible="false">
21+
<ui:Label text="Vehicle Type:" name="shared-vehicle-type-label" class="details-title" />
22+
<ui:Label text="Health:" name="shared-health-label" class="details-text" />
23+
<ui:Label text="Target:" name="shared-target-label" class="details-text" />
24+
<ui:Label text="Fuel:" name="shared-fuel-label" class="details-text" />
25+
<ui:Label text="Bullets:" name="shared-bullets-label" class="details-text" />
26+
27+
<ui:VisualElement name="vehicle-dynamic-content-container" />
2028
</ui:VisualElement>
2129

2230
</ui:VisualElement>
23-
</ui:UXML>
31+
</ui:UXML>

Red Strike/Assets/UISystem/GameHUDController.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public class GameHUDController : MonoBehaviour
88
public InputController.InputController inputController;
99
protected UIDocument uiDocument;
1010
protected VisualElement root;
11+
protected VisualElement buildingDynamicContentContainer;
12+
protected VisualElement vehicleDynamicContentContainer;
1113

1214
protected virtual void OnEnable()
1315
{
@@ -18,6 +20,8 @@ protected virtual void OnEnable()
1820
return;
1921
}
2022
root = uiDocument.rootVisualElement;
23+
buildingDynamicContentContainer = root.Q<VisualElement>("building-dynamic-content-container");
24+
vehicleDynamicContentContainer = root.Q<VisualElement>("vehicle-dynamic-content-container");
2125
}
2226

2327
protected virtual void OnDisable() { /* Boş bırakıldı, alt sınıflar tarafından geçersiz kılınabilir */ }

0 commit comments

Comments
 (0)