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;
}
}