| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- 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);
- }
- }
- }
- 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)
- {
- OnActionSelected?.Invoke(actionType);
- HideWheel();
- }
- public void ShowWheelForCharacter(Character character)
- {
- if (character == null)
- {
- return;
- }
- currentCharacter = character;
- SetVisible(true);
- }
- public void HideWheel()
- {
- SetVisible(false);
- OnWheelClosed?.Invoke();
- }
- 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;
- }
- }
|