Explorar el Código

New combat selection system

Axel Nordh hace 8 meses
padre
commit
b94e7d2086

+ 172 - 0
Assets/Resources/UI/ItemSelectionUI.uss

@@ -0,0 +1,172 @@
+/* Item Selection UI Styles */
+
+.item-selection-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.7);
+    align-items: center;
+    justify-content: center;
+    display: flex;
+}
+
+.item-selection-modal {
+    background-color: rgb(45, 45, 45);
+    border-color: rgb(100, 100, 100);
+    border-width: 2px;
+    border-radius: 8px;
+    width: 400px;
+    height: 500px;
+    padding: 0;
+}
+
+.header {
+    background-color: rgb(60, 60, 60);
+    border-bottom-width: 1px;
+    border-bottom-color: rgb(100, 100, 100);
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    padding: 10px 15px;
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+}
+
+.title {
+    font-size: 18px;
+    color: rgb(255, 255, 255);
+    -unity-font-style: bold;
+    margin: 0;
+}
+
+.close-button {
+    width: 25px;
+    height: 25px;
+    background-color: rgb(200, 80, 80);
+    border-radius: 12px;
+    border-width: 0;
+    color: white;
+    font-size: 16px;
+    -unity-font-style: bold;
+}
+
+.close-button:hover {
+    background-color: rgb(220, 100, 100);
+}
+
+.close-button:active {
+    background-color: rgb(180, 60, 60);
+}
+
+.content {
+    padding: 15px;
+    flex-grow: 1;
+}
+
+.character-label {
+    font-size: 16px;
+    color: rgb(255, 220, 100);
+    -unity-font-style: bold;
+    margin-bottom: 10px;
+    -unity-text-align: middle-center;
+}
+
+.instruction-label {
+    font-size: 14px;
+    color: rgb(200, 200, 200);
+    margin-bottom: 15px;
+    -unity-text-align: middle-center;
+}
+
+.item-scroll-view {
+    flex-grow: 1;
+    margin-bottom: 15px;
+}
+
+.item-list {
+    flex-grow: 1;
+}
+
+.item-button {
+    background-color: rgb(60, 60, 60);
+    border-color: rgb(100, 100, 100);
+    border-width: 1px;
+    border-radius: 4px;
+    margin-bottom: 8px;
+    padding: 12px 15px;
+    flex-direction: column;
+    align-items: stretch;
+}
+
+.item-button:hover {
+    background-color: rgb(80, 80, 80);
+    border-color: rgb(150, 150, 150);
+}
+
+.item-button:active {
+    background-color: rgb(100, 100, 100);
+}
+
+.item-name {
+    font-size: 14px;
+    color: rgb(255, 255, 255);
+    -unity-font-style: bold;
+    margin-bottom: 4px;
+}
+
+.item-description {
+    font-size: 12px;
+    color: rgb(180, 180, 180);
+    -unity-font-style: italic;
+}
+
+.no-items-container {
+    align-items: center;
+    justify-content: center;
+    flex-grow: 1;
+}
+
+.no-items-label {
+    font-size: 14px;
+    color: rgb(150, 150, 150);
+    -unity-font-style: italic;
+    -unity-text-align: middle-center;
+}
+
+.footer {
+    background-color: rgb(50, 50, 50);
+    border-top-width: 1px;
+    border-top-color: rgb(100, 100, 100);
+    padding: 10px 15px;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom-left-radius: 6px;
+    border-bottom-right-radius: 6px;
+}
+
+.cancel-button {
+    background-color: rgb(120, 120, 120);
+    border-color: rgb(100, 100, 100);
+    border-width: 1px;
+    border-radius: 4px;
+    padding: 8px 16px;
+    color: white;
+    font-size: 14px;
+}
+
+.cancel-button:hover {
+    background-color: rgb(140, 140, 140);
+}
+
+.cancel-button:active {
+    background-color: rgb(100, 100, 100);
+}
+
+.help-text {
+    font-size: 12px;
+    color: rgb(150, 150, 150);
+    -unity-font-style: italic;
+}

+ 29 - 0
Assets/Resources/UI/ItemSelectionUI.uxml

@@ -0,0 +1,29 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <ui:VisualElement name="ItemSelectionContainer" class="item-selection-container">
+        <ui:VisualElement name="ItemSelectionModal" class="item-selection-modal">
+            <ui:VisualElement name="Header" class="header">
+                <ui:Label name="TitleLabel" text="Select Item" class="title" />
+                <ui:Button name="CloseButton" text="×" class="close-button" />
+            </ui:VisualElement>
+            
+            <ui:VisualElement name="Content" class="content">
+                <ui:Label name="CharacterLabel" text="Character Name" class="character-label" />
+                <ui:Label name="InstructionLabel" text="Choose an item to use:" class="instruction-label" />
+                
+                <ui:ScrollView name="ItemScrollView" class="item-scroll-view">
+                    <ui:VisualElement name="ItemList" class="item-list">
+                    </ui:VisualElement>
+                </ui:ScrollView>
+                
+                <ui:VisualElement name="NoItemsContainer" class="no-items-container" style="display: none;">
+                    <ui:Label text="No usable items available" class="no-items-label" />
+                </ui:VisualElement>
+            </ui:VisualElement>
+            
+            <ui:VisualElement name="Footer" class="footer">
+                <ui:Button name="CancelButton" text="Cancel" class="cancel-button" />
+                <ui:Label name="HelpText" text="Press ESC to cancel" class="help-text" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 29 - 0
Assets/Resources/UI/ItemSelectionUI_Fixed.uxml

@@ -0,0 +1,29 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <ui:VisualElement name="ItemSelectionContainer" class="item-selection-container">
+        <ui:VisualElement name="ItemSelectionModal" class="item-selection-modal">
+            <ui:VisualElement name="Header" class="header">
+                <ui:Label name="TitleLabel" text="Select Item" class="title" />
+                <ui:Button name="CloseButton" text="×" class="close-button" />
+            </ui:VisualElement>
+            
+            <ui:VisualElement name="Content" class="content">
+                <ui:Label name="CharacterLabel" text="Character Name" class="character-label" />
+                <ui:Label name="InstructionLabel" text="Choose an item to use:" class="instruction-label" />
+                
+                <ui:ScrollView name="ItemScrollView" class="item-scroll-view">
+                    <ui:VisualElement name="ItemList" class="item-list">
+                    </ui:VisualElement>
+                </ui:ScrollView>
+                
+                <ui:VisualElement name="NoItemsContainer" class="no-items-container" style="display: none;">
+                    <ui:Label text="No usable items available" class="no-items-label" />
+                </ui:VisualElement>
+            </ui:VisualElement>
+            
+            <ui:VisualElement name="Footer" class="footer">
+                <ui:Button name="CancelButton" text="Cancel" class="cancel-button" />
+                <ui:Label name="HelpText" text="Press ESC to cancel" class="help-text" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 14 - 0
Assets/Resources/UI/ItemSelectionUI_Simple.uxml

@@ -0,0 +1,14 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements">
+    <ui:VisualElement name="ItemSelectionContainer">
+        <ui:VisualElement name="ItemSelectionModal">
+            <ui:Label name="TitleLabel" text="Select Item" />
+            <ui:Label name="CharacterLabel" text="Character Name" />
+            <ui:VisualElement name="ItemList" />
+            <ui:VisualElement name="NoItemsContainer">
+                <ui:Label text="No usable items available" />
+            </ui:VisualElement>
+            <ui:Button name="CancelButton" text="Cancel" />
+            <ui:Button name="CloseButton" text="Close" />
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 105 - 0
Assets/Scenes/BattleScene.unity

@@ -129,6 +129,8 @@ GameObject:
   m_Component:
   - component: {fileID: 291472280}
   - component: {fileID: 291472279}
+  - component: {fileID: 291472281}
+  - component: {fileID: 291472282}
   m_Layer: 0
   m_Name: BattleIntegrationSetup
   m_TagString: Untagged
@@ -169,6 +171,39 @@ Transform:
   m_Children: []
   m_Father: {fileID: 0}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &291472281
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 291472278}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: e4b3beaf54c40e040a42193e12fe18fa, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  uiDocument: {fileID: 291472282}
+  maxItemsToShow: 10
+--- !u!114 &291472282
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 291472278}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_PanelSettings: {fileID: 11400000, guid: 0d7125098b341c74d868b72a1bacddf4, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: f2b5bbcffdc7d9e44a089bd0887d3def, type: 3}
+  m_SortingOrder: 0
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
 --- !u!1 &330585543
 GameObject:
   m_ObjectHideFlags: 0
@@ -1401,6 +1436,75 @@ Transform:
   - {fileID: 330585546}
   m_Father: {fileID: 0}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1566626101
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1566626103}
+  - component: {fileID: 1566626102}
+  - component: {fileID: 1566626104}
+  m_Layer: 0
+  m_Name: ActionWheelComponent
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1566626102
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566626101}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3c9a800e450843645b180388d915045e, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  playerDecisionController: {fileID: 0}
+  battleActionSystem: {fileID: 0}
+  actionWheel: {fileID: 0}
+  enemySelectionUI: {fileID: 0}
+  itemSelectionUI: {fileID: 0}
+  useNewActionSystem: 1
+  actionWheelKey: 32
+--- !u!4 &1566626103
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566626101}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 2.962676, y: 0.00000011920929, z: 11.034308}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1566626104
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1566626101}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 404f392a3dc713e45a4f328c2b0d0c4b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  toggleKey: 9
+  useEnemyListMode: 0
+  windowWidth: 300
+  windowHeight: 400
+  buttonHeight: 40
 --- !u!1 &1940765008
 GameObject:
   m_ObjectHideFlags: 0
@@ -1685,3 +1789,4 @@ SceneRoots:
   - {fileID: 864824021}
   - {fileID: 865903348}
   - {fileID: 291472280}
+  - {fileID: 1566626103}

+ 103 - 0
Assets/Scripts/BattleScene/ActionButtonCreator.cs

@@ -0,0 +1,103 @@
+using UnityEngine;
+using UnityEngine.UI;
+using TMPro;
+
+/// <summary>
+/// Simple script to help create action button prefabs programmatically
+/// This can be attached to a prefab or used to create buttons at runtime
+/// </summary>
+public class ActionButtonCreator : MonoBehaviour
+{
+    [Header("Button Creation")]
+    public bool createButtonOnStart = false;
+    public string buttonText = "Action";
+    public Sprite buttonIcon;
+
+    void Start()
+    {
+        if (createButtonOnStart)
+        {
+            CreateActionButton();
+        }
+    }
+
+    /// <summary>
+    /// Creates a complete action button with icon and text
+    /// </summary>
+    public static GameObject CreateActionButton(Transform parent, string buttonName = "ActionButton")
+    {
+        // Create main button object
+        GameObject buttonObj = new GameObject(buttonName);
+        buttonObj.transform.SetParent(parent, false);
+
+        // Add RectTransform
+        RectTransform rectTransform = buttonObj.AddComponent<RectTransform>();
+        rectTransform.sizeDelta = new Vector2(60, 60);
+
+        // Add Image component for background
+        Image backgroundImage = buttonObj.AddComponent<Image>();
+        backgroundImage.color = new Color(0.2f, 0.2f, 0.2f, 0.8f);
+        backgroundImage.type = Image.Type.Sliced;
+
+        // Add Button component
+        Button button = buttonObj.AddComponent<Button>();
+
+        // Create Icon child
+        GameObject iconObj = new GameObject("Icon");
+        iconObj.transform.SetParent(buttonObj.transform, false);
+
+        RectTransform iconRect = iconObj.AddComponent<RectTransform>();
+        iconRect.anchorMin = new Vector2(0.1f, 0.3f);
+        iconRect.anchorMax = new Vector2(0.9f, 0.9f);
+        iconRect.offsetMin = Vector2.zero;
+        iconRect.offsetMax = Vector2.zero;
+
+        Image iconImage = iconObj.AddComponent<Image>();
+        iconImage.color = Color.white;
+
+        // Create Label child
+        GameObject labelObj = new GameObject("Label");
+        labelObj.transform.SetParent(buttonObj.transform, false);
+
+        RectTransform labelRect = labelObj.AddComponent<RectTransform>();
+        labelRect.anchorMin = new Vector2(0f, 0f);
+        labelRect.anchorMax = new Vector2(1f, 0.3f);
+        labelRect.offsetMin = Vector2.zero;
+        labelRect.offsetMax = Vector2.zero;
+
+        TextMeshProUGUI labelText = labelObj.AddComponent<TextMeshProUGUI>();
+        labelText.text = "Action";
+        labelText.fontSize = 8;
+        labelText.alignment = TextAlignmentOptions.Center;
+        labelText.color = Color.white;
+
+        // Setup button colors
+        ColorBlock colors = button.colors;
+        colors.normalColor = new Color(0.2f, 0.2f, 0.2f, 0.8f);
+        colors.highlightedColor = new Color(0.3f, 0.3f, 0.3f, 0.9f);
+        colors.pressedColor = new Color(0.1f, 0.1f, 0.1f, 0.9f);
+        colors.selectedColor = new Color(0.3f, 0.3f, 0.3f, 0.9f);
+        colors.disabledColor = new Color(0.1f, 0.1f, 0.1f, 0.5f);
+        button.colors = colors;
+
+        return buttonObj;
+    }
+
+    private void CreateActionButton()
+    {
+        GameObject button = CreateActionButton(transform, buttonText);
+
+        // Set icon if provided
+        if (buttonIcon != null)
+        {
+            Image iconImage = button.transform.Find("Icon").GetComponent<Image>();
+            if (iconImage != null)
+                iconImage.sprite = buttonIcon;
+        }
+
+        // Set text
+        TextMeshProUGUI labelText = button.transform.Find("Label").GetComponent<TextMeshProUGUI>();
+        if (labelText != null)
+            labelText.text = buttonText;
+    }
+}

+ 175 - 0
Assets/Scripts/BattleScene/BattleActionData.cs

@@ -0,0 +1,175 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+/// <summary>
+/// Defines all possible battle actions a character can take
+/// </summary>
+public enum BattleActionType
+{
+    Move,
+    Attack,
+    UseItem,
+    CastSpell,
+    RunAway,
+    Defend, // Optional: block/defend action
+    Wait     // Optional: skip turn but maintain position
+}
+
+/// <summary>
+/// Enhanced action data to support multiple action types
+/// </summary>
+[System.Serializable]
+public class EnhancedCharacterActionData
+{
+    [Header("Action State")]
+    public ActionDecisionState state = ActionDecisionState.NoAction;
+    public BattleActionType actionType = BattleActionType.Move;
+
+    [Header("Targeting")]
+    public Vector3 targetPosition = Vector3.zero;
+    public GameObject targetEnemy;
+    public Character targetCharacter; // For healing spells/items
+
+    [Header("Item/Spell Data")]
+    public string selectedItemName = "";
+    public string selectedSpellName = "";
+    public int selectedItemIndex = -1;
+
+    [Header("Action Properties")]
+    public bool requiresTarget = false;
+    public bool isAreaOfEffect = false;
+    public float aoeRadius = 0f;
+
+    public bool hasTarget => targetEnemy != null || targetCharacter != null || targetPosition != Vector3.zero;
+    public bool hasValidAction => state == ActionDecisionState.ActionSelected &&
+                                 (actionType == BattleActionType.Wait ||
+                                  actionType == BattleActionType.Defend ||
+                                  actionType == BattleActionType.RunAway ||
+                                  hasTarget ||
+                                  (!string.IsNullOrEmpty(selectedItemName) && selectedItemIndex >= 0) ||
+                                  !string.IsNullOrEmpty(selectedSpellName));
+
+    public void Reset()
+    {
+        state = ActionDecisionState.NoAction;
+        actionType = BattleActionType.Move;
+        targetPosition = Vector3.zero;
+        targetEnemy = null;
+        targetCharacter = null;
+        selectedItemName = "";
+        selectedSpellName = "";
+        selectedItemIndex = -1;
+        requiresTarget = false;
+        isAreaOfEffect = false;
+        aoeRadius = 0f;
+    }
+
+    public void SetMoveAction(Vector3 position)
+    {
+        Reset();
+        actionType = BattleActionType.Move;
+        targetPosition = position;
+        state = ActionDecisionState.ActionSelected;
+    }
+
+    public void SetAttackAction(GameObject enemy)
+    {
+        Reset();
+        actionType = BattleActionType.Attack;
+        targetEnemy = enemy;
+        requiresTarget = true;
+        state = ActionDecisionState.ActionSelected;
+    }
+
+    public void SetItemAction(string itemName, int itemIndex, bool requiresTargeting = false)
+    {
+        Reset();
+        actionType = BattleActionType.UseItem;
+        selectedItemName = itemName;
+        selectedItemIndex = itemIndex;
+        requiresTarget = requiresTargeting;
+        state = requiresTargeting ? ActionDecisionState.NoAction : ActionDecisionState.ActionSelected;
+    }
+
+    public void SetSpellAction(string spellName, bool requiresTargeting = false, bool isAoE = false, float radius = 0f)
+    {
+        Reset();
+        actionType = BattleActionType.CastSpell;
+        selectedSpellName = spellName;
+        requiresTarget = requiresTargeting;
+        isAreaOfEffect = isAoE;
+        aoeRadius = radius;
+        state = requiresTargeting ? ActionDecisionState.NoAction : ActionDecisionState.ActionSelected;
+    }
+
+    public void SetDefendAction()
+    {
+        Reset();
+        actionType = BattleActionType.Defend;
+        state = ActionDecisionState.ActionSelected;
+    }
+
+    public void SetWaitAction()
+    {
+        Reset();
+        actionType = BattleActionType.Wait;
+        state = ActionDecisionState.ActionSelected;
+    }
+
+    public void SetRunAwayAction()
+    {
+        Reset();
+        actionType = BattleActionType.RunAway;
+        state = ActionDecisionState.ActionSelected;
+    }
+
+    public void SetTarget(GameObject enemy)
+    {
+        targetEnemy = enemy;
+        if (requiresTarget)
+        {
+            state = ActionDecisionState.ActionSelected;
+        }
+    }
+
+    public void SetTarget(Character character)
+    {
+        targetCharacter = character;
+        if (requiresTarget)
+        {
+            state = ActionDecisionState.ActionSelected;
+        }
+    }
+
+    public void SetTarget(Vector3 position)
+    {
+        targetPosition = position;
+        if (requiresTarget && (isAreaOfEffect || actionType == BattleActionType.CastSpell))
+        {
+            state = ActionDecisionState.ActionSelected;
+        }
+    }
+
+    public string GetActionDescription()
+    {
+        switch (actionType)
+        {
+            case BattleActionType.Move:
+                return $"Move to {targetPosition}";
+            case BattleActionType.Attack:
+                return $"Attack {(targetEnemy ? targetEnemy.name : "target")}";
+            case BattleActionType.UseItem:
+                return $"Use {selectedItemName}";
+            case BattleActionType.CastSpell:
+                return $"Cast {selectedSpellName}";
+            case BattleActionType.Defend:
+                return "Defend";
+            case BattleActionType.Wait:
+                return "Wait";
+            case BattleActionType.RunAway:
+                return "Run Away";
+            default:
+                return "No Action";
+        }
+    }
+}

+ 595 - 0
Assets/Scripts/BattleScene/BattleActionIntegration.cs

@@ -0,0 +1,595 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+
+/// <summary>
+/// Integration script that connects the new battle action system with existing character selection
+/// This allows switching between the old click-drag system and the new action wheel system
+/// </summary>
+public class BattleActionIntegration : MonoBehaviour
+{
+    [Header("System References")]
+    public PlayerDecisionController playerDecisionController;
+    public BattleActionSystem battleActionSystem;
+    public BattleActionWheel actionWheel; // Legacy Canvas-based wheel
+    public EnemySelectionUI enemySelectionUI; // TODO: Add after compilation
+    public BattleItemSelector itemSelectionUI;
+
+    [Header("Settings")]
+    public bool useNewActionSystem = true;
+    public KeyCode actionWheelKey = KeyCode.Q; // Use Q consistently
+
+    private Character lastSelectedCharacter;
+    private MonoBehaviour simpleWheelComponent;
+    private string currentInstruction = "";
+    private float instructionTimer = 0f;
+    private float instructionDuration = 5f;
+
+    void Start()
+    {
+        Debug.Log("🚀 BattleActionIntegration starting...");
+
+        // Find components if not assigned
+        if (playerDecisionController == null)
+            playerDecisionController = FindFirstObjectByType<PlayerDecisionController>();
+
+        if (battleActionSystem == null)
+            battleActionSystem = FindFirstObjectByType<BattleActionSystem>();
+
+        if (actionWheel == null)
+            actionWheel = FindFirstObjectByType<BattleActionWheel>();
+
+        if (enemySelectionUI == null)
+            enemySelectionUI = FindFirstObjectByType<EnemySelectionUI>();
+
+        if (itemSelectionUI == null)
+            itemSelectionUI = FindFirstObjectByType<BattleItemSelector>();
+
+        // Disable old drag system if using new action system (but allow re-enabling for targeting)
+        if (useNewActionSystem && playerDecisionController != null)
+        {
+            // Don't completely disable - we'll use it for targeting after action selection
+            Debug.Log("🎮 PlayerDecisionController will be used for targeting after action selection");
+        }
+
+        // Try to find or create a simple wheel component
+        var existingWheels = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
+        foreach (var comp in existingWheels)
+        {
+            if (comp.GetType().Name == "SimpleActionWheel")
+            {
+                simpleWheelComponent = comp;
+                Debug.Log("🎮 Found existing SimpleActionWheel");
+                break;
+            }
+        }
+
+        if (simpleWheelComponent == null)
+        {
+            // Create simple wheel if it doesn't exist
+            GameObject wheelObj = new GameObject("SimpleActionWheel");
+            // Use reflection to add the component
+            var componentType = System.Type.GetType("SimpleActionWheel");
+            if (componentType != null)
+            {
+                simpleWheelComponent = wheelObj.AddComponent(componentType) as MonoBehaviour;
+                Debug.Log("🎮 Created SimpleActionWheel automatically");
+            }
+            else
+            {
+                Debug.LogError("❌ Could not find SimpleActionWheel type");
+            }
+        }
+
+        // Subscribe to events
+        if (battleActionSystem != null)
+        {
+            battleActionSystem.OnActionCompleted += OnCharacterActionCompleted;
+        }
+
+        // Connect SimpleActionWheel events using reflection
+        if (simpleWheelComponent != null)
+        {
+            ConnectSimpleWheelEvents();
+        }
+
+        Debug.Log($"✅ BattleActionIntegration initialized - useNewActionSystem: {useNewActionSystem}, actionWheelKey: {actionWheelKey}");
+    }
+
+    void Update()
+    {
+        if (useNewActionSystem)
+        {
+            HandleNewActionSystemInput();
+        }
+
+        // Update instruction timer
+        if (instructionTimer > 0f)
+        {
+            instructionTimer -= Time.deltaTime;
+            if (instructionTimer <= 0f)
+            {
+                currentInstruction = "";
+            }
+        }
+    }
+
+    void OnGUI()
+    {
+        // Show instruction message if active
+        if (!string.IsNullOrEmpty(currentInstruction))
+        {
+            GUIStyle instructionStyle = new GUIStyle(GUI.skin.label);
+            instructionStyle.fontSize = 18;
+            instructionStyle.fontStyle = FontStyle.Bold;
+            instructionStyle.alignment = TextAnchor.MiddleCenter;
+            instructionStyle.normal.textColor = Color.yellow;
+
+            Rect instructionRect = new Rect(0, 50, Screen.width, 30);
+
+            // Background
+            GUI.color = new Color(0, 0, 0, 0.7f);
+            GUI.Box(instructionRect, "");
+
+            // Text
+            GUI.color = Color.white;
+            GUI.Label(instructionRect, currentInstruction, instructionStyle);
+        }
+
+        if (!useNewActionSystem) return;
+
+        // Simple UI for testing
+        GUILayout.BeginArea(new Rect(10, 10, 300, 250));
+        GUILayout.Label("Battle Action System");
+        GUILayout.Label($"Action Key: {actionWheelKey}");
+        GUILayout.Label($"Simple Wheel: {(simpleWheelComponent != null ? "✅" : "❌")}");
+
+        if (lastSelectedCharacter != null)
+        {
+            GUILayout.Label($"Selected: {lastSelectedCharacter.CharacterName}");
+
+            var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (actionData != null && actionData.hasValidAction)
+            {
+                GUILayout.Label($"Action: {actionData.GetActionDescription()}");
+            }
+        }
+        else
+        {
+            GUILayout.Label("No character selected");
+            GUILayout.Label("Click a player character to select");
+        }
+
+        GUILayout.Label($"Press {actionWheelKey} to show action wheel");
+
+        if (GUILayout.Button("Test Action Wheel"))
+        {
+            var testCharacter = FindFirstObjectByType<Character>();
+            if (testCharacter != null)
+            {
+                ShowActionWheelForCharacter(testCharacter);
+            }
+        }
+
+        GUILayout.EndArea();
+    }
+
+    private void HandleNewActionSystemInput()
+    {
+        // Check for character selection
+        if (Input.GetMouseButtonDown(0))
+        {
+            Character selectedCharacter = GetCharacterAtMousePosition();
+            if (selectedCharacter != null)
+            {
+                Debug.Log($"🖱️ Clicked on character: {selectedCharacter.CharacterName} - Tag: {selectedCharacter.tag}");
+
+                if (selectedCharacter.CompareTag("Player"))
+                {
+                    Debug.Log($"✅ Confirmed player character: {selectedCharacter.CharacterName}");
+                    SelectCharacterForAction(selectedCharacter);
+                }
+                else
+                {
+                    Debug.Log($"❌ Not a player character: {selectedCharacter.CharacterName} (Tag: {selectedCharacter.tag})");
+                    // Try to force selection anyway for testing
+                    Debug.Log($"🧪 Trying to select anyway for testing...");
+                    SelectCharacterForAction(selectedCharacter);
+                }
+            }
+            else
+            {
+                Debug.Log("🖱️ Clicked but no character found");
+            }
+        }
+
+        // Show action wheel with Q key
+        if (Input.GetKeyDown(actionWheelKey))
+        {
+            if (lastSelectedCharacter != null)
+            {
+                Debug.Log($"⌨️ {actionWheelKey} pressed, showing wheel for {lastSelectedCharacter.CharacterName}");
+                ShowActionWheelForCharacter(lastSelectedCharacter);
+            }
+            else
+            {
+                Debug.Log($"⌨️ {actionWheelKey} pressed but no character selected");
+            }
+        }
+    }
+
+    private Character GetCharacterAtMousePosition()
+    {
+        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
+        RaycastHit hit;
+
+        if (Physics.Raycast(ray, out hit))
+        {
+            return hit.collider.GetComponent<Character>();
+        }
+
+        return null;
+    }
+
+    private void SelectCharacterForAction(Character character)
+    {
+        // Clear previous selection
+        if (lastSelectedCharacter != null)
+        {
+            lastSelectedCharacter.SetVisualState(ActionDecisionState.NoAction);
+        }
+
+        lastSelectedCharacter = character;
+
+        // Initialize enhanced action data if needed
+        var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (actionData == null)
+        {
+            // Create instance at runtime to avoid compilation issues
+            actionData = new EnhancedCharacterActionData();
+            character.SetEnhancedActionData(actionData);
+        }
+
+        // Highlight selected character
+        character.SetVisualState(ActionDecisionState.NoAction);
+
+        Debug.Log($"🎯 Selected character for action: {character.CharacterName}");
+
+        // Don't auto-show wheel - let user press Q manually
+        // if (useNewActionSystem)
+        // {
+        //     ShowActionWheelForCharacter(character);
+        // }
+    }
+
+    private void ShowActionWheelForCharacter(Character character)
+    {
+        Debug.Log($"🎯 ShowActionWheelForCharacter called for: {character.CharacterName}");
+
+        // Try simple wheel first
+        if (simpleWheelComponent != null)
+        {
+            Debug.Log($"🎮 Found SimpleActionWheel component: {simpleWheelComponent.GetType().Name}");
+
+            // Use reflection to call ShowWheelForCharacter
+            var method = simpleWheelComponent.GetType().GetMethod("ShowWheelForCharacter");
+            if (method != null)
+            {
+                Debug.Log("🔧 Calling ShowWheelForCharacter via reflection...");
+                method.Invoke(simpleWheelComponent, new object[] { character });
+                return;
+            }
+            else
+            {
+                Debug.LogError("❌ ShowWheelForCharacter method not found on SimpleActionWheel!");
+            }
+        }
+        else
+        {
+            Debug.LogError("❌ simpleWheelComponent is null!");
+        }
+
+        // Fallback to battle action system
+        if (battleActionSystem != null)
+        {
+            Debug.Log("🔄 Falling back to BattleActionSystem...");
+            battleActionSystem.ShowActionWheel(character);
+        }
+        else
+        {
+            Debug.LogError("BattleActionIntegration: No action wheel system found!");
+        }
+    }
+
+    private void ConnectSimpleWheelEvents()
+    {
+        if (simpleWheelComponent == null)
+        {
+            Debug.LogError("❌ simpleWheelComponent is null in ConnectSimpleWheelEvents");
+            return;
+        }
+
+        Debug.Log($"🔧 Connecting events for SimpleActionWheel component: {simpleWheelComponent.GetType().Name}");
+
+        // Use reflection to connect to OnActionSelected event
+        var eventInfo = simpleWheelComponent.GetType().GetEvent("OnActionSelected");
+        if (eventInfo != null)
+        {
+            Debug.Log($"✅ Found OnActionSelected event: {eventInfo.EventHandlerType}");
+
+            // Create delegate that matches the event signature: Action<BattleActionType>
+            var delegateType = eventInfo.EventHandlerType;
+            var methodInfo = this.GetType().GetMethod("OnActionSelected", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+
+            if (methodInfo != null)
+            {
+                Debug.Log($"✅ Found OnActionSelected method: {methodInfo.Name}");
+                var handler = System.Delegate.CreateDelegate(delegateType, this, methodInfo);
+                eventInfo.AddEventHandler(simpleWheelComponent, handler);
+                Debug.Log("✅ Successfully connected SimpleActionWheel.OnActionSelected event");
+            }
+            else
+            {
+                Debug.LogError("❌ Could not find OnActionSelected method in BattleActionIntegration");
+            }
+        }
+        else
+        {
+            Debug.LogError("❌ Could not find OnActionSelected event in SimpleActionWheel");
+        }
+    }
+
+    private void OnActionSelected(BattleActionType actionType)
+    {
+        Debug.Log($"🔥 OnActionSelected called with: {actionType}");
+
+        if (lastSelectedCharacter == null)
+        {
+            Debug.LogWarning("❌ Action selected but no character selected!");
+            return;
+        }
+
+        Debug.Log($"🎯 {lastSelectedCharacter.CharacterName} selected action: {actionType}");
+
+        // Set action data for the character
+        var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (actionData == null)
+        {
+            actionData = new EnhancedCharacterActionData();
+            lastSelectedCharacter.SetEnhancedActionData(actionData);
+            Debug.Log($"📝 Created new EnhancedCharacterActionData for {lastSelectedCharacter.CharacterName}");
+        }
+
+        // Configure action based on type and enable targeting mode
+        switch (actionType)
+        {
+            case BattleActionType.Attack:
+                actionData.actionType = actionType;
+                Debug.Log("🗡️ Attack selected - Now drag from character to target enemy!");
+                ShowInstructionMessage("ATTACK: Drag from character to enemy");
+                StartTargetingMode(lastSelectedCharacter, actionType);
+                break;
+
+            case BattleActionType.Move:
+                actionData.actionType = actionType;
+                Debug.Log("👟 Move selected - Now drag from character to target position!");
+                ShowInstructionMessage("MOVE: Drag from character to target position");
+                StartTargetingMode(lastSelectedCharacter, actionType);
+                break;
+
+            case BattleActionType.UseItem:
+                actionData.actionType = actionType;
+                Debug.Log("🧪 Use Item selected - showing item selection UI");
+                ShowInstructionMessage("USE ITEM: Select item from list");
+                ShowItemSelection(lastSelectedCharacter);
+                break;
+
+            case BattleActionType.CastSpell:
+                actionData.actionType = actionType;
+                actionData.state = ActionDecisionState.ActionSelected;
+                lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
+                Debug.Log("✨ Cast Spell selected - implement spell selection UI");
+                break;
+
+            case BattleActionType.Defend:
+                actionData.actionType = actionType;
+                actionData.state = ActionDecisionState.ActionSelected;
+                lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
+                Debug.Log("🛡️ Defend action set - character will defend this turn");
+                break;
+
+            case BattleActionType.RunAway:
+                actionData.actionType = actionType;
+                actionData.state = ActionDecisionState.ActionSelected;
+                lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
+                Debug.Log("💨 Run Away action set - character will attempt to flee");
+                break;
+        }
+
+        Debug.Log($"✅ Action {actionType} configured for {lastSelectedCharacter.CharacterName}");
+    }
+
+    private void StartTargetingMode(Character character, BattleActionType actionType)
+    {
+        Debug.Log($"🎯 Starting targeting mode for {character.CharacterName} with action {actionType}");
+
+        // Enable the PlayerDecisionController to handle targeting
+        if (playerDecisionController != null)
+        {
+            // Use the new public method to start targeting
+            playerDecisionController.StartTargetingForCharacter(character, actionType);
+            Debug.Log($"✅ PlayerDecisionController targeting started for {actionType}");
+        }
+        else
+        {
+            Debug.LogError("❌ PlayerDecisionController not found - cannot start targeting mode");
+        }
+    }
+
+    private void ShowItemSelection(Character character)
+    {
+        Debug.Log($"🧪 Showing item selection for {character.CharacterName}");
+
+        if (itemSelectionUI != null)
+        {
+            // Subscribe to item selection events
+            itemSelectionUI.OnItemSelected -= OnItemSelected;
+            itemSelectionUI.OnSelectionCancelled -= OnItemSelectionCancelled;
+            itemSelectionUI.OnItemSelected += OnItemSelected;
+            itemSelectionUI.OnSelectionCancelled += OnItemSelectionCancelled;
+
+            itemSelectionUI.ShowItemSelection(character);
+        }
+        else
+        {
+            Debug.LogError("❌ BattleItemSelector not found!");
+            // Fallback: Complete action immediately
+            var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (actionData != null)
+            {
+                actionData.state = ActionDecisionState.ActionSelected;
+                character.SetVisualState(ActionDecisionState.ActionSelected);
+            }
+        }
+    }
+
+    private void OnItemSelected(string itemName, int itemIndex)
+    {
+        Debug.Log($"📦 Item selected: {itemName} (index: {itemIndex})");
+
+        if (lastSelectedCharacter != null)
+        {
+            var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (actionData != null)
+            {
+                actionData.selectedItemName = itemName;
+                actionData.selectedItemIndex = itemIndex;
+                actionData.state = ActionDecisionState.ActionSelected;
+                lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
+
+                Debug.Log($"✅ {lastSelectedCharacter.CharacterName} will use {itemName}");
+            }
+        }
+    }
+
+    private void OnItemSelectionCancelled()
+    {
+        Debug.Log("❌ Item selection cancelled");
+
+        if (lastSelectedCharacter != null)
+        {
+            var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (actionData != null)
+            {
+                actionData.Reset();
+                lastSelectedCharacter.SetVisualState(ActionDecisionState.NoAction);
+            }
+        }
+    }
+
+    private void OnCharacterActionCompleted(Character character)
+    {
+        Debug.Log($"✅ Action completed for {character.CharacterName}");
+
+        // Clear selection after action is complete
+        if (character == lastSelectedCharacter)
+        {
+            lastSelectedCharacter = null;
+        }
+    }
+
+    /// <summary>
+    /// Manually trigger action selection for a character (for use by other systems)
+    /// </summary>
+    public void SelectCharacter(Character character)
+    {
+        SelectCharacterForAction(character);
+    }
+
+    /// <summary>
+    /// Execute all selected actions (for turn-based systems)
+    /// </summary>
+    public void ExecuteAllPlayerActions()
+    {
+        Character[] playerCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
+
+        foreach (Character character in playerCharacters)
+        {
+            var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (character.CompareTag("Player") && actionData != null && actionData.hasValidAction)
+            {
+                if (battleActionSystem != null)
+                {
+                    battleActionSystem.ExecuteCharacterAction(character);
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Switch between old and new action systems
+    /// </summary>
+    public void ToggleActionSystem()
+    {
+        useNewActionSystem = !useNewActionSystem;
+
+        // Enable/disable appropriate systems
+        if (playerDecisionController != null)
+        {
+            playerDecisionController.enabled = !useNewActionSystem;
+        }
+
+        Debug.Log($"🎯 Action system switched to: {(useNewActionSystem ? "New Action Wheel" : "Old Click-Drag")}");
+    }
+
+    /// <summary>
+    /// Check if all players have selected actions
+    /// </summary>
+    public bool AllPlayersHaveActions()
+    {
+        Character[] playerCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
+
+        foreach (Character character in playerCharacters)
+        {
+            if (character.CompareTag("Player"))
+            {
+                var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+                if (actionData == null || !actionData.hasValidAction)
+                {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /// <summary>
+    /// Reset all player actions (useful for new turns)
+    /// </summary>
+    public void ResetAllPlayerActions()
+    {
+        Character[] playerCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
+
+        foreach (Character character in playerCharacters)
+        {
+            if (character.CompareTag("Player"))
+            {
+                var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+                if (actionData != null)
+                    actionData.Reset();
+
+                character.SetVisualState(ActionDecisionState.NoAction);
+            }
+        }
+
+        lastSelectedCharacter = null;
+        Debug.Log("🔄 All player actions reset");
+    }
+
+    private void ShowInstructionMessage(string message)
+    {
+        currentInstruction = message;
+        instructionTimer = instructionDuration;
+        Debug.Log($"📢 Instruction: {message}");
+    }
+}

+ 624 - 0
Assets/Scripts/BattleScene/BattleActionSystem.cs

@@ -0,0 +1,624 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.Collections;
+
+/// <summary>
+/// Manages the execution of battle actions and coordinates with existing systems
+/// </summary>
+public class BattleActionSystem : MonoBehaviour
+{
+    [Header("References")]
+    public BattleActionWheel actionWheel;
+
+    [Header("Item System")]
+    public BattleItemSelector itemSelectionUI;
+
+    [Header("Spell System")]
+    public SpellSelectionUI spellSelectionUI;
+
+    [Header("Settings")]
+    public LayerMask enemyLayerMask = 1 << 10;
+    public LayerMask playerLayerMask = 1 << 9;
+    public LayerMask groundLayerMask = 1 << 0;
+
+    private Character currentCharacter;
+    private EnhancedCharacterActionData pendingAction;
+    private bool isWaitingForTarget = false;
+    private Camera mainCamera;
+
+    // Events
+    public event System.Action<Character> OnActionCompleted;
+    public event System.Action<Character, BattleActionType> OnActionStarted;
+
+    void Awake()
+    {
+        mainCamera = Camera.main;
+
+        // Find or create action wheel
+        if (actionWheel == null)
+            actionWheel = FindFirstObjectByType<BattleActionWheel>();
+    }
+
+    void Start()
+    {
+        // Subscribe to action wheel events
+        if (actionWheel != null)
+        {
+            actionWheel.OnActionSelected += OnActionTypeSelected;
+            actionWheel.OnWheelClosed += OnActionWheelClosed;
+        }
+
+        // Subscribe to item/spell selection events
+        if (itemSelectionUI != null)
+        {
+            itemSelectionUI.OnItemSelected += OnItemSelected;
+            itemSelectionUI.OnSelectionCancelled += OnItemSelectionCancelled;
+        }
+
+        if (spellSelectionUI != null)
+        {
+            spellSelectionUI.OnSpellSelected += OnSpellSelected;
+            spellSelectionUI.OnSelectionCancelled += OnSpellSelectionCancelled;
+        }
+    }
+
+    void Update()
+    {
+        if (isWaitingForTarget)
+        {
+            HandleTargetSelection();
+        }
+    }
+
+    /// <summary>
+    /// Shows the action wheel for a character
+    /// </summary>
+    public void ShowActionWheel(Character character)
+    {
+        currentCharacter = character;
+
+        if (actionWheel != null)
+        {
+            Vector3 wheelPosition = character.transform.position + Vector3.up * 2f;
+            actionWheel.ShowWheel(character, wheelPosition);
+        }
+        else
+        {
+            Debug.LogError("BattleActionSystem: No action wheel assigned!");
+        }
+    }
+
+    /// <summary>
+    /// Hides the action wheel
+    /// </summary>
+    public void HideActionWheel()
+    {
+        if (actionWheel != null)
+        {
+            actionWheel.HideWheel();
+        }
+    }
+
+    /// <summary>
+    /// Executes the character's selected action
+    /// </summary>
+    public void ExecuteCharacterAction(Character character)
+    {
+        if (character == null)
+        {
+            Debug.LogWarning("BattleActionSystem: Invalid character");
+            return;
+        }
+
+        var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (actionData == null)
+        {
+            Debug.LogWarning($"BattleActionSystem: Character {character.CharacterName} has no enhanced action data");
+            return;
+        }
+
+        if (!actionData.hasValidAction)
+        {
+            Debug.LogWarning($"BattleActionSystem: Character {character.CharacterName} has no valid action");
+            return;
+        }
+
+        Debug.Log($"🎯 Executing {actionData.actionType} for {character.CharacterName}: {actionData.GetActionDescription()}");
+
+        OnActionStarted?.Invoke(character, actionData.actionType);
+
+        StartCoroutine(ExecuteActionCoroutine(character, actionData));
+    }
+
+    private IEnumerator ExecuteActionCoroutine(Character character, EnhancedCharacterActionData actionData)
+    {
+        switch (actionData.actionType)
+        {
+            case BattleActionType.Move:
+                yield return ExecuteMoveAction(character, actionData);
+                break;
+
+            case BattleActionType.Attack:
+                yield return ExecuteAttackAction(character, actionData);
+                break;
+
+            case BattleActionType.UseItem:
+                yield return ExecuteItemAction(character, actionData);
+                break;
+
+            case BattleActionType.CastSpell:
+                yield return ExecuteSpellAction(character, actionData);
+                break;
+
+            case BattleActionType.Defend:
+                yield return ExecuteDefendAction(character, actionData);
+                break;
+
+            case BattleActionType.Wait:
+                yield return ExecuteWaitAction(character, actionData);
+                break;
+
+            case BattleActionType.RunAway:
+                yield return ExecuteRunAwayAction(character, actionData);
+                break;
+        }
+
+        actionData.state = ActionDecisionState.ActionExecuted;
+        OnActionCompleted?.Invoke(character);
+    }
+
+    #region Action Execution Methods
+
+    private IEnumerator ExecuteMoveAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        Debug.Log($"🚶 {character.CharacterName} moving to {actionData.targetPosition}");
+
+        // Use existing movement system or implement new one
+        character.transform.position = actionData.targetPosition;
+
+        yield return new WaitForSeconds(0.5f); // Animation time
+    }
+
+    private IEnumerator ExecuteAttackAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        if (actionData.targetEnemy == null)
+        {
+            Debug.LogWarning($"Attack action for {character.CharacterName} has no target!");
+            yield break;
+        }
+
+        Debug.Log($"⚔️ {character.CharacterName} attacking {actionData.targetEnemy.name}");
+
+        // Use existing attack system
+        Character targetCharacter = actionData.targetEnemy.GetComponent<Character>();
+        if (targetCharacter != null)
+        {
+            character.AttackTarget(targetCharacter);
+        }
+
+        yield return new WaitForSeconds(1f); // Attack animation time
+    }
+
+    private IEnumerator ExecuteItemAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        Debug.Log($"🧪 {character.CharacterName} using item: {actionData.selectedItemName}");
+
+        // Placeholder item usage logic
+        yield return UseItem(character, actionData.selectedItemName, actionData.selectedItemIndex, actionData.targetCharacter);
+
+        yield return new WaitForSeconds(0.8f);
+    }
+
+    private IEnumerator ExecuteSpellAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        Debug.Log($"✨ {character.CharacterName} casting spell: {actionData.selectedSpellName}");
+
+        // Placeholder spell casting logic
+        yield return CastSpell(character, actionData.selectedSpellName, actionData.targetCharacter, actionData.targetPosition);
+
+        yield return new WaitForSeconds(1.2f);
+    }
+
+    private IEnumerator ExecuteDefendAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        Debug.Log($"🛡️ {character.CharacterName} defending");
+
+        // Apply defend buff (reduce incoming damage, increase AC, etc.)
+        ApplyDefendBuff(character);
+
+        yield return new WaitForSeconds(0.3f);
+    }
+
+    private IEnumerator ExecuteWaitAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        Debug.Log($"⏳ {character.CharacterName} waiting");
+
+        // Character does nothing but maintains position
+        yield return new WaitForSeconds(0.1f);
+    }
+
+    private IEnumerator ExecuteRunAwayAction(Character character, EnhancedCharacterActionData actionData)
+    {
+        Debug.Log($"🏃 {character.CharacterName} running away");
+
+        // Move character away from enemies or off battlefield
+        yield return HandleRunAway(character);
+
+        yield return new WaitForSeconds(1f);
+    }
+
+    #endregion
+
+    #region Event Handlers
+
+    private void OnActionTypeSelected(BattleActionType actionType)
+    {
+        if (currentCharacter == null) return;
+
+        Debug.Log($"🎯 Action type selected: {actionType} for {currentCharacter.CharacterName}");
+
+        // Initialize enhanced action data if needed
+        var actionData = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (actionData == null)
+        {
+            actionData = new EnhancedCharacterActionData();
+            currentCharacter.SetEnhancedActionData(actionData);
+        }
+
+        switch (actionType)
+        {
+            case BattleActionType.Move:
+                StartTargetSelectionForMove();
+                break;
+
+            case BattleActionType.Attack:
+                StartTargetSelectionForAttack();
+                break;
+
+            case BattleActionType.UseItem:
+                ShowItemSelection();
+                break;
+
+            case BattleActionType.CastSpell:
+                ShowSpellSelection();
+                break;
+
+            case BattleActionType.Defend:
+                actionData.SetDefendAction();
+                CompleteActionSelection();
+                break;
+
+            case BattleActionType.Wait:
+                actionData.SetWaitAction();
+                CompleteActionSelection();
+                break;
+
+            case BattleActionType.RunAway:
+                actionData.SetRunAwayAction();
+                CompleteActionSelection();
+                break;
+        }
+    }
+
+    private void OnActionWheelClosed()
+    {
+        if (!isWaitingForTarget)
+        {
+            CancelActionSelection();
+        }
+    }
+
+    private void OnItemSelected(string itemName, int itemIndex)
+    {
+        var actionData = currentCharacter?.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (actionData == null) return;
+
+        // Determine if item requires targeting
+        bool requiresTarget = DoesItemRequireTarget(itemName);
+
+        actionData.SetItemAction(itemName, itemIndex, requiresTarget);
+
+        if (requiresTarget)
+        {
+            StartTargetSelectionForItem();
+        }
+        else
+        {
+            CompleteActionSelection();
+        }
+    }
+
+    private void OnItemSelectionCancelled()
+    {
+        CancelActionSelection();
+    }
+
+    private void OnSpellSelected(string spellName)
+    {
+        var actionData = currentCharacter?.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (actionData == null) return;
+
+        // Determine spell properties
+        var spellInfo = GetSpellInfo(spellName);
+
+        actionData.SetSpellAction(spellName, spellInfo.requiresTarget, spellInfo.isAoE, spellInfo.aoeRadius);
+
+        if (spellInfo.requiresTarget)
+        {
+            StartTargetSelectionForSpell();
+        }
+        else
+        {
+            CompleteActionSelection();
+        }
+    }
+
+    private void OnSpellSelectionCancelled()
+    {
+        CancelActionSelection();
+    }
+
+    #endregion
+
+    #region Target Selection
+
+    private void StartTargetSelectionForMove()
+    {
+        Debug.Log("🎯 Select move target...");
+        pendingAction = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+        isWaitingForTarget = true;
+        // Show move cursor or indicators
+    }
+
+    private void StartTargetSelectionForAttack()
+    {
+        Debug.Log("🎯 Select attack target...");
+        pendingAction = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+        isWaitingForTarget = true;
+        // Show attack cursor or highlight enemies
+    }
+
+    private void StartTargetSelectionForItem()
+    {
+        Debug.Log("🎯 Select item target...");
+        pendingAction = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+        isWaitingForTarget = true;
+    }
+
+    private void StartTargetSelectionForSpell()
+    {
+        Debug.Log("🎯 Select spell target...");
+        pendingAction = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+        isWaitingForTarget = true;
+    }
+
+    private void HandleTargetSelection()
+    {
+        if (Input.GetMouseButtonDown(0))
+        {
+            Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
+            RaycastHit hit;
+
+            // Check for character targets
+            if (Physics.Raycast(ray, out hit, Mathf.Infinity, enemyLayerMask | playerLayerMask))
+            {
+                Character targetCharacter = hit.collider.GetComponent<Character>();
+                if (targetCharacter != null)
+                {
+                    SetCharacterTarget(targetCharacter);
+                    return;
+                }
+            }
+
+            // Check for ground/position targets
+            if (Physics.Raycast(ray, out hit, Mathf.Infinity, groundLayerMask))
+            {
+                SetPositionTarget(hit.point);
+                return;
+            }
+        }
+
+        // Cancel targeting with right click or escape
+        if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape))
+        {
+            CancelTargetSelection();
+        }
+    }
+
+    private void SetCharacterTarget(Character target)
+    {
+        if (pendingAction == null) return;
+
+        if (pendingAction.actionType == BattleActionType.Attack && target.CompareTag("Enemy"))
+        {
+            pendingAction.SetTarget(target.gameObject);
+            CompleteActionSelection();
+        }
+        else if (pendingAction.actionType == BattleActionType.UseItem || pendingAction.actionType == BattleActionType.CastSpell)
+        {
+            pendingAction.SetTarget(target);
+            CompleteActionSelection();
+        }
+    }
+
+    private void SetPositionTarget(Vector3 position)
+    {
+        if (pendingAction == null) return;
+
+        if (pendingAction.actionType == BattleActionType.Move)
+        {
+            pendingAction.SetMoveAction(position);
+            CompleteActionSelection();
+        }
+        else if (pendingAction.actionType == BattleActionType.CastSpell && pendingAction.isAreaOfEffect)
+        {
+            pendingAction.SetTarget(position);
+            CompleteActionSelection();
+        }
+    }
+
+    private void CancelTargetSelection()
+    {
+        isWaitingForTarget = false;
+        pendingAction = null;
+        CancelActionSelection();
+    }
+
+    #endregion
+
+    #region Helper Methods
+
+    private void CompleteActionSelection()
+    {
+        isWaitingForTarget = false;
+        pendingAction = null;
+
+        if (currentCharacter != null)
+        {
+            currentCharacter.SetVisualState(ActionDecisionState.ActionSelected);
+            var actionData = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (actionData != null)
+            {
+                Debug.Log($"✅ Action selection complete for {currentCharacter.CharacterName}: {actionData.GetActionDescription()}");
+            }
+        }
+    }
+
+    private void CancelActionSelection()
+    {
+        isWaitingForTarget = false;
+        pendingAction = null;
+
+        if (currentCharacter != null)
+        {
+            var actionData = currentCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
+            if (actionData != null)
+                actionData.Reset();
+
+            currentCharacter.SetVisualState(ActionDecisionState.NoAction);
+            Debug.Log($"❌ Action selection cancelled for {currentCharacter.CharacterName}");
+        }
+
+        currentCharacter = null;
+    }
+
+    private void ShowItemSelection()
+    {
+        if (itemSelectionUI != null)
+        {
+            itemSelectionUI.ShowItemSelection(currentCharacter);
+        }
+        else
+        {
+            Debug.LogWarning("No ItemSelectionUI found - creating placeholder item action");
+            // Placeholder: auto-select a health potion
+            OnItemSelected("Health Potion", 0);
+        }
+    }
+
+    private void ShowSpellSelection()
+    {
+        if (spellSelectionUI != null)
+        {
+            spellSelectionUI.ShowSpellSelection(currentCharacter);
+        }
+        else
+        {
+            Debug.LogWarning("No SpellSelectionUI found - creating placeholder spell action");
+            // Placeholder: auto-select a basic spell
+            OnSpellSelected("Magic Missile");
+        }
+    }
+
+    private bool DoesItemRequireTarget(string itemName)
+    {
+        // Placeholder logic - determine if item needs a target
+        return itemName.ToLower().Contains("heal") || itemName.ToLower().Contains("buff") || itemName.ToLower().Contains("restore");
+    }
+
+    private (bool requiresTarget, bool isAoE, float aoeRadius) GetSpellInfo(string spellName)
+    {
+        // Placeholder spell database
+        switch (spellName.ToLower())
+        {
+            case "magic missile":
+                return (true, false, 0f);
+            case "heal":
+                return (true, false, 0f);
+            case "fireball":
+                return (true, true, 3f);
+            case "shield":
+                return (false, false, 0f);
+            default:
+                return (true, false, 0f);
+        }
+    }
+
+    private IEnumerator UseItem(Character user, string itemName, int itemIndex, Character target)
+    {
+        Debug.Log($"📦 Using item {itemName} on {(target ? target.CharacterName : "self")}");
+
+        // Placeholder item effects
+        if (itemName.ToLower().Contains("heal"))
+        {
+            Character healTarget = target ?? user;
+            healTarget.Heal(20); // Heal for 20 HP
+            Debug.Log($"💚 {healTarget.CharacterName} healed for 20 HP");
+        }
+
+        yield return null;
+    }
+
+    private IEnumerator CastSpell(Character caster, string spellName, Character target, Vector3 targetPosition)
+    {
+        Debug.Log($"🔮 Casting {spellName} from {caster.CharacterName}");
+
+        // Placeholder spell effects
+        switch (spellName.ToLower())
+        {
+            case "magic missile":
+                if (target != null)
+                {
+                    target.TakeDamage(15);
+                    Debug.Log($"💥 {target.CharacterName} hit by Magic Missile for 15 damage");
+                }
+                break;
+
+            case "heal":
+                if (target != null)
+                {
+                    target.Heal(25);
+                    Debug.Log($"💚 {target.CharacterName} healed for 25 HP");
+                }
+                break;
+
+            case "fireball":
+                // AoE damage around target position
+                Debug.Log($"🔥 Fireball explodes at {targetPosition}");
+                break;
+        }
+
+        yield return null;
+    }
+
+    private void ApplyDefendBuff(Character character)
+    {
+        // Placeholder: apply defensive buff
+        Debug.Log($"🛡️ {character.CharacterName} gains defensive stance");
+        // TODO: Implement actual defensive bonuses
+    }
+
+    private IEnumerator HandleRunAway(Character character)
+    {
+        // Placeholder: move character away from combat
+        Vector3 runDirection = -character.transform.forward;
+        Vector3 runTarget = character.transform.position + runDirection * 5f;
+
+        character.transform.position = runTarget;
+
+        Debug.Log($"🏃 {character.CharacterName} retreats to {runTarget}");
+        yield return null;
+    }
+
+    #endregion
+}

+ 418 - 0
Assets/Scripts/BattleScene/BattleActionWheel.cs

@@ -0,0 +1,418 @@
+using UnityEngine;
+using UnityEngine.UI;
+using System.Collections.Generic;
+using System;
+using TMPro;
+
+/// <summary>
+/// Radial menu (decision wheel) for selecting battle actions
+/// </summary>
+public class BattleActionWheel : MonoBehaviour
+{
+    [Header("UI References")]
+    public Canvas wheelCanvas;
+    public GameObject wheelBackground;
+    public GameObject actionButtonPrefab;
+    public Transform wheelCenter;
+
+    [Header("Wheel Settings")]
+    public float wheelRadius = 100f;
+    public float buttonSize = 60f;
+    public float animationDuration = 0.3f;
+    public AnimationCurve scaleCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
+
+    [Header("Action Icons")]
+    public Sprite moveIcon;
+    public Sprite attackIcon;
+    public Sprite itemIcon;
+    public Sprite spellIcon;
+    public Sprite runAwayIcon;
+    public Sprite defendIcon;
+    public Sprite waitIcon;
+
+    [Header("Colors")]
+    public Color defaultColor = Color.white;
+    public Color hoverColor = Color.yellow;
+    public Color disabledColor = Color.gray;
+
+    private List<ActionButton> actionButtons = new List<ActionButton>();
+    private Character currentCharacter;
+    private bool isVisible = false;
+    private Vector3 worldPosition;
+    private Camera mainCamera;
+
+    // Events
+    public event Action<BattleActionType> OnActionSelected;
+    public event Action OnWheelClosed;
+
+    [System.Serializable]
+    private class ActionButton
+    {
+        public GameObject buttonObject;
+        public Button button;
+        public Image icon;
+        public TextMeshProUGUI label;
+        public BattleActionType actionType;
+        public bool isEnabled = true;
+
+        public void SetEnabled(bool enabled)
+        {
+            isEnabled = enabled;
+            button.interactable = enabled;
+            icon.color = enabled ? Color.white : Color.gray;
+        }
+
+        public void SetHighlight(bool highlighted, Color normalColor, Color highlightColor)
+        {
+            icon.color = highlighted ? highlightColor : (isEnabled ? normalColor : Color.gray);
+        }
+    }
+
+    void Awake()
+    {
+        mainCamera = Camera.main;
+        if (wheelCanvas == null)
+            wheelCanvas = GetComponentInChildren<Canvas>();
+
+        if (wheelCanvas != null)
+            wheelCanvas.worldCamera = mainCamera;
+
+        SetVisible(false);
+    }
+
+    void Start()
+    {
+        InitializeWheel();
+    }
+
+    void Update()
+    {
+        if (isVisible)
+        {
+            // Update wheel position to follow character or world position
+            UpdateWheelPosition();
+
+            // Handle input for closing wheel
+            if (Input.GetKeyDown(KeyCode.Escape) || Input.GetMouseButtonDown(1))
+            {
+                HideWheel();
+            }
+        }
+    }
+
+    private void InitializeWheel()
+    {
+        if (actionButtonPrefab == null)
+        {
+            Debug.LogError("BattleActionWheel: Action button prefab not assigned!");
+            return;
+        }
+
+        CreateActionButtons();
+    }
+
+    private void CreateActionButtons()
+    {
+        // Define actions and their properties
+        var actionDefinitions = new[]
+        {
+            new { type = BattleActionType.Attack, icon = attackIcon, label = "Attack" },
+            new { type = BattleActionType.Move, icon = moveIcon, label = "Move" },
+            new { type = BattleActionType.UseItem, icon = itemIcon, label = "Use Item" },
+            new { type = BattleActionType.CastSpell, icon = spellIcon, label = "Cast Spell" },
+            new { type = BattleActionType.Defend, icon = defendIcon, label = "Defend" },
+            new { type = BattleActionType.RunAway, icon = runAwayIcon, label = "Run Away" }
+        };
+
+        int actionCount = actionDefinitions.Length;
+        float angleStep = 360f / actionCount;
+
+        for (int i = 0; i < actionCount; i++)
+        {
+            var actionDef = actionDefinitions[i];
+            float angle = i * angleStep - 90f; // Start from top
+            Vector3 position = GetPositionOnCircle(angle, wheelRadius);
+
+            CreateActionButton(actionDef.type, actionDef.icon, actionDef.label, position, i);
+        }
+    }
+
+    private void CreateActionButton(BattleActionType actionType, Sprite icon, string label, Vector3 position, int index)
+    {
+        GameObject buttonObj = Instantiate(actionButtonPrefab, wheelCenter);
+        buttonObj.name = $"ActionButton_{actionType}";
+
+        // Position the button
+        RectTransform rectTransform = buttonObj.GetComponent<RectTransform>();
+        if (rectTransform != null)
+        {
+            rectTransform.anchoredPosition = position;
+            rectTransform.sizeDelta = Vector2.one * buttonSize;
+        }
+
+        // Get components
+        Button button = buttonObj.GetComponent<Button>();
+        Image iconImage = buttonObj.transform.Find("Icon")?.GetComponent<Image>();
+        TextMeshProUGUI labelText = buttonObj.transform.Find("Label")?.GetComponent<TextMeshProUGUI>();
+
+        // If components don't exist, create them
+        if (iconImage == null)
+        {
+            GameObject iconObj = new GameObject("Icon");
+            iconObj.transform.SetParent(buttonObj.transform, false);
+            iconImage = iconObj.AddComponent<Image>();
+            RectTransform iconRect = iconImage.GetComponent<RectTransform>();
+            iconRect.anchorMin = Vector2.zero;
+            iconRect.anchorMax = Vector2.one;
+            iconRect.offsetMin = Vector2.zero;
+            iconRect.offsetMax = Vector2.zero;
+        }
+
+        if (labelText == null)
+        {
+            GameObject labelObj = new GameObject("Label");
+            labelObj.transform.SetParent(buttonObj.transform, false);
+            labelText = labelObj.AddComponent<TextMeshProUGUI>();
+            RectTransform labelRect = labelText.GetComponent<RectTransform>();
+            labelRect.anchorMin = new Vector2(0f, -0.5f);
+            labelRect.anchorMax = new Vector2(1f, -0.1f);
+            labelRect.offsetMin = Vector2.zero;
+            labelRect.offsetMax = Vector2.zero;
+            labelText.text = label;
+            labelText.fontSize = 12;
+            labelText.alignment = TextAlignmentOptions.Center;
+        }
+
+        // Setup button
+        if (icon != null && iconImage != null)
+            iconImage.sprite = icon;
+
+        if (labelText != null)
+            labelText.text = label;
+
+        // Create action button data
+        ActionButton actionButton = new ActionButton
+        {
+            buttonObject = buttonObj,
+            button = button,
+            icon = iconImage,
+            label = labelText,
+            actionType = actionType
+        };
+
+        // Setup button events
+        if (button != null)
+        {
+            button.onClick.AddListener(() => OnActionButtonClicked(actionType));
+
+            // Add hover effects
+            var eventTrigger = buttonObj.GetComponent<UnityEngine.EventSystems.EventTrigger>();
+            if (eventTrigger == null)
+                eventTrigger = buttonObj.AddComponent<UnityEngine.EventSystems.EventTrigger>();
+
+            // Hover enter
+            var pointerEnter = new UnityEngine.EventSystems.EventTrigger.Entry();
+            pointerEnter.eventID = UnityEngine.EventSystems.EventTriggerType.PointerEnter;
+            pointerEnter.callback.AddListener((data) => { actionButton.SetHighlight(true, defaultColor, hoverColor); });
+            eventTrigger.triggers.Add(pointerEnter);
+
+            // Hover exit
+            var pointerExit = new UnityEngine.EventSystems.EventTrigger.Entry();
+            pointerExit.eventID = UnityEngine.EventSystems.EventTriggerType.PointerExit;
+            pointerExit.callback.AddListener((data) => { actionButton.SetHighlight(false, defaultColor, hoverColor); });
+            eventTrigger.triggers.Add(pointerExit);
+        }
+
+        actionButtons.Add(actionButton);
+        buttonObj.SetActive(false); // Start hidden
+    }
+
+    public void ShowWheel(Character character, Vector3 worldPos)
+    {
+        currentCharacter = character;
+        worldPosition = worldPos;
+
+        UpdateActionAvailability();
+        SetVisible(true);
+        AnimateWheelIn();
+
+        Debug.Log($"🎯 Action wheel shown for {character.CharacterName} at {worldPos}");
+    }
+
+    public void HideWheel()
+    {
+        AnimateWheelOut(() =>
+        {
+            SetVisible(false);
+            OnWheelClosed?.Invoke();
+        });
+
+        Debug.Log("🎯 Action wheel hidden");
+    }
+
+    private void UpdateActionAvailability()
+    {
+        if (currentCharacter == null) return;
+
+        foreach (var actionButton in actionButtons)
+        {
+            bool isAvailable = IsActionAvailable(actionButton.actionType);
+            actionButton.SetEnabled(isAvailable);
+        }
+    }
+
+    private bool IsActionAvailable(BattleActionType actionType)
+    {
+        if (currentCharacter == null) return false;
+
+        switch (actionType)
+        {
+            case BattleActionType.Attack:
+                return currentCharacter.Weapon != null;
+
+            case BattleActionType.Move:
+                return true; // Always available
+
+            case BattleActionType.UseItem:
+                // Check if character has any items (placeholder - implement item system)
+                return HasUsableItems();
+
+            case BattleActionType.CastSpell:
+                // Check if character can cast spells (placeholder - implement spell system)
+                return HasSpells();
+
+            case BattleActionType.Defend:
+            case BattleActionType.RunAway:
+                return true; // Usually always available
+
+            default:
+                return true;
+        }
+    }
+
+    private bool HasUsableItems()
+    {
+        // Placeholder implementation
+        // TODO: Check character's inventory for usable items
+        return true; // For now, assume characters always have items
+    }
+
+    private bool HasSpells()
+    {
+        // Placeholder implementation
+        // TODO: Check character's spell list or mana
+        return true; // For now, assume characters can cast spells
+    }
+
+    private void OnActionButtonClicked(BattleActionType actionType)
+    {
+        Debug.Log($"🎯 Action selected: {actionType}");
+        OnActionSelected?.Invoke(actionType);
+        HideWheel();
+    }
+
+    private Vector3 GetPositionOnCircle(float angleDegrees, float radius)
+    {
+        float angleRadians = angleDegrees * Mathf.Deg2Rad;
+        return new Vector3(
+            Mathf.Cos(angleRadians) * radius,
+            Mathf.Sin(angleRadians) * radius,
+            0f
+        );
+    }
+
+    private void UpdateWheelPosition()
+    {
+        if (wheelCanvas == null || mainCamera == null) return;
+
+        // Convert world position to screen position, then to canvas position
+        Vector3 screenPos = mainCamera.WorldToScreenPoint(worldPosition);
+
+        if (wheelCanvas.renderMode == RenderMode.ScreenSpaceOverlay)
+        {
+            wheelCenter.position = screenPos;
+        }
+        else if (wheelCanvas.renderMode == RenderMode.ScreenSpaceCamera)
+        {
+            Vector2 canvasPos;
+            RectTransformUtility.ScreenPointToLocalPointInRectangle(
+                wheelCanvas.transform as RectTransform,
+                screenPos,
+                wheelCanvas.worldCamera,
+                out canvasPos
+            );
+            wheelCenter.localPosition = canvasPos;
+        }
+    }
+
+    private void SetVisible(bool visible)
+    {
+        isVisible = visible;
+        if (wheelCanvas != null)
+            wheelCanvas.gameObject.SetActive(visible);
+    }
+
+    private void AnimateWheelIn()
+    {
+        // Simple scale animation using Unity's built-in animation
+        if (wheelCenter != null)
+        {
+            wheelCenter.localScale = Vector3.zero;
+            StartCoroutine(AnimateScale(wheelCenter, Vector3.zero, Vector3.one, animationDuration, () =>
+            {
+                // Show all buttons after animation
+                foreach (var button in actionButtons)
+                {
+                    button.buttonObject.SetActive(true);
+                }
+            }));
+        }
+    }
+
+    private void AnimateWheelOut(Action onComplete = null)
+    {
+        // Hide buttons first
+        foreach (var button in actionButtons)
+        {
+            button.buttonObject.SetActive(false);
+        }
+
+        if (wheelCenter != null)
+        {
+            StartCoroutine(AnimateScale(wheelCenter, Vector3.one, Vector3.zero, animationDuration * 0.5f, onComplete));
+        }
+        else
+        {
+            onComplete?.Invoke();
+        }
+    }
+
+    private System.Collections.IEnumerator AnimateScale(Transform target, Vector3 from, Vector3 to, float duration, Action onComplete = null)
+    {
+        float elapsed = 0f;
+
+        while (elapsed < duration)
+        {
+            elapsed += Time.deltaTime;
+            float t = elapsed / duration;
+
+            // Apply easing curve if available
+            if (scaleCurve != null && scaleCurve.keys.Length > 0)
+            {
+                t = scaleCurve.Evaluate(t);
+            }
+
+            target.localScale = Vector3.Lerp(from, to, t);
+            yield return null;
+        }
+
+        target.localScale = to;
+        onComplete?.Invoke();
+    }
+
+    void OnDestroy()
+    {
+        // Clean up any running coroutines
+        StopAllCoroutines();
+    }
+}

+ 361 - 0
Assets/Scripts/BattleScene/BattleItemSelector.cs

@@ -0,0 +1,361 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+using System.Collections.Generic;
+using System;
+
+/// <summary>
+/// UI Toolkit-based item selection UI for battle
+/// </summary>
+public class BattleItemSelector : MonoBehaviour
+{
+    [Header("UI References")]
+    public UIDocument uiDocument;
+
+    [Header("Settings")]
+    public int maxItemsToShow = 10;
+
+    private Character currentCharacter;
+    private VisualElement rootElement;
+    private VisualElement container;
+    private VisualElement itemList;
+    private Label titleLabel;
+    private Label characterLabel;
+    private VisualElement noItemsContainer;
+    private Button cancelButton;
+    private Button closeButton;
+
+    // Events
+    public event Action<string, int> OnItemSelected;
+    public event Action OnSelectionCancelled;
+
+    void Awake()
+    {
+        if (uiDocument == null)
+            uiDocument = GetComponent<UIDocument>();
+
+        if (uiDocument == null)
+        {
+            // Create UIDocument if it doesn't exist
+            uiDocument = gameObject.AddComponent<UIDocument>();
+        }
+    }
+
+    void Start()
+    {
+        InitializeUI();
+        SetVisible(false);
+    }
+
+    void Update()
+    {
+        if (container != null && container.style.display == DisplayStyle.Flex)
+        {
+            if (Input.GetKeyDown(KeyCode.Escape))
+            {
+                OnSelectionCancelled?.Invoke();
+                HideSelection();
+            }
+        }
+    }
+
+    private void InitializeUI()
+    {
+        // Load UXML and USS
+        var visualTreeAsset = Resources.Load<VisualTreeAsset>("UI/ItemSelectionUI");
+        var styleSheet = Resources.Load<StyleSheet>("UI/ItemSelectionUI");
+
+        Debug.Log($"🔍 Loading UXML: {(visualTreeAsset != null ? "✅ Found" : "❌ Not Found")}");
+        Debug.Log($"🔍 Loading USS: {(styleSheet != null ? "✅ Found" : "❌ Not Found")}");
+
+        // Try simple version if main version fails
+        if (visualTreeAsset == null)
+        {
+            Debug.LogWarning("Main UXML failed, trying simple version...");
+            visualTreeAsset = Resources.Load<VisualTreeAsset>("UI/ItemSelectionUI_Simple");
+            Debug.Log($"🔍 Loading Simple UXML: {(visualTreeAsset != null ? "✅ Found" : "❌ Not Found")}");
+        }
+
+        if (visualTreeAsset == null)
+        {
+            Debug.LogError("Could not load any ItemSelectionUI.uxml from Resources/UI/");
+            CreateFallbackUI();
+            return;
+        }
+
+        rootElement = uiDocument.rootVisualElement;
+        rootElement.Clear();
+
+        // Clone the visual tree
+        var clonedTree = visualTreeAsset.CloneTree();
+        rootElement.Add(clonedTree);
+
+        // Apply styles
+        if (styleSheet != null)
+        {
+            rootElement.styleSheets.Add(styleSheet);
+        }
+
+        // Get UI elements
+        container = rootElement.Q<VisualElement>("ItemSelectionContainer");
+        itemList = rootElement.Q<VisualElement>("ItemList");
+        titleLabel = rootElement.Q<Label>("TitleLabel");
+        characterLabel = rootElement.Q<Label>("CharacterLabel");
+        noItemsContainer = rootElement.Q<VisualElement>("NoItemsContainer");
+        cancelButton = rootElement.Q<Button>("CancelButton");
+        closeButton = rootElement.Q<Button>("CloseButton");
+
+        // Debug element finding
+        Debug.Log($"🔍 Elements found:");
+        Debug.Log($"  - container: {(container != null ? "✅" : "❌")}");
+        Debug.Log($"  - itemList: {(itemList != null ? "✅" : "❌")}");
+        Debug.Log($"  - titleLabel: {(titleLabel != null ? "✅" : "❌")}");
+        Debug.Log($"  - characterLabel: {(characterLabel != null ? "✅" : "❌")}");
+        Debug.Log($"  - noItemsContainer: {(noItemsContainer != null ? "✅" : "❌")}");
+        Debug.Log($"  - cancelButton: {(cancelButton != null ? "✅" : "❌")}");
+        Debug.Log($"  - closeButton: {(closeButton != null ? "✅" : "❌")}");
+
+        // Setup event handlers
+        if (cancelButton != null)
+        {
+            cancelButton.clicked += () =>
+            {
+                OnSelectionCancelled?.Invoke();
+                HideSelection();
+            };
+        }
+
+        if (closeButton != null)
+        {
+            closeButton.clicked += () =>
+            {
+                OnSelectionCancelled?.Invoke();
+                HideSelection();
+            };
+        }
+
+        Debug.Log("✅ BattleItemSelector initialized with UI Toolkit");
+    }
+
+    private void CreateFallbackUI()
+    {
+        Debug.LogWarning("Creating fallback BattleItemSelector UI");
+
+        rootElement = uiDocument.rootVisualElement;
+        rootElement.Clear();
+
+        // Create basic container
+        container = new VisualElement();
+        container.name = "ItemSelectionContainer";
+        container.style.position = Position.Absolute;
+        container.style.top = 0;
+        container.style.left = 0;
+        container.style.right = 0;
+        container.style.bottom = 0;
+        container.style.backgroundColor = new Color(0, 0, 0, 0.7f);
+        container.style.alignItems = Align.Center;
+        container.style.justifyContent = Justify.Center;
+
+        // Create modal
+        var modal = new VisualElement();
+        modal.style.backgroundColor = new Color(0.18f, 0.18f, 0.18f, 1f);
+        modal.style.borderTopWidth = modal.style.borderBottomWidth = modal.style.borderLeftWidth = modal.style.borderRightWidth = 2;
+        modal.style.borderTopColor = modal.style.borderBottomColor = modal.style.borderLeftColor = modal.style.borderRightColor = Color.gray;
+        modal.style.borderTopLeftRadius = modal.style.borderTopRightRadius = modal.style.borderBottomLeftRadius = modal.style.borderBottomRightRadius = 8;
+        modal.style.width = 400;
+        modal.style.height = 500;
+        modal.style.paddingTop = modal.style.paddingBottom = modal.style.paddingLeft = modal.style.paddingRight = 15;
+
+        // Title
+        titleLabel = new Label("Select Item");
+        titleLabel.style.fontSize = 18;
+        titleLabel.style.color = Color.white;
+        titleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
+        titleLabel.style.marginBottom = 10;
+        titleLabel.style.unityTextAlign = TextAnchor.MiddleCenter;
+
+        // Character label
+        characterLabel = new Label();
+        characterLabel.style.fontSize = 16;
+        characterLabel.style.color = new Color(1f, 0.86f, 0.39f);
+        characterLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
+        characterLabel.style.marginBottom = 15;
+        characterLabel.style.unityTextAlign = TextAnchor.MiddleCenter;
+
+        // Item list
+        var scrollView = new ScrollView();
+        scrollView.style.flexGrow = 1;
+        scrollView.style.marginBottom = 15;
+
+        itemList = new VisualElement();
+        scrollView.Add(itemList);
+        Debug.Log("🔧 Fallback UI: itemList created successfully");
+
+        // No items message
+        noItemsContainer = new VisualElement();
+        noItemsContainer.style.alignItems = Align.Center;
+        noItemsContainer.style.justifyContent = Justify.Center;
+        noItemsContainer.style.flexGrow = 1;
+        noItemsContainer.style.display = DisplayStyle.None;
+
+        var noItemsLabel = new Label("No usable items available");
+        noItemsLabel.style.color = new Color(0.6f, 0.6f, 0.6f);
+        noItemsContainer.Add(noItemsLabel);
+
+        // Cancel button
+        cancelButton = new Button(() =>
+        {
+            OnSelectionCancelled?.Invoke();
+            HideSelection();
+        });
+        cancelButton.text = "Cancel";
+        cancelButton.style.paddingTop = cancelButton.style.paddingBottom = 8;
+        cancelButton.style.paddingLeft = cancelButton.style.paddingRight = 16;
+
+        // Assemble UI
+        modal.Add(titleLabel);
+        modal.Add(characterLabel);
+        modal.Add(scrollView);
+        modal.Add(noItemsContainer);
+        modal.Add(cancelButton);
+
+        container.Add(modal);
+        rootElement.Add(container);
+    }
+
+    public void ShowItemSelection(Character character)
+    {
+        Debug.Log($"📦 ShowItemSelection called for {character.CharacterName}");
+        Debug.Log($"📦 UI State - itemList: {(itemList != null ? "✅" : "❌")}, container: {(container != null ? "✅" : "❌")}");
+
+        if (itemList == null)
+        {
+            Debug.LogError("❌ itemList is null - reinitializing UI");
+            InitializeUI();
+        }
+
+        currentCharacter = character;
+
+        if (characterLabel != null)
+            characterLabel.text = $"{character.CharacterName}";
+
+        if (titleLabel != null)
+            titleLabel.text = "Select Item";
+
+        PopulateItemList();
+        SetVisible(true);
+
+        Debug.Log($"📦 Item selection shown for {character.CharacterName}");
+    }
+
+    public void HideSelection()
+    {
+        SetVisible(false);
+        ClearItemList();
+        currentCharacter = null;
+
+        Debug.Log("📦 Item selection hidden");
+    }
+
+    private void SetVisible(bool visible)
+    {
+        if (container != null)
+        {
+            container.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
+        }
+    }
+
+    private void PopulateItemList()
+    {
+        Debug.Log($"📦 PopulateItemList called - itemList null: {itemList == null}");
+
+        ClearItemList();
+
+        var items = GetCharacterItems();
+        Debug.Log($"📦 Found {items.Count} items to display");
+
+        if (items.Count == 0)
+        {
+            if (noItemsContainer != null)
+                noItemsContainer.style.display = DisplayStyle.Flex;
+            return;
+        }
+
+        if (noItemsContainer != null)
+            noItemsContainer.style.display = DisplayStyle.None;
+
+        for (int i = 0; i < items.Count && i < maxItemsToShow; i++)
+        {
+            CreateItemButton(items[i], i);
+        }
+    }
+
+    private void CreateItemButton(ItemData item, int index)
+    {
+        // Safety check to prevent NullReferenceException
+        if (itemList == null)
+        {
+            Debug.LogError("❌ itemList is null! UI initialization may have failed.");
+            return;
+        }
+
+        var button = new Button();
+        button.AddToClassList("item-button");
+
+        // Item name
+        var nameLabel = new Label(item.name);
+        nameLabel.AddToClassList("item-name");
+
+        // Item description
+        var descLabel = new Label(item.description);
+        descLabel.AddToClassList("item-description");
+
+        button.Add(nameLabel);
+        button.Add(descLabel);
+
+        button.clicked += () =>
+        {
+            OnItemSelected?.Invoke(item.name, index);
+            HideSelection();
+        };
+
+        itemList.Add(button);
+    }
+
+    private void ClearItemList()
+    {
+        if (itemList != null)
+        {
+            itemList.Clear();
+        }
+    }
+
+    private List<ItemData> GetCharacterItems()
+    {
+        // Placeholder implementation - return sample items
+        // TODO: Get actual items from character's inventory
+
+        return new List<ItemData>
+        {
+            new ItemData { name = "Health Potion", description = "Restores 50 HP" },
+            new ItemData { name = "Mana Potion", description = "Restores 30 MP" },
+            new ItemData { name = "Antidote", description = "Cures poison" },
+            new ItemData { name = "Strength Elixir", description = "+3 Str for 5 rounds" },
+            new ItemData { name = "Magic Scroll", description = "Casts Magic Missile" }
+        };
+    }
+
+    [System.Serializable]
+    public class ItemData
+    {
+        public string name;
+        public string description;
+        public int quantity = 1;
+        public bool isUsable = true;
+    }
+
+    void OnDestroy()
+    {
+        OnItemSelected = null;
+        OnSelectionCancelled = null;
+    }
+}

+ 285 - 0
Assets/Scripts/BattleScene/EnemySelectionUI.cs

@@ -0,0 +1,285 @@
+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;
+    }
+}

+ 83 - 0
Assets/Scripts/BattleScene/PlayerDecisionController .cs

@@ -149,12 +149,16 @@ public class PlayerDecisionController : MonoBehaviour
             // Set attack target
             selectedCharacter.actionData.SetAttackTarget(enemyAtMouse);
 
+            // Also update enhanced action data if it exists
+            UpdateEnhancedActionData(selectedCharacter, BattleActionType.Attack, enemyAtMouse, mouseWorldPos);
         }
         else
         {
             // Set move target
             selectedCharacter.actionData.SetMoveTarget(mouseWorldPos);
 
+            // Also update enhanced action data if it exists
+            UpdateEnhancedActionData(selectedCharacter, BattleActionType.Move, null, mouseWorldPos);
         }
 
         selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
@@ -370,4 +374,83 @@ public class PlayerDecisionController : MonoBehaviour
             }
         }
     }
+
+    private void UpdateEnhancedActionData(Character character, BattleActionType actionType, GameObject targetEnemy, Vector3 targetPosition)
+    {
+        // Check if character has enhanced action data
+        var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (enhancedData != null)
+        {
+            Debug.Log($"🔄 Updating enhanced action data for {character.CharacterName}: {actionType}");
+
+            // Update the enhanced action data to match the targeting result
+            enhancedData.actionType = actionType;
+            enhancedData.state = ActionDecisionState.ActionSelected;
+
+            if (actionType == BattleActionType.Attack && targetEnemy != null)
+            {
+                enhancedData.targetEnemy = targetEnemy;
+                enhancedData.targetPosition = Vector3.zero;
+                Debug.Log($"🗡️ Enhanced data updated for attack on {targetEnemy.name}");
+            }
+            else if (actionType == BattleActionType.Move)
+            {
+                enhancedData.targetPosition = targetPosition;
+                enhancedData.targetEnemy = null;
+                Debug.Log($"👟 Enhanced data updated for move to {targetPosition}");
+            }
+        }
+        else
+        {
+            Debug.Log($"ℹ️ No enhanced action data found for {character.CharacterName}");
+        }
+    }
+
+    /// <summary>
+    /// Manually start targeting mode for a specific character and action type
+    /// Called by the action wheel system
+    /// </summary>
+    public void StartTargetingForCharacter(Character character, BattleActionType actionType)
+    {
+        Debug.Log($"🎯 StartTargetingForCharacter called: {character.CharacterName} -> {actionType}");
+
+        selectedCharacter = character;
+        isDragging = true;
+        dragStartPosition = character.transform.position;
+
+        // Store the action type for later reference
+        var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
+        if (enhancedData == null)
+        {
+            enhancedData = new EnhancedCharacterActionData();
+            character.SetEnhancedActionData(enhancedData);
+        }
+        enhancedData.actionType = actionType;
+
+        // Clear any existing action lines before starting new targeting
+        ClearActionLineForCharacter(character);
+
+        // Start the targeting line
+        targetingLine.StartTargeting(dragStartPosition);
+
+        Debug.Log($"✅ Targeting mode activated for {character.CharacterName}");
+    }
+
+    /// <summary>
+    /// Cancel current targeting operation
+    /// </summary>
+    public void CancelTargeting()
+    {
+        if (isDragging && selectedCharacter != null)
+        {
+            selectedCharacter.actionData.Reset();
+            selectedCharacter.SetVisualState(ActionDecisionState.NoAction);
+
+            targetingLine.StopTargeting();
+            selectedCharacter = null;
+            isDragging = false;
+
+            Debug.Log("❌ Targeting cancelled");
+        }
+    }
 }

+ 245 - 0
Assets/Scripts/BattleScene/SimpleActionWheel.cs

@@ -0,0 +1,245 @@
+using UnityEngine;
+using System;
+
+/// <summary>
+/// Simple IMGUI-based action wheel that doesn't require any Canvas setup
+/// Perfect for testing and prototyping the battle action system
+/// </summary>
+public class SimpleActionWheel : MonoBehaviour
+{
+    [Header("Settings")]
+    public KeyCode toggleKey = KeyCode.Q;
+    public bool showDebugGUI = true;
+
+    private Character currentCharacter;
+    private bool isVisible = false;
+    private Vector2 wheelCenter;
+    private float wheelRadius = 120f; // Increased for better spacing
+    private float buttonSize = 70f; // Larger buttons for better visibility
+
+    // Events
+    public event Action<BattleActionType> OnActionSelected;
+
+    private BattleActionType[] actionTypes =
+    {
+        BattleActionType.Attack,
+        BattleActionType.Move,
+        BattleActionType.UseItem,
+        BattleActionType.CastSpell,
+        BattleActionType.Defend,
+        BattleActionType.RunAway
+    };
+
+    private string[] actionLabels =
+    {
+        "⚔️ Attack",
+        "👟 Move",
+        "🧪 Item",
+        "✨ Spell",
+        "🛡️ Defend",
+        "💨 Run"
+    };
+
+    private Color[] actionColors =
+    {
+        Color.red,
+        Color.green,
+        Color.blue,
+        Color.magenta,
+        Color.yellow,
+        Color.gray
+    };
+
+    void Update()
+    {
+        if (isVisible && Input.GetKeyDown(KeyCode.Escape))
+        {
+            HideWheel();
+        }
+    }
+
+    void OnGUI()
+    {
+        if (!isVisible || currentCharacter == null) return;
+
+        // Set up GUI
+        GUI.depth = -1000; // Ensure it's on top
+
+        // Draw background
+        Vector2 center = new Vector2(Screen.width / 2, Screen.height / 2);
+        wheelCenter = center;
+
+        // Draw wheel background with better visibility
+        DrawCircle(center, wheelRadius + 30, new Color(0, 0, 0, 0.8f)); // Darker background
+        DrawCircle(center, wheelRadius + 25, Color.white);
+        DrawCircle(center, wheelRadius + 20, new Color(0.2f, 0.2f, 0.2f, 0.9f)); // Inner background
+
+        // Draw title with better contrast
+        GUI.color = Color.white;
+        GUIStyle titleStyle = new GUIStyle(GUI.skin.label);
+        titleStyle.fontSize = 24; // Larger font
+        titleStyle.alignment = TextAnchor.MiddleCenter;
+        titleStyle.normal.textColor = Color.white;
+        titleStyle.fontStyle = FontStyle.Bold;
+
+        Rect titleRect = new Rect(center.x - 150, center.y - wheelRadius - 60, 300, 40);
+
+        // Draw background for title text
+        GUI.color = new Color(0, 0, 0, 0.8f);
+        GUI.Box(titleRect, "");
+
+        GUI.color = Color.white;
+        GUI.Label(titleRect, $"{currentCharacter.CharacterName} - Choose Action", titleStyle);
+
+        // Draw action buttons with better spacing
+        int actionCount = actionTypes.Length;
+        float angleStep = 360f / actionCount;
+
+        for (int i = 0; i < actionCount; i++)
+        {
+            float angle = i * angleStep - 90f; // Start from top
+            Vector2 buttonPos = GetPositionOnCircle(center, angle, wheelRadius * 0.75f); // Moved closer to center
+
+            DrawActionButton(buttonPos, actionTypes[i], actionLabels[i], actionColors[i]);
+        }
+
+        // Draw improved instructions
+        GUIStyle instructionStyle = new GUIStyle(GUI.skin.label);
+        instructionStyle.fontSize = 16;
+        instructionStyle.alignment = TextAnchor.MiddleCenter;
+        instructionStyle.normal.textColor = Color.white;
+        instructionStyle.fontStyle = FontStyle.Bold;
+
+        Rect instructionRect = new Rect(center.x - 200, center.y + wheelRadius + 40, 400, 25);
+
+        // Background for instructions
+        GUI.color = new Color(0, 0, 0, 0.8f);
+        GUI.Box(instructionRect, "");
+
+        GUI.color = Color.white;
+        GUI.Label(instructionRect, "Click action or press ESC to cancel", instructionStyle);
+
+        GUI.color = Color.white;
+    }
+
+    private void DrawActionButton(Vector2 position, BattleActionType actionType, string label, Color color)
+    {
+        Rect buttonRect = new Rect(position.x - buttonSize / 2, position.y - buttonSize / 2, buttonSize, buttonSize);
+
+        // Check if mouse is over button
+        bool isHovered = buttonRect.Contains(Event.current.mousePosition);
+
+        // Draw button with improved visuals
+        Color buttonColor = isHovered ? Color.Lerp(color, Color.white, 0.4f) : color;
+
+        // Draw button shadow
+        GUI.color = new Color(0, 0, 0, 0.5f);
+        Rect shadowRect = new Rect(buttonRect.x + 3, buttonRect.y + 3, buttonRect.width, buttonRect.height);
+        GUI.Box(shadowRect, "");
+
+        // Draw button background
+        GUI.color = buttonColor;
+        GUI.Box(buttonRect, "");
+
+        // Draw button border (simple outline)
+        GUI.color = isHovered ? Color.white : new Color(0.8f, 0.8f, 0.8f);
+        GUI.Box(new Rect(buttonRect.x - 1, buttonRect.y - 1, buttonRect.width + 2, buttonRect.height + 2), "");
+
+        // Draw button text
+        GUIStyle buttonStyle = new GUIStyle(GUI.skin.label);
+        buttonStyle.fontSize = 14;
+        buttonStyle.alignment = TextAnchor.MiddleCenter;
+        buttonStyle.normal.textColor = isHovered ? Color.black : Color.white;
+        buttonStyle.fontStyle = FontStyle.Bold;
+        buttonStyle.wordWrap = true;
+
+        GUI.color = Color.white;
+        GUI.Label(buttonRect, label, buttonStyle);
+
+        // Handle button click using GUI.Button for easier event handling
+        GUI.color = Color.clear; // Make button invisible
+        if (GUI.Button(buttonRect, "", GUIStyle.none))
+        {
+            OnActionButtonClicked(actionType);
+        }
+
+        GUI.color = Color.white;
+    }
+
+    private void DrawCircle(Vector2 center, float radius, Color color)
+    {
+        GUI.color = color;
+        float size = radius * 2;
+        Rect circleRect = new Rect(center.x - radius, center.y - radius, size, size);
+
+        // Simple circle approximation using GUI.DrawTexture with a circular texture
+        // For simplicity, we'll just draw a square for now
+        GUI.Box(circleRect, "");
+        GUI.color = Color.white;
+    }
+
+    private Vector2 GetPositionOnCircle(Vector2 center, float angle, float radius)
+    {
+        float radian = angle * Mathf.Deg2Rad;
+        float x = center.x + Mathf.Cos(radian) * radius;
+        float y = center.y + Mathf.Sin(radian) * radius;
+        return new Vector2(x, y);
+    }
+
+    private void OnActionButtonClicked(BattleActionType actionType)
+    {
+        Debug.Log($"🎯 Action button clicked: {actionType}");
+        Debug.Log($"🎯 OnActionSelected event has {(OnActionSelected != null ? OnActionSelected.GetInvocationList().Length : 0)} subscribers");
+
+        OnActionSelected?.Invoke(actionType);
+
+        Debug.Log($"🎯 Event invoked, hiding wheel...");
+        HideWheel();
+    }
+
+    public void ShowWheelForCharacter(Character character)
+    {
+        Debug.Log($"🎮 SimpleActionWheel.ShowWheelForCharacter called with: {(character != null ? character.CharacterName : "NULL")}");
+
+        if (character == null)
+        {
+            Debug.LogWarning("Cannot show action wheel: character is null");
+            return;
+        }
+
+        currentCharacter = character;
+        isVisible = true;
+
+        Debug.Log($"🎮 Simple action wheel shown for {character.CharacterName} - isVisible: {isVisible}");
+    }
+    public void HideWheel()
+    {
+        isVisible = false;
+        currentCharacter = null;
+
+        Debug.Log("🎮 Simple action wheel hidden");
+    }
+
+    private Character FindSelectedCharacter()
+    {
+        // Find the currently selected character
+        var characters = FindObjectsByType<Character>(FindObjectsSortMode.None);
+
+        foreach (var character in characters)
+        {
+            if (character.CompareTag("Player"))
+            {
+                // For now, return the first player character found
+                // In a real implementation, you'd check which one is actually selected
+                return character;
+            }
+        }
+
+        return null;
+    }
+
+    void OnDestroy()
+    {
+        OnActionSelected = null;
+    }
+}

+ 307 - 0
Assets/Scripts/BattleScene/SpellSelectionUI.cs

@@ -0,0 +1,307 @@
+using UnityEngine;
+using UnityEngine.UI;
+using System.Collections.Generic;
+using TMPro;
+using System;
+
+/// <summary>
+/// UI for selecting spells to cast in battle
+/// </summary>
+public class SpellSelectionUI : MonoBehaviour
+{
+    [Header("UI References")]
+    public Canvas selectionCanvas;
+    public Transform spellListContainer;
+    public GameObject spellButtonPrefab;
+    public Button cancelButton;
+    public TextMeshProUGUI titleText;
+
+    [Header("Settings")]
+    public int maxSpellsToShow = 6;
+
+    private Character currentCharacter;
+    private List<GameObject> spellButtons = new List<GameObject>();
+
+    // Events
+    public event Action<string> OnSpellSelected;
+    public event Action OnSelectionCancelled;
+
+    void Awake()
+    {
+        if (selectionCanvas == null)
+            selectionCanvas = GetComponentInChildren<Canvas>();
+
+        SetVisible(false);
+    }
+
+    void Start()
+    {
+        if (cancelButton != null)
+        {
+            cancelButton.onClick.AddListener(() =>
+            {
+                OnSelectionCancelled?.Invoke();
+                HideSelection();
+            });
+        }
+    }
+
+    void Update()
+    {
+        if (selectionCanvas.gameObject.activeInHierarchy)
+        {
+            if (Input.GetKeyDown(KeyCode.Escape))
+            {
+                OnSelectionCancelled?.Invoke();
+                HideSelection();
+            }
+        }
+    }
+
+    public void ShowSpellSelection(Character character)
+    {
+        currentCharacter = character;
+
+        if (titleText != null)
+            titleText.text = $"{character.CharacterName} - Select Spell";
+
+        PopulateSpellList();
+        SetVisible(true);
+
+        Debug.Log($"✨ Spell selection shown for {character.CharacterName}");
+    }
+
+    public void HideSelection()
+    {
+        SetVisible(false);
+        ClearSpellList();
+        currentCharacter = null;
+
+        Debug.Log("✨ Spell selection hidden");
+    }
+
+    private void PopulateSpellList()
+    {
+        ClearSpellList();
+
+        var spells = GetCharacterSpells();
+
+        for (int i = 0; i < spells.Count && i < maxSpellsToShow; i++)
+        {
+            CreateSpellButton(spells[i], i);
+        }
+    }
+
+    private List<SpellData> GetCharacterSpells()
+    {
+        // Placeholder implementation - return sample spells
+        // TODO: Get actual spells from character's spell list/class abilities
+
+        return new List<SpellData>
+        {
+            new SpellData {
+                name = "Magic Missile",
+                description = "Deals 15 magic damage to target",
+                manaCost = 5,
+                requiresTarget = true,
+                isAoE = false,
+                icon = null
+            },
+            new SpellData {
+                name = "Heal",
+                description = "Restores 25 HP to target",
+                manaCost = 8,
+                requiresTarget = true,
+                isAoE = false,
+                icon = null
+            },
+            new SpellData {
+                name = "Fireball",
+                description = "Explosive fire damage in area",
+                manaCost = 12,
+                requiresTarget = true,
+                isAoE = true,
+                icon = null
+            },
+            new SpellData {
+                name = "Shield",
+                description = "Increases AC by 2 for 5 turns",
+                manaCost = 6,
+                requiresTarget = false,
+                isAoE = false,
+                icon = null
+            },
+            new SpellData {
+                name = "Lightning Bolt",
+                description = "Chain lightning hits multiple enemies",
+                manaCost = 10,
+                requiresTarget = true,
+                isAoE = true,
+                icon = null
+            },
+            new SpellData {
+                name = "Cure Disease",
+                description = "Removes negative effects",
+                manaCost = 7,
+                requiresTarget = true,
+                isAoE = false,
+                icon = null
+            }
+        };
+    }
+
+    private void CreateSpellButton(SpellData spell, int index)
+    {
+        GameObject buttonObj = Instantiate(spellButtonPrefab, spellListContainer);
+
+        // Get or create components
+        Button button = buttonObj.GetComponent<Button>();
+        if (button == null)
+            button = buttonObj.AddComponent<Button>();
+
+        // Find or create text components
+        TextMeshProUGUI nameText = buttonObj.transform.Find("SpellName")?.GetComponent<TextMeshProUGUI>();
+        TextMeshProUGUI descText = buttonObj.transform.Find("Description")?.GetComponent<TextMeshProUGUI>();
+        TextMeshProUGUI costText = buttonObj.transform.Find("ManaCost")?.GetComponent<TextMeshProUGUI>();
+        Image iconImage = buttonObj.transform.Find("Icon")?.GetComponent<Image>();
+
+        // Create text components if they don't exist
+        if (nameText == null)
+        {
+            GameObject nameObj = new GameObject("SpellName");
+            nameObj.transform.SetParent(buttonObj.transform, false);
+            nameText = nameObj.AddComponent<TextMeshProUGUI>();
+
+            RectTransform nameRect = nameText.GetComponent<RectTransform>();
+            nameRect.anchorMin = new Vector2(0.1f, 0.7f);
+            nameRect.anchorMax = new Vector2(0.7f, 0.9f);
+            nameRect.offsetMin = Vector2.zero;
+            nameRect.offsetMax = Vector2.zero;
+
+            nameText.fontSize = 14;
+            nameText.fontStyle = FontStyles.Bold;
+            nameText.alignment = TextAlignmentOptions.Left;
+        }
+
+        if (descText == null)
+        {
+            GameObject descObj = new GameObject("Description");
+            descObj.transform.SetParent(buttonObj.transform, false);
+            descText = descObj.AddComponent<TextMeshProUGUI>();
+
+            RectTransform descRect = descText.GetComponent<RectTransform>();
+            descRect.anchorMin = new Vector2(0.1f, 0.3f);
+            descRect.anchorMax = new Vector2(0.9f, 0.7f);
+            descRect.offsetMin = Vector2.zero;
+            descRect.offsetMax = Vector2.zero;
+
+            descText.fontSize = 10;
+            descText.alignment = TextAlignmentOptions.Left;
+            descText.color = Color.gray;
+        }
+
+        if (costText == null)
+        {
+            GameObject costObj = new GameObject("ManaCost");
+            costObj.transform.SetParent(buttonObj.transform, false);
+            costText = costObj.AddComponent<TextMeshProUGUI>();
+
+            RectTransform costRect = costText.GetComponent<RectTransform>();
+            costRect.anchorMin = new Vector2(0.7f, 0.7f);
+            costRect.anchorMax = new Vector2(0.9f, 0.9f);
+            costRect.offsetMin = Vector2.zero;
+            costRect.offsetMax = Vector2.zero;
+
+            costText.fontSize = 12;
+            costText.alignment = TextAlignmentOptions.Right;
+            costText.color = Color.cyan;
+        }
+
+        // Set content
+        nameText.text = spell.name;
+        descText.text = spell.description;
+        costText.text = $"{spell.manaCost} MP";
+
+        // Add spell type indicators
+        if (spell.isAoE)
+        {
+            nameText.text += " (AoE)";
+        }
+        if (spell.requiresTarget)
+        {
+            descText.text += " [Requires Target]";
+        }
+
+        if (iconImage != null && spell.icon != null)
+            iconImage.sprite = spell.icon;
+
+        // Check if character can cast this spell (placeholder)
+        bool canCast = CanCharacterCastSpell(spell);
+        button.interactable = canCast;
+
+        if (!canCast)
+        {
+            // Dim the button for unusable spells
+            var colors = button.colors;
+            colors.normalColor = Color.gray;
+            colors.disabledColor = Color.gray;
+            button.colors = colors;
+
+            nameText.color = Color.gray;
+            descText.color = Color.gray;
+            costText.color = Color.gray;
+        }
+
+        // Setup button click
+        button.onClick.AddListener(() =>
+        {
+            if (canCast)
+            {
+                OnSpellSelected?.Invoke(spell.name);
+                HideSelection();
+            }
+        });
+
+        spellButtons.Add(buttonObj);
+    }
+
+    private bool CanCharacterCastSpell(SpellData spell)
+    {
+        // Placeholder logic - check if character has enough mana, knows spell, etc.
+        // TODO: Implement actual spell casting requirements
+
+        if (currentCharacter == null)
+            return false;
+
+        // For now, assume character can cast if they have enough "mana"
+        // (We'll need to add a mana system to characters later)
+        return true;
+    }
+
+    private void ClearSpellList()
+    {
+        foreach (var button in spellButtons)
+        {
+            if (button != null)
+                DestroyImmediate(button);
+        }
+        spellButtons.Clear();
+    }
+
+    private void SetVisible(bool visible)
+    {
+        if (selectionCanvas != null)
+            selectionCanvas.gameObject.SetActive(visible);
+    }
+
+    [System.Serializable]
+    private class SpellData
+    {
+        public string name;
+        public string description;
+        public int manaCost;
+        public bool requiresTarget;
+        public bool isAoE;
+        public Sprite icon;
+    }
+}

+ 282 - 0
Assets/Scripts/BattleScene/UIToolkitActionWheel.cs

@@ -0,0 +1,282 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+using System.Collections.Generic;
+using System;
+
+/// <summary>
+/// Modern UI Toolkit-based action wheel for battle actions
+/// Uses UI Builder and USS for styling instead of legacy Canvas components
+/// </summary>
+public class UIToolkitActionWheel : MonoBehaviour
+{
+    [Header("Settings")]
+    public float wheelRadius = 150f;
+    public float buttonSize = 80f;
+    public KeyCode toggleKey = KeyCode.Q;
+
+    private UIDocument uiDocument;
+    private VisualElement root;
+    private VisualElement wheelContainer;
+    private List<ActionButtonElement> actionButtons = new List<ActionButtonElement>();
+    private Character currentCharacter;
+    private bool isVisible = false;
+
+    // Events
+    public event Action<BattleActionType> OnActionSelected;
+    public event Action OnWheelClosed;
+
+    private class ActionButtonElement
+    {
+        public VisualElement element;
+        public BattleActionType actionType;
+        public bool isEnabled = true;
+
+        public ActionButtonElement(VisualElement element, BattleActionType actionType)
+        {
+            this.element = element;
+            this.actionType = actionType;
+        }
+    }
+
+    void Awake()
+    {
+        // Get or create UIDocument
+        uiDocument = GetComponent<UIDocument>();
+        if (uiDocument == null)
+        {
+            uiDocument = gameObject.AddComponent<UIDocument>();
+        }
+
+        CreateActionWheelUI();
+    }
+
+    void Start()
+    {
+        SetVisible(false);
+    }
+
+    void Update()
+    {
+        if (Input.GetKeyDown(toggleKey))
+        {
+            if (isVisible)
+            {
+                HideWheel();
+            }
+            else
+            {
+                // Find selected character
+                var selectedCharacter = FindSelectedCharacter();
+                if (selectedCharacter != null)
+                {
+                    ShowWheelForCharacter(selectedCharacter);
+                }
+                else
+                {
+                    Debug.Log("⚠️ No character selected for action wheel");
+                }
+            }
+        }
+
+        if (isVisible && Input.GetKeyDown(KeyCode.Escape))
+        {
+            HideWheel();
+        }
+    }
+
+    private void CreateActionWheelUI()
+    {
+        // Create the root UI structure programmatically
+        root = new VisualElement();
+        root.name = "ActionWheelRoot";
+        root.style.position = Position.Absolute;
+        root.style.width = Length.Percent(100);
+        root.style.height = Length.Percent(100);
+        root.style.justifyContent = Justify.Center;
+        root.style.alignItems = Align.Center;
+
+        // Create wheel container
+        wheelContainer = new VisualElement();
+        wheelContainer.name = "WheelContainer";
+        wheelContainer.style.width = wheelRadius * 2;
+        wheelContainer.style.height = wheelRadius * 2;
+        wheelContainer.style.position = Position.Relative;
+
+        // Add background circle
+        var background = new VisualElement();
+        background.name = "WheelBackground";
+        background.style.width = Length.Percent(100);
+        background.style.height = Length.Percent(100);
+        background.style.borderTopLeftRadius = wheelRadius;
+        background.style.borderTopRightRadius = wheelRadius;
+        background.style.borderBottomLeftRadius = wheelRadius;
+        background.style.borderBottomRightRadius = wheelRadius;
+        background.style.backgroundColor = new Color(0, 0, 0, 0.3f);
+        background.style.borderBottomColor = Color.white;
+        background.style.borderBottomWidth = 2;
+        background.style.borderTopColor = Color.white;
+        background.style.borderTopWidth = 2;
+        background.style.borderLeftColor = Color.white;
+        background.style.borderLeftWidth = 2;
+        background.style.borderRightColor = Color.white;
+        background.style.borderRightWidth = 2;
+
+        wheelContainer.Add(background);
+
+        // Create action buttons
+        CreateActionButtons();
+
+        root.Add(wheelContainer);
+
+        // Set the visual tree
+        if (uiDocument.visualTreeAsset == null)
+        {
+            uiDocument.rootVisualElement.Add(root);
+        }
+    }
+
+    private void CreateActionButtons()
+    {
+        var actionDefinitions = new[]
+        {
+            new { type = BattleActionType.Attack, label = "⚔️\nAttack", color = new Color(1f, 0.3f, 0.3f) },
+            new { type = BattleActionType.Move, label = "👟\nMove", color = new Color(0.3f, 1f, 0.3f) },
+            new { type = BattleActionType.UseItem, label = "🧪\nItem", color = new Color(0.3f, 0.3f, 1f) },
+            new { type = BattleActionType.CastSpell, label = "✨\nSpell", color = new Color(1f, 0.3f, 1f) },
+            new { type = BattleActionType.Defend, label = "🛡️\nDefend", color = new Color(0.8f, 0.8f, 0.3f) },
+            new { type = BattleActionType.RunAway, label = "💨\nRun", color = new Color(0.6f, 0.6f, 0.6f) }
+        };
+
+        int actionCount = actionDefinitions.Length;
+        float angleStep = 360f / actionCount;
+
+        for (int i = 0; i < actionCount; i++)
+        {
+            var actionDef = actionDefinitions[i];
+            float angle = i * angleStep - 90f; // Start from top
+
+            CreateActionButton(actionDef.type, actionDef.label, actionDef.color, angle);
+        }
+    }
+
+    private void CreateActionButton(BattleActionType actionType, string label, Color color, float angle)
+    {
+        var button = new Button();
+        button.name = $"ActionButton_{actionType}";
+        button.text = label;
+
+        // Calculate position on circle
+        float radian = angle * Mathf.Deg2Rad;
+        float x = Mathf.Cos(radian) * (wheelRadius * 0.7f);
+        float y = Mathf.Sin(radian) * (wheelRadius * 0.7f);
+
+        // Style the button
+        button.style.position = Position.Absolute;
+        button.style.width = buttonSize;
+        button.style.height = buttonSize;
+        button.style.left = wheelRadius + x - buttonSize / 2;
+        button.style.top = wheelRadius + y - buttonSize / 2;
+        button.style.borderTopLeftRadius = buttonSize / 2;
+        button.style.borderTopRightRadius = buttonSize / 2;
+        button.style.borderBottomLeftRadius = buttonSize / 2;
+        button.style.borderBottomRightRadius = buttonSize / 2;
+        button.style.backgroundColor = color;
+        button.style.color = Color.white;
+        button.style.fontSize = 12;
+        button.style.unityTextAlign = TextAnchor.MiddleCenter;
+        button.style.borderBottomColor = Color.white;
+        button.style.borderBottomWidth = 2;
+        button.style.borderTopColor = Color.white;
+        button.style.borderTopWidth = 2;
+        button.style.borderLeftColor = Color.white;
+        button.style.borderLeftWidth = 2;
+        button.style.borderRightColor = Color.white;
+        button.style.borderRightWidth = 2;
+
+        // Add hover effects
+        button.RegisterCallback<MouseEnterEvent>(evt =>
+        {
+            button.style.scale = new Scale(new Vector3(1.1f, 1.1f, 1f));
+            button.style.backgroundColor = Color.Lerp(color, Color.white, 0.3f);
+        });
+
+        button.RegisterCallback<MouseLeaveEvent>(evt =>
+        {
+            button.style.scale = new Scale(Vector3.one);
+            button.style.backgroundColor = color;
+        });
+
+        // Handle button click
+        button.clicked += () =>
+        {
+            OnActionButtonClicked(actionType);
+        };
+
+        wheelContainer.Add(button);
+        actionButtons.Add(new ActionButtonElement(button, actionType));
+    }
+
+    private void OnActionButtonClicked(BattleActionType actionType)
+    {
+        Debug.Log($"🎯 Action selected: {actionType}");
+        OnActionSelected?.Invoke(actionType);
+        HideWheel();
+    }
+
+    public void ShowWheelForCharacter(Character character)
+    {
+        if (character == null)
+        {
+            Debug.LogWarning("Cannot show action wheel: character is null");
+            return;
+        }
+
+        currentCharacter = character;
+        SetVisible(true);
+
+        Debug.Log($"🎮 Action wheel shown for {character.CharacterName}");
+    }
+
+    public void HideWheel()
+    {
+        SetVisible(false);
+        OnWheelClosed?.Invoke();
+
+        Debug.Log("🎮 Action wheel hidden");
+    }
+
+    private void SetVisible(bool visible)
+    {
+        isVisible = visible;
+        if (root != null)
+        {
+            root.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
+        }
+    }
+
+    private Character FindSelectedCharacter()
+    {
+        // Find the currently selected character
+        // This could be done through various methods - checking what's highlighted, etc.
+        var characters = FindObjectsByType<Character>(FindObjectsSortMode.None);
+
+        foreach (var character in characters)
+        {
+            if (character.CompareTag("Player"))
+            {
+                // For now, return the first player character found
+                // In a real implementation, you'd check which one is actually selected
+                return character;
+            }
+        }
+
+        return null;
+    }
+
+    void OnDestroy()
+    {
+        // Clean up events
+        OnActionSelected = null;
+        OnWheelClosed = null;
+    }
+}

+ 64 - 0
Assets/Scripts/Objects/Character.cs

@@ -112,6 +112,26 @@ public abstract class Character : MonoBehaviour
     public bool IsDead { get => isDead; }
     public bool IsTargetable { get => isTargetable; }
 
+    // Enhanced action data - dynamically typed to avoid compilation dependencies
+    private object _enhancedActionData;
+    public object enhancedActionData
+    {
+        get => _enhancedActionData;
+        set => _enhancedActionData = value;
+    }
+
+    // Helper method to get typed action data
+    public T GetEnhancedActionData<T>() where T : class
+    {
+        return _enhancedActionData as T;
+    }
+
+    // Helper method to set enhanced action data safely
+    public void SetEnhancedActionData(object data)
+    {
+        _enhancedActionData = data;
+    }
+
     protected Weapon spawnedWeapon;
 
     public Weapon Weapon { get => spawnedWeapon; set => spawnedWeapon = value; }
@@ -452,6 +472,50 @@ public abstract class Character : MonoBehaviour
         }
     }
 
+    public void Heal(int healAmount)
+    {
+        if (isDead) return;
+
+        currentHealth = Mathf.Min(currentHealth + healAmount, maxHealth);
+        Debug.Log($"{CharacterName} healed for {healAmount} HP. Health: {currentHealth}/{maxHealth}");
+
+        // Update health bar
+        UpdateHealthBar();
+    }
+
+    public void AttackTarget(Character target)
+    {
+        if (target == null || target.IsDead)
+        {
+            Debug.LogWarning($"{CharacterName} tried to attack invalid target");
+            return;
+        }
+
+        // Calculate damage based on weapon and stats
+        int damage = CalculateDamage();
+
+        Debug.Log($"⚔️ {CharacterName} attacks {target.CharacterName} for {damage} damage");
+
+        target.TakeDamage(damage);
+    }
+
+    private int CalculateDamage()
+    {
+        // Base damage calculation
+        int baseDamage = attack + damageModifier;
+
+        // Add weapon damage if equipped
+        if (spawnedWeapon != null)
+        {
+            baseDamage += spawnedWeapon.damage;
+        }
+
+        // Add some randomness (±20%)
+        float randomMultiplier = UnityEngine.Random.Range(0.8f, 1.2f);
+
+        return Mathf.Max(1, Mathf.RoundToInt(baseDamage * randomMultiplier));
+    }
+
     // Debug method to test attacks manually
     public void DebugAttack(GameObject target)
     {

+ 204 - 0
BATTLE_ACTION_SYSTEM_GUIDE.md

@@ -0,0 +1,204 @@
+# Battle Action System Setup Guide
+
+## Overview
+This new battle action system provides a radial decision wheel for selecting character actions including:
+- **Move** - Move to a target location
+- **Attack** - Attack an enemy target  
+- **Use Item** - Use consumable items (healing potions, etc.)
+- **Cast Spell** - Cast magical spells (placeholder implementation)
+- **Defend** - Defensive stance for damage reduction
+- **Run Away** - Retreat from combat
+
+## Setup Instructions
+
+### 1. Scene Setup
+Add these components to your BattleScene:
+
+1. **BattleActionSystem** - Main system controller
+   - Add to an empty GameObject named "BattleActionSystem"
+
+2. **BattleActionWheel** - The radial menu UI
+   - Create a Canvas with these settings:
+     - Render Mode: Screen Space - Overlay (or Camera)
+     - Canvas Scaler: Scale With Screen Size
+   - Add BattleActionWheel script to Canvas or child object
+
+3. **BattleActionIntegration** - Connects new and old systems
+   - Add to an empty GameObject named "BattleActionIntegration"
+
+### 2. UI Setup
+
+#### Action Wheel Canvas Structure:
+```
+Canvas (BattleActionWheel)
+├── WheelBackground (Image)
+└── WheelCenter (Empty GameObject)
+    └── ActionButtons (will be created automatically)
+```
+
+#### Action Button Prefab:
+Create a prefab with this structure:
+```
+ActionButton (Button + Image)
+├── Icon (Image)
+└── Label (TextMeshPro)
+```
+
+Use the `ActionButtonCreator.CreateActionButton()` method to create buttons programmatically.
+
+### 3. Integration with Existing System
+
+The new system can run alongside your existing click-drag system:
+
+- **Space Key** - Show action wheel for selected character
+- **Left Click** - Select character (when using new system)
+- **Toggle** - Switch between old and new systems via `BattleActionIntegration.ToggleActionSystem()`
+
+### 4. Required Assets
+
+#### Icons (Optional but recommended):
+- Move icon (arrow or footsteps)
+- Attack icon (sword or crossed swords)  
+- Item icon (potion or bag)
+- Spell icon (magic wand or star)
+- Defend icon (shield)
+- Run Away icon (running figure)
+
+#### Fonts:
+- TextMeshPro font for button labels
+
+### 5. Character Setup
+
+No changes needed to existing Character prefabs! The system will:
+- Automatically initialize enhanced action data when needed
+- Work with existing health/damage systems
+- Use existing weapon systems
+
+### 6. Usage Flow
+
+1. **Character Selection**:
+   ```csharp
+   // Manual selection
+   battleActionIntegration.SelectCharacter(character);
+   
+   // Or click on character in game
+   ```
+
+2. **Action Selection**:
+   - Action wheel appears automatically
+   - Click desired action type
+   - Follow targeting prompts if needed
+
+3. **Action Execution**:
+   ```csharp
+   // Execute single character
+   battleActionSystem.ExecuteCharacterAction(character);
+   
+   // Execute all players (turn-based)
+   battleActionIntegration.ExecuteAllPlayerActions();
+   ```
+
+## API Reference
+
+### Key Components
+
+#### BattleActionSystem
+- `ShowActionWheel(Character)` - Display action wheel
+- `ExecuteCharacterAction(Character)` - Execute selected action
+- Events: `OnActionStarted`, `OnActionCompleted`
+
+#### BattleActionWheel  
+- `ShowWheel(Character, Vector3)` - Show at world position
+- `HideWheel()` - Hide the wheel
+- Events: `OnActionSelected`, `OnWheelClosed`
+
+#### BattleActionIntegration
+- `SelectCharacter(Character)` - Select for action
+- `ExecuteAllPlayerActions()` - Execute all player actions
+- `ResetAllPlayerActions()` - Clear all actions for new turn
+- `AllPlayersHaveActions()` - Check if all players ready
+
+### Action Types
+
+```csharp
+public enum BattleActionType
+{
+    Move,        // Position targeting
+    Attack,      // Enemy targeting  
+    UseItem,     // Item selection + optional targeting
+    CastSpell,   // Spell selection + optional targeting
+    Defend,      // No targeting needed
+    Wait,        // No targeting needed
+    RunAway      // No targeting needed
+}
+```
+
+### Enhanced Action Data
+
+```csharp
+// Access character's action data
+var actionData = character.enhancedActionData as EnhancedCharacterActionData;
+if (actionData != null && actionData.hasValidAction)
+{
+    Debug.Log($"Action: {actionData.GetActionDescription()}");
+}
+```
+
+## Extending the System
+
+### Adding New Actions:
+1. Add to `BattleActionType` enum
+2. Update `BattleActionWheel.CreateActionButtons()`
+3. Add case to `BattleActionSystem.ExecuteActionCoroutine()`
+4. Create execution method in `BattleActionSystem`
+
+### Custom Item/Spell Systems:
+Replace placeholder implementations in:
+- `ItemSelectionUI.GetCharacterItems()`
+- `SpellSelectionUI.GetCharacterSpells()`
+- `BattleActionSystem.UseItem()` 
+- `BattleActionSystem.CastSpell()`
+
+### Visual Customization:
+- Modify colors in `BattleActionWheel`
+- Replace button creation in `ActionButtonCreator`
+- Add animations to action execution methods
+
+## Testing
+
+Use the debug UI (visible when `useNewActionSystem = true`):
+- Select characters
+- View action status
+- Execute actions manually
+- Reset system state
+- Toggle between old/new systems
+
+The system includes extensive debug logging with emoji prefixes:
+- 🎯 Action selection
+- ⚔️ Combat actions
+- 🧪 Item usage
+- ✨ Spell casting
+- 🛡️ Defensive actions
+
+## Troubleshooting
+
+### Common Issues:
+
+1. **Action wheel not showing**: Check Canvas setup and camera assignments
+2. **Buttons not working**: Verify Button components and event setup
+3. **Targeting not working**: Check LayerMasks in BattleActionSystem
+4. **Compilation errors**: Ensure all scripts are in correct folders
+
+### Debug Commands:
+```csharp
+// Force show action wheel
+battleActionSystem.ShowActionWheel(character);
+
+// Check action status
+Debug.Log(character.enhancedActionData?.GetActionDescription());
+
+// Reset if stuck
+battleActionIntegration.ResetAllPlayerActions();
+```
+
+This system provides a solid foundation for complex battle actions while maintaining compatibility with your existing combat system!

+ 4 - 4
UserSettings/EditorUserSettings.asset

@@ -15,19 +15,19 @@ EditorUserSettings:
       value: 5655020755505a0d5e0a5577457b0a44154f1a7f2a7e70697e284b30e4b2623b
       flags: 0
     RecentlyUsedSceneGuid-2:
-      value: 510500025d560a0c095d092111730d44464f4b78757b72357a701c31b7b16368
+      value: 51020c5550545a0354575e7b47270744174e4b787e2b77687b7e1b37e7e4366d
       flags: 0
     RecentlyUsedSceneGuid-3:
       value: 5309060006570d5f0c580e2715270c44144e1c722a7d20612c2d4b37b1b4643a
       flags: 0
     RecentlyUsedSceneGuid-4:
-      value: 5a08575f5207595a0f5d59741173094444164f7d7d2a23317c7a4465bbe1646d
+      value: 510500025d560a0c095d092111730d44464f4b78757b72357a701c31b7b16368
       flags: 0
     RecentlyUsedSceneGuid-5:
-      value: 5a090503000558580f0d557342700844144f4d7c7b7d74692c281e63b0e2623c
+      value: 5a08575f5207595a0f5d59741173094444164f7d7d2a23317c7a4465bbe1646d
       flags: 0
     RecentlyUsedSceneGuid-6:
-      value: 51020c5550545a0354575e7b47270744174e4b787e2b77687b7e1b37e7e4366d
+      value: 5a090503000558580f0d557342700844144f4d7c7b7d74692c281e63b0e2623c
       flags: 0
     vcSharedLogLevel:
       value: 0d5e400f0650

+ 2 - 2
UserSettings/Layouts/default-6000.dwlt

@@ -1431,7 +1431,7 @@ MonoBehaviour:
     scrollPos: {x: 0, y: 219}
     m_SelectedIDs: 2eb50000
     m_LastClickedID: 46382
-    m_ExpandedIDs: 0000000090b3000092b3000094b3000096b3000098b300009ab300009cb300009eb30000a0b30000a2b30000a4b30000a6b30000a8b30000aab30000
+    m_ExpandedIDs: 
     m_RenameOverlay:
       m_UserAcceptedRename: 0
       m_Name: 
@@ -1460,7 +1460,7 @@ MonoBehaviour:
     scrollPos: {x: 0, y: 0}
     m_SelectedIDs: 
     m_LastClickedID: 0
-    m_ExpandedIDs: 0000000090b3000092b3000094b3000096b3000098b300009ab300009cb300009eb30000a0b30000a2b30000a4b30000a6b30000a8b30000aab30000
+    m_ExpandedIDs: 
     m_RenameOverlay:
       m_UserAcceptedRename: 0
       m_Name: