using UnityEngine; using UnityEngine.UIElements; using System.Reflection; public class MapSceneLegendUI : MonoBehaviour, IClickBlocker { [Header("UI References")] public UIDocument uiDocument; [Header("Settings")] public bool startVisible = true; public KeyCode toggleKey = KeyCode.L; public bool debugMode = true; // UI Elements private VisualElement legendContainer; private Button toggleButton; private VisualElement legendContent; private VisualElement nameToggleSection; // Name toggle buttons private Toggle settlementNamesToggle; private Toggle forestNamesToggle; private Toggle lakeNamesToggle; private Toggle plainNamesToggle; private Toggle mountainNamesToggle; private Toggle riverNamesToggle; // References private MapLocationNameDisplay nameDisplay; private bool isLegendVisible; // Helper method to call methods on WorldSpaceLocationNames using reflection private void TryCallWorldSpaceMethod(string methodName, bool parameter) { var allMonoBehaviours = FindObjectsByType(FindObjectsSortMode.None); foreach (var mb in allMonoBehaviours) { if (mb.GetType().Name == "WorldSpaceLocationNames") { var method = mb.GetType().GetMethod(methodName); if (method != null) { method.Invoke(mb, new object[] { parameter }); break; } } } } private void Awake() { if (uiDocument == null) uiDocument = GetComponent(); } private void Start() { nameDisplay = FindFirstObjectByType(); if (debugMode) { Debug.Log($"MapSceneLegendUI: Starting setup. UIDocument: {(uiDocument != null ? "Found" : "NULL")}"); Debug.Log($"MapSceneLegendUI: NameDisplay: {(nameDisplay != null ? "Found" : "NULL")}"); Debug.Log($"MapSceneLegendUI: Root Visual Element: {(uiDocument?.rootVisualElement != null ? "Found" : "NULL")}"); } SetupUI(); SetLegendVisible(startVisible); if (debugMode) { Debug.Log($"MapSceneLegendUI: Setup complete. Legend visible: {isLegendVisible}"); Debug.Log($"MapSceneLegendUI: Legend container: {(legendContainer != null ? "Found" : "NULL")}"); } // Register with ClickManager if (ClickManager.Instance != null) { ClickManager.Instance.RegisterClickBlocker(this); if (debugMode) Debug.Log("MapSceneLegendUI: Registered with ClickManager"); } else if (debugMode) { Debug.LogWarning("MapSceneLegendUI: ClickManager not found"); } } private void OnDestroy() { // Unregister from ClickManager if (ClickManager.Instance != null) { ClickManager.Instance.UnregisterClickBlocker(this); } } private void Update() { if (Input.GetKeyDown(toggleKey)) { ToggleLegend(); } } private void SetupUI() { if (uiDocument == null) { if (debugMode) Debug.LogError("MapSceneLegendUI: UIDocument is null! Cannot setup UI."); return; } var root = uiDocument.rootVisualElement; if (root == null) { if (debugMode) Debug.LogError("MapSceneLegendUI: Root visual element is null!"); return; } if (debugMode) Debug.Log("MapSceneLegendUI: Setting up UI..."); // Try to find existing legend container from UXML first legendContainer = root.Q("map-legend-container"); if (legendContainer != null) { // UXML is loaded, use existing structure if (debugMode) Debug.Log("MapSceneLegendUI: Using UXML structure"); legendContent = legendContainer; // Find the name toggle section nameToggleSection = root.Q("name-toggle-section"); if (nameToggleSection == null) { // Create it if not found nameToggleSection = new VisualElement(); nameToggleSection.name = "name-toggle-section"; nameToggleSection.AddToClassList("legend-section"); var sectionTitle = new Label("Location Names"); sectionTitle.AddToClassList("legend-section-title"); nameToggleSection.Add(sectionTitle); legendContainer.Add(nameToggleSection); } // Create name toggles CreateNameTogglesSection(); } else { // Fallback to programmatic creation if (debugMode) Debug.Log("MapSceneLegendUI: Using programmatic UI creation"); // Create main legend container legendContainer = new VisualElement(); legendContainer.name = "map-legend-container"; legendContainer.AddToClassList("map-legend"); // Create toggle button toggleButton = new Button(() => ToggleLegend()); toggleButton.text = "Map Legend"; toggleButton.name = "legend-toggle-button"; toggleButton.AddToClassList("legend-toggle-btn"); // Create legend content legendContent = new VisualElement(); legendContent.name = "legend-content"; legendContent.AddToClassList("legend-content"); // Add title var title = new Label("Map Legend"); title.AddToClassList("legend-title"); legendContent.Add(title); // Create terrain legend section CreateTerrainLegend(); // Create name toggles section CreateNameTogglesSection(); // Create controls info CreateControlsInfo(); // Assemble the UI legendContainer.Add(toggleButton); legendContainer.Add(legendContent); root.Add(legendContainer); } // Apply styles ApplyStyles(); if (debugMode) Debug.Log("MapSceneLegendUI: UI setup complete"); } private void CreateTerrainLegend() { var terrainSection = new VisualElement(); terrainSection.AddToClassList("legend-section"); var terrainTitle = new Label("Terrain"); terrainTitle.AddToClassList("legend-section-title"); terrainSection.Add(terrainTitle); // Terrain items var terrainItems = new[] { ("Ocean", "ocean-color"), ("Rivers / Lakes", "river-color"), ("Plains / Grasslands", "plain-color"), ("Forests", "forest-color"), ("Mountains", "mountain-color"), ("Towns / Cities", "town-color"), ("Villages", "village-color"), ("Roads", "road-color") }; foreach (var (label, colorClass) in terrainItems) { var item = CreateLegendItem(label, colorClass); terrainSection.Add(item); } legendContent.Add(terrainSection); } private void CreateNameTogglesSection() { nameToggleSection = new VisualElement(); nameToggleSection.AddToClassList("legend-section"); var nameTitle = new Label("Location Names"); nameTitle.AddToClassList("legend-section-title"); nameToggleSection.Add(nameTitle); // Create toggle switches for each name type settlementNamesToggle = CreateNameToggle("Settlements", true, (show) => { // Try both old and new name display systems if (nameDisplay == null) nameDisplay = FindFirstObjectByType(); if (nameDisplay != null) nameDisplay.ToggleSettlementNames(show); // Also try to find WorldSpaceLocationNames component using reflection TryCallWorldSpaceMethod("ToggleSettlementNames", show); }); forestNamesToggle = CreateNameToggle("Forests", true, (show) => { if (nameDisplay == null) nameDisplay = FindFirstObjectByType(); if (nameDisplay != null) nameDisplay.ToggleForestNames(show); TryCallWorldSpaceMethod("ToggleForestNames", show); }); lakeNamesToggle = CreateNameToggle("Lakes", true, (show) => { if (nameDisplay == null) nameDisplay = FindFirstObjectByType(); if (nameDisplay != null) nameDisplay.ToggleLakeNames(show); TryCallWorldSpaceMethod("ToggleLakeNames", show); }); plainNamesToggle = CreateNameToggle("Plains", true, (show) => { if (nameDisplay == null) nameDisplay = FindFirstObjectByType(); if (nameDisplay != null) nameDisplay.TogglePlainNames(show); TryCallWorldSpaceMethod("TogglePlainNames", show); }); mountainNamesToggle = CreateNameToggle("Mountains", true, (show) => { if (nameDisplay == null) nameDisplay = FindFirstObjectByType(); if (nameDisplay != null) nameDisplay.ToggleMountainNames(show); TryCallWorldSpaceMethod("ToggleMountainNames", show); }); riverNamesToggle = CreateNameToggle("Rivers", true, (show) => { if (nameDisplay == null) nameDisplay = FindFirstObjectByType(); if (nameDisplay != null) nameDisplay.ToggleRiverNames(show); TryCallWorldSpaceMethod("ToggleRiverNames", show); }); nameToggleSection.Add(settlementNamesToggle); nameToggleSection.Add(forestNamesToggle); nameToggleSection.Add(lakeNamesToggle); nameToggleSection.Add(plainNamesToggle); nameToggleSection.Add(mountainNamesToggle); nameToggleSection.Add(riverNamesToggle); legendContent.Add(nameToggleSection); } private Toggle CreateNameToggle(string labelText, bool defaultValue, System.Action onValueChanged) { var toggle = new Toggle(); toggle.text = labelText; toggle.value = defaultValue; toggle.AddToClassList("name-toggle"); toggle.RegisterValueChangedCallback(evt => onValueChanged(evt.newValue)); return toggle; } private void CreateControlsInfo() { var controlsSection = new VisualElement(); controlsSection.AddToClassList("legend-section"); controlsSection.AddToClassList("controls-info"); var controlsTitle = new Label("Controls"); controlsTitle.AddToClassList("legend-section-title"); controlsSection.Add(controlsTitle); var controls = new[] { "WASD / Arrow Keys: Move Camera", "Mouse Wheel: Zoom In/Out", $"{toggleKey}: Toggle Legend", "Click: Select Location", "Mouse Hover: Show Details" }; foreach (var controlText in controls) { var controlLabel = new Label(controlText); controlLabel.AddToClassList("controls-text"); controlsSection.Add(controlLabel); } legendContent.Add(controlsSection); } private VisualElement CreateLegendItem(string labelText, string colorClass) { var item = new VisualElement(); item.AddToClassList("legend-item"); var colorBox = new VisualElement(); colorBox.AddToClassList("color-box"); colorBox.AddToClassList(colorClass); var label = new Label(labelText); label.AddToClassList("legend-text"); item.Add(colorBox); item.Add(label); return item; } private void ApplyStyles() { var styleSheet = Resources.Load("UI/MapLegend"); if (styleSheet != null) { uiDocument.rootVisualElement.styleSheets.Add(styleSheet); } else { // Apply inline styles if stylesheet not found ApplyInlineStyles(); } } private void ApplyInlineStyles() { // Legend container positioning legendContainer.style.position = Position.Absolute; legendContainer.style.top = 20; legendContainer.style.left = 20; legendContainer.style.width = 250; // Toggle button toggleButton.style.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.9f); toggleButton.style.color = Color.white; toggleButton.style.borderTopLeftRadius = 5; toggleButton.style.borderTopRightRadius = 5; toggleButton.style.borderBottomLeftRadius = 0; toggleButton.style.borderBottomRightRadius = 0; toggleButton.style.paddingTop = 8; toggleButton.style.paddingBottom = 8; toggleButton.style.paddingLeft = 12; toggleButton.style.paddingRight = 12; // Legend content legendContent.style.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.9f); legendContent.style.borderBottomLeftRadius = 5; legendContent.style.borderBottomRightRadius = 5; legendContent.style.borderTopWidth = 1; legendContent.style.borderTopColor = new Color(0.4f, 0.4f, 0.4f, 0.8f); legendContent.style.paddingTop = 10; legendContent.style.paddingBottom = 10; legendContent.style.paddingLeft = 12; legendContent.style.paddingRight = 12; // Apply basic color classes ApplyTerrainColors(); } private void ApplyTerrainColors() { // This would ideally be done via USS, but for now we'll handle it in the legend creation // The actual color styling should be handled by the MapLegend.uss file } public void ToggleLegend() { if (debugMode) Debug.Log($"MapSceneLegendUI: Toggling legend. Current state: {isLegendVisible}"); SetLegendVisible(!isLegendVisible); } public void SetLegendVisible(bool visible) { isLegendVisible = visible; if (legendContent != null) { legendContent.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None; if (debugMode) Debug.Log($"MapSceneLegendUI: Set legend visible: {visible}"); } else if (debugMode) { Debug.LogWarning("MapSceneLegendUI: Cannot set visibility - legendContent is null"); } if (toggleButton != null) { toggleButton.text = visible ? "Hide Legend" : "Map Legend"; } } public void OnFeaturesGenerated() { // Refresh the toggle states to match the current display settings if (nameDisplay != null) { settlementNamesToggle?.SetValueWithoutNotify(nameDisplay.showSettlementNames); forestNamesToggle?.SetValueWithoutNotify(nameDisplay.showForestNames); lakeNamesToggle?.SetValueWithoutNotify(nameDisplay.showLakeNames); plainNamesToggle?.SetValueWithoutNotify(nameDisplay.showPlainNames); mountainNamesToggle?.SetValueWithoutNotify(nameDisplay.showMountainNames); riverNamesToggle?.SetValueWithoutNotify(nameDisplay.showRiverNames); } } // IClickBlocker implementation public bool IsBlockingClick(Vector2 screenPosition) { if (!isLegendVisible || legendContainer == null) return false; // Convert screen position to UI coordinates and check if it's within the legend bounds var panelGeometry = legendContainer.worldBound; return panelGeometry.Contains(screenPosition); } [ContextMenu("Toggle Legend")] public void ToggleLegendManual() { ToggleLegend(); } [ContextMenu("Show Legend")] public void ShowLegend() { SetLegendVisible(true); } [ContextMenu("Hide Legend")] public void HideLegend() { SetLegendVisible(false); } [ContextMenu("Debug Legend")] public void RefreshNameDisplayConnection() { // Try to find the name display if it wasn't found initially if (nameDisplay == null) { nameDisplay = FindFirstObjectByType(); if (debugMode && nameDisplay != null) { Debug.Log("MapSceneLegendUI: Successfully connected to MapLocationNameDisplay"); } } } public void DebugLegend() { Debug.Log($"=== MapSceneLegendUI Debug Info ==="); Debug.Log($"UIDocument: {(uiDocument != null ? "Found" : "NULL")}"); Debug.Log($"LegendContainer: {(legendContainer != null ? "Found" : "NULL")}"); Debug.Log($"LegendContent: {(legendContent != null ? "Found" : "NULL")}"); Debug.Log($"IsLegendVisible: {isLegendVisible}"); Debug.Log($"NameDisplay: {(nameDisplay != null ? "Found" : "NULL")}"); if (uiDocument?.rootVisualElement != null) { Debug.Log($"Root element children: {uiDocument.rootVisualElement.childCount}"); } } }