| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- using UnityEngine;
- using System.Collections.Generic;
- using System.Linq;
- /// <summary>
- /// Simple IMGUI-based enemy selection UI for attack targeting
- /// Alternative to direct mouse targeting
- /// </summary>
- 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<Character> availableEnemies = new List<Character>();
- private Character selectedEnemy;
- private Vector2 scrollPosition;
- // Events
- public event System.Action<Character> 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<Character>(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<Character>(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;
- }
- }
|