| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- using UnityEngine;
- using UnityEngine.UIElements;
- using System.Collections.Generic;
- using System.Linq;
- /// <summary>
- /// Displays active fights in the UI with zoom buttons
- /// Shows runner vs monster fights, sorted by fight intensity (participants in room)
- /// </summary>
- public class ActiveFightsUIPanel : MonoBehaviour
- {
- [Header("Settings")]
- [SerializeField] private float updateInterval = 0.5f;
- private VisualElement root;
- private VisualElement fightsList;
- private Dictionary<string, VisualElement> fightEntries = new();
- private float lastUpdateTime = 0f;
- void Start()
- {
- InitializeUI();
- }
- private void InitializeUI()
- {
- // Find or create UIDocument
- var uiDocument = FindAnyObjectByType<UIDocument>();
- if (uiDocument == null)
- {
- var docGO = new GameObject("UIDocument");
- uiDocument = docGO.AddComponent<UIDocument>();
- }
- root = uiDocument.rootVisualElement;
- // Create the fights panel container
- var panelContainer = new VisualElement();
- panelContainer.name = "ActiveFightsPanel";
- panelContainer.style.position = Position.Absolute;
- panelContainer.style.left = 20; // Left side instead of right
- panelContainer.style.top = 20;
- panelContainer.style.width = 350;
- // Limit height so the list scrolls instead of growing off-screen
- panelContainer.style.maxHeight = new StyleLength(new Length(85, LengthUnit.Percent));
- panelContainer.style.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.8f);
- panelContainer.style.borderBottomLeftRadius = 5;
- panelContainer.style.borderBottomRightRadius = 5;
- panelContainer.style.borderTopLeftRadius = 5;
- panelContainer.style.borderTopRightRadius = 5;
- panelContainer.style.paddingBottom = 10;
- panelContainer.style.paddingTop = 10;
- panelContainer.style.paddingLeft = 10;
- panelContainer.style.paddingRight = 10;
- panelContainer.style.flexDirection = FlexDirection.Column;
- // Title
- var title = new Label("Active Fights");
- title.style.fontSize = 16;
- title.style.color = Color.white;
- title.style.marginBottom = 10;
- title.style.unityFontStyleAndWeight = FontStyle.Bold;
- title.style.flexShrink = 0;
- panelContainer.Add(title);
- // Scrollable container so the list doesn't overflow the screen
- var scrollView = new ScrollView(ScrollViewMode.Vertical);
- scrollView.name = "FightsScrollView";
- scrollView.style.flexGrow = 1;
- scrollView.style.flexShrink = 1;
- scrollView.horizontalScrollerVisibility = ScrollerVisibility.Hidden;
- scrollView.verticalScrollerVisibility = ScrollerVisibility.Auto;
- // Fights list container (lives inside the ScrollView)
- fightsList = new VisualElement();
- fightsList.name = "FightsList";
- fightsList.style.flexDirection = FlexDirection.Column;
- scrollView.Add(fightsList);
- panelContainer.Add(scrollView);
- root.Add(panelContainer);
- }
- void Update()
- {
- if (FightTracker.Instance == null) return;
- if (fightsList == null) return;
- if (Time.time - lastUpdateTime < updateInterval) return;
- lastUpdateTime = Time.time;
- RefreshFightsList();
- }
- /// <summary>
- /// Updates the list of displayed fights
- /// </summary>
- private void RefreshFightsList()
- {
- var fights = FightTracker.Instance.GetDisplayFights();
- var currentFightIds = new HashSet<string>();
- // Update or create entries for current fights
- foreach (var fight in fights)
- {
- string fightId = $"{fight.runnerId}_{fight.monster.GetHashCode()}";
- currentFightIds.Add(fightId);
- if (fightEntries.ContainsKey(fightId))
- {
- // Update existing entry
- UpdateFightEntry(fightEntries[fightId], fight);
- }
- else
- {
- // Create new entry
- var entryElement = CreateFightEntry(fight, fightId);
- fightEntries[fightId] = entryElement;
- fightsList.Add(entryElement);
- }
- }
- // Remove entries for fights that are no longer active
- var entriesToRemove = fightEntries.Keys.Where(id => !currentFightIds.Contains(id)).ToList();
- foreach (var id in entriesToRemove)
- {
- if (fightEntries[id] != null)
- {
- fightEntries[id].RemoveFromHierarchy();
- }
- fightEntries.Remove(id);
- }
- }
- /// <summary>
- /// Creates a single fight entry UI element
- /// </summary>
- private VisualElement CreateFightEntry(FightData fight, string fightId)
- {
- var entryContainer = new VisualElement();
- entryContainer.name = $"FightEntry_{fightId}";
- entryContainer.style.flexDirection = FlexDirection.Row;
- entryContainer.style.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.9f);
- entryContainer.style.borderBottomLeftRadius = 3;
- entryContainer.style.borderBottomRightRadius = 3;
- entryContainer.style.borderTopLeftRadius = 3;
- entryContainer.style.borderTopRightRadius = 3;
- entryContainer.style.paddingBottom = 5;
- entryContainer.style.paddingTop = 5;
- entryContainer.style.paddingLeft = 8;
- entryContainer.style.paddingRight = 8;
- entryContainer.style.marginBottom = 5;
- entryContainer.style.alignItems = Align.Center;
- // Status indicator
- var statusDot = new VisualElement();
- statusDot.style.width = 12;
- statusDot.style.height = 12;
- statusDot.style.borderBottomLeftRadius = 6;
- statusDot.style.borderBottomRightRadius = 6;
- statusDot.style.borderTopLeftRadius = 6;
- statusDot.style.borderTopRightRadius = 6;
- statusDot.style.backgroundColor = fight.isActive ? Color.red : new Color(1f, 0.5f, 0f);
- statusDot.style.marginRight = 8;
- entryContainer.Add(statusDot);
- // Fight text
- var fightText = new Label(fight.GetDisplayText());
- fightText.style.color = Color.white;
- fightText.style.fontSize = 12;
- fightText.style.flexGrow = 1;
- entryContainer.Add(fightText);
- // Zoom button
- var zoomButton = new Button(() => ZoomToFight(fight));
- zoomButton.text = "Zoom";
- zoomButton.style.width = 60;
- zoomButton.style.height = 25;
- zoomButton.style.backgroundColor = new Color(0.2f, 0.5f, 0.9f, 0.9f);
- zoomButton.style.color = Color.white;
- zoomButton.style.fontSize = 11;
- zoomButton.style.marginLeft = 8;
- entryContainer.Add(zoomButton);
- return entryContainer;
- }
- /// <summary>
- /// Updates an existing fight entry
- /// </summary>
- private void UpdateFightEntry(VisualElement entryElement, FightData fight)
- {
- if (entryElement == null) return;
- // Update status dot color
- var statusDot = entryElement.Q<VisualElement>(null, "unity-content-container")?.Children().FirstOrDefault() as VisualElement;
- if (statusDot != null)
- {
- statusDot.style.backgroundColor = fight.isActive ? Color.red : new Color(1f, 0.5f, 0f);
- }
- }
- /// <summary>
- /// Zooms the camera to the room where the fight is happening
- /// </summary>
- private void ZoomToFight(FightData fight)
- {
- var cameraController = FindAnyObjectByType<MazeCameraController>();
- if (cameraController != null)
- {
- cameraController.ZoomToRoom(fight.room, 1.3f, 0.5f);
- }
- }
- }
|