AgentStatsUIController.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. using System.Collections.Generic;
  4. /// <summary>
  5. /// Manages the UI Toolkit-based Agent Stats display
  6. /// Shows total active agents and count that have reached an exit
  7. /// </summary>
  8. public class AgentStatsUIController : MonoBehaviour
  9. {
  10. [Header("UI Settings")]
  11. [SerializeField] private UIDocument uiDocument;
  12. [SerializeField] private float updateInterval = 0.25f;
  13. private Label totalAgentsLabel;
  14. private Label exitReachedLabel;
  15. private Label killedLabel;
  16. private Label monstersKilledLabel;
  17. private AIAgentManager agentManager;
  18. private MazeController mazeController;
  19. private float lastUpdateTime = 0f;
  20. private int lastTotalCount = -1;
  21. private int lastExitCount = -1;
  22. private int lastKilledCount = -1;
  23. private int lastMonstersKilledCount = -1;
  24. void Start()
  25. {
  26. // Find references in Start instead of Awake for better timing
  27. if (uiDocument == null)
  28. {
  29. uiDocument = GetComponent<UIDocument>();
  30. // If not on this GameObject, try to find it in the scene
  31. if (uiDocument == null)
  32. {
  33. uiDocument = FindAnyObjectByType<UIDocument>();
  34. Debug.Log("AgentStatsUIController: Found UIDocument in scene");
  35. }
  36. if (uiDocument == null)
  37. {
  38. Debug.LogError("AgentStatsUIController: UIDocument not found anywhere in scene!");
  39. enabled = false;
  40. return;
  41. }
  42. }
  43. // Get the root and find labels
  44. var root = uiDocument.rootVisualElement;
  45. if (root == null)
  46. {
  47. Debug.LogError("AgentStatsUIController: Root visual element is null!");
  48. return;
  49. }
  50. totalAgentsLabel = root.Q<Label>("TotalAgentsLabel");
  51. exitReachedLabel = root.Q<Label>("ExitReachedLabel");
  52. killedLabel = root.Q<Label>("KilledLabel");
  53. monstersKilledLabel = root.Q<Label>("MonstersKilledLabel");
  54. if (totalAgentsLabel == null)
  55. Debug.LogError("AgentStatsUIController: TotalAgentsLabel not found in UXML!");
  56. if (exitReachedLabel == null)
  57. Debug.LogError("AgentStatsUIController: ExitReachedLabel not found in UXML!");
  58. // killedLabel / monstersKilledLabel are optional – no error if absent
  59. // Find managers
  60. mazeController = FindAnyObjectByType<MazeController>();
  61. if (mazeController == null)
  62. {
  63. Debug.LogError("AgentStatsUIController: MazeController not found in scene!");
  64. return;
  65. }
  66. agentManager = mazeController.GetAgentManager();
  67. if (agentManager == null)
  68. {
  69. Debug.LogError("AgentStatsUIController: AgentManager not found in MazeController!");
  70. return;
  71. }
  72. Debug.Log("AgentStatsUIController: Initialized successfully");
  73. // Do first update immediately
  74. UpdateDisplay();
  75. }
  76. void Update()
  77. {
  78. if (agentManager == null || totalAgentsLabel == null) return;
  79. if (Time.time - lastUpdateTime > updateInterval)
  80. {
  81. UpdateDisplay();
  82. lastUpdateTime = Time.time;
  83. }
  84. }
  85. /// <summary>
  86. /// Updates the UI display with current agent stats
  87. /// </summary>
  88. private void UpdateDisplay()
  89. {
  90. int totalAgents = agentManager.GetActiveAgentCount();
  91. int agentsAtExit = GetAgentsAtExit();
  92. int agentsKilled = agentManager.AgentsKilledByMonsters;
  93. int monstersKilled = agentManager.MonstersKilledByAgents;
  94. // Only update if values changed
  95. if (totalAgents != lastTotalCount)
  96. {
  97. if (totalAgentsLabel != null)
  98. {
  99. totalAgentsLabel.text = totalAgents.ToString();
  100. lastTotalCount = totalAgents;
  101. }
  102. }
  103. if (agentsAtExit != lastExitCount)
  104. {
  105. if (exitReachedLabel != null)
  106. {
  107. exitReachedLabel.text = agentsAtExit.ToString();
  108. lastExitCount = agentsAtExit;
  109. }
  110. }
  111. if (agentsKilled != lastKilledCount)
  112. {
  113. if (killedLabel != null)
  114. {
  115. killedLabel.text = agentsKilled.ToString();
  116. lastKilledCount = agentsKilled;
  117. }
  118. }
  119. if (monstersKilled != lastMonstersKilledCount)
  120. {
  121. if (monstersKilledLabel != null)
  122. {
  123. monstersKilledLabel.text = monstersKilled.ToString();
  124. lastMonstersKilledCount = monstersKilled;
  125. }
  126. }
  127. }
  128. /// <summary>
  129. /// Counts how many agents have reached the goal/exit
  130. /// </summary>
  131. private int GetAgentsAtExit()
  132. {
  133. if (agentManager == null) return 0;
  134. List<AIAgent> allAgents = agentManager.GetActiveAgents();
  135. int count = 0;
  136. foreach (var agent in allAgents)
  137. {
  138. if (agent != null && agent.HasReachedGoal)
  139. {
  140. count++;
  141. }
  142. }
  143. return count;
  144. }
  145. }