using UnityEngine; using System.Collections.Generic; using System.Linq; /// /// Simple IMGUI-based enemy selection UI for attack targeting /// Alternative to direct mouse targeting /// public class EnemySelectionUI : MonoBehaviour { [Header("Settings")] public KeyCode toggleKey = KeyCode.Tab; public bool useEnemyListMode = false; // Can be toggled in inspector [Header("UI Settings")] public float windowWidth = 300f; public float windowHeight = 400f; public float buttonHeight = 40f; private bool isVisible = false; private Character currentAttacker; private List availableEnemies = new List(); private Character selectedEnemy; private Vector2 scrollPosition; // Events public event System.Action OnEnemySelected; public event System.Action OnSelectionCancelled; private GUIStyle windowStyle; private GUIStyle buttonStyle; private GUIStyle selectedButtonStyle; private GUIStyle labelStyle; private bool stylesInitialized = false; void Update() { // Toggle enemy list mode with Tab key if (Input.GetKeyDown(toggleKey)) { useEnemyListMode = !useEnemyListMode; Debug.Log($"🎯 Enemy selection mode: {(useEnemyListMode ? "List UI" : "Direct Targeting")}"); } // Close UI with Escape if (isVisible && Input.GetKeyDown(KeyCode.Escape)) { HideEnemySelection(); OnSelectionCancelled?.Invoke(); } } void OnGUI() { if (!isVisible) return; InitializeStyles(); DrawEnemySelectionWindow(); } private void InitializeStyles() { if (stylesInitialized) return; windowStyle = new GUIStyle(GUI.skin.window); windowStyle.fontSize = 16; windowStyle.fontStyle = FontStyle.Bold; buttonStyle = new GUIStyle(GUI.skin.button); buttonStyle.fontSize = 14; buttonStyle.alignment = TextAnchor.MiddleLeft; buttonStyle.padding = new RectOffset(10, 10, 10, 10); selectedButtonStyle = new GUIStyle(buttonStyle); selectedButtonStyle.normal.background = buttonStyle.active.background; selectedButtonStyle.normal.textColor = Color.yellow; selectedButtonStyle.fontStyle = FontStyle.Bold; labelStyle = new GUIStyle(GUI.skin.label); labelStyle.fontSize = 14; labelStyle.fontStyle = FontStyle.Bold; labelStyle.alignment = TextAnchor.MiddleCenter; stylesInitialized = true; } private void DrawEnemySelectionWindow() { Rect windowRect = new Rect( Screen.width - windowWidth - 20, (Screen.height - windowHeight) / 2, windowWidth, windowHeight ); GUI.Window(0, windowRect, DrawWindowContent, $"Select Target for {(currentAttacker ? currentAttacker.CharacterName : "Character")}", windowStyle); } private void DrawWindowContent(int windowID) { GUILayout.BeginVertical(); // Instructions GUILayout.Label("Choose an enemy to attack:", labelStyle); GUILayout.Space(10); // Scroll area for enemy list scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.ExpandHeight(true)); foreach (Character enemy in availableEnemies) { if (enemy == null) continue; bool isSelected = (selectedEnemy == enemy); GUIStyle currentStyle = isSelected ? selectedButtonStyle : buttonStyle; // Create button content with enemy info string buttonText = $"{enemy.CharacterName}"; if (enemy.TryGetComponent(out var character)) { buttonText += $" (HP: {character.CurrentHealth}/{character.MaxHealth})"; } if (GUILayout.Button(buttonText, currentStyle, GUILayout.Height(buttonHeight))) { SelectEnemy(enemy); } // Highlight selected enemy in the scene if (isSelected) { HighlightEnemy(enemy); } } GUILayout.EndScrollView(); GUILayout.Space(10); // Action buttons GUILayout.BeginHorizontal(); GUI.enabled = selectedEnemy != null; if (GUILayout.Button("Attack Selected", GUILayout.Height(30))) { ConfirmSelection(); } GUI.enabled = true; if (GUILayout.Button("Cancel", GUILayout.Height(30))) { CancelSelection(); } GUILayout.EndHorizontal(); GUILayout.Space(5); GUILayout.Label("Press TAB to toggle targeting mode", GUI.skin.box); GUILayout.Label("Press ESC to cancel", GUI.skin.box); GUILayout.EndVertical(); } public void ShowEnemySelection(Character attacker) { if (!useEnemyListMode) { Debug.Log("🎯 Enemy list mode disabled - use direct targeting"); return; } currentAttacker = attacker; selectedEnemy = null; // Find all enemy characters RefreshEnemyList(); if (availableEnemies.Count == 0) { Debug.LogWarning("No enemies found for targeting!"); return; } isVisible = true; Debug.Log($"🎯 Enemy selection UI shown for {attacker.CharacterName} - {availableEnemies.Count} enemies available"); } public void HideEnemySelection() { isVisible = false; selectedEnemy = null; ClearEnemyHighlights(); Debug.Log("🎯 Enemy selection UI hidden"); } private void RefreshEnemyList() { availableEnemies.Clear(); // Find all characters tagged as enemies Character[] allCharacters = FindObjectsByType(FindObjectsSortMode.None); foreach (Character character in allCharacters) { if (character.CompareTag("Enemy") && character.CurrentHealth > 0) { availableEnemies.Add(character); } } // Sort by distance to attacker for convenience if (currentAttacker != null) { availableEnemies = availableEnemies .OrderBy(enemy => Vector3.Distance(currentAttacker.transform.position, enemy.transform.position)) .ToList(); } Debug.Log($"🎯 Found {availableEnemies.Count} available enemies"); } private void SelectEnemy(Character enemy) { // Clear previous selection highlight if (selectedEnemy != null) { ClearEnemyHighlight(selectedEnemy); } selectedEnemy = enemy; Debug.Log($"🎯 Selected enemy: {enemy.CharacterName}"); } private void ConfirmSelection() { if (selectedEnemy != null) { Debug.Log($"✅ Attack target confirmed: {selectedEnemy.CharacterName}"); OnEnemySelected?.Invoke(selectedEnemy); HideEnemySelection(); } } private void CancelSelection() { Debug.Log("❌ Enemy selection cancelled"); OnSelectionCancelled?.Invoke(); HideEnemySelection(); } private void HighlightEnemy(Character enemy) { // Add visual highlight to the enemy (simple outline or color change) if (enemy != null) { // Use the character's existing visual state system enemy.SetVisualState(ActionDecisionState.NoAction); // Temporary highlight } } private void ClearEnemyHighlight(Character enemy) { if (enemy != null) { enemy.SetVisualState(ActionDecisionState.NoAction); // Reset to normal } } private void ClearEnemyHighlights() { foreach (Character enemy in availableEnemies) { ClearEnemyHighlight(enemy); } } void OnDestroy() { OnEnemySelected = null; OnSelectionCancelled = null; } }