| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867 |
- using System.Collections;
- using System.Collections.Generic;
- using Unity.VisualScripting;
- using UnityEngine;
- using UnityEngine.UIElements;
- using UnityEngine.AI;
- public class PlayerDecisionController : MonoBehaviour
- {
- [Header("References")]
- public LayerMask enemyLayerMask = 1 << 10; // Enemy layer
- public LayerMask playerLayerMask = 1 << 9; // Player layer
- [Header("State")]
- private Character selectedCharacter;
- private bool isDragging = false;
- private Vector3 dragStartPosition;
- [Header("Settings")]
- public float enemySnapDistance = 1f;
- private List<Character> playerCharacters = new List<Character>();
- private TargetingLine targetingLine;
- private Camera mainCamera;
- private bool isEnabled = true;
- private List<TargetingLine> activeActionLines = new List<TargetingLine>();
- [Header("Character Stats UI")]
- public VisualTreeAsset characterStatsUXML;
- public StyleSheet characterStatsUSS;
- private UIDocument uiDocument;
- private VisualElement statsPanel;
- private bool isStatsPanelVisible = false;
- void Awake()
- {
- mainCamera = Camera.main;
- targetingLine = GetComponent<TargetingLine>();
- if (targetingLine == null)
- {
- targetingLine = gameObject.AddComponent<TargetingLine>();
- }
- }
- void Start()
- {
- InitializePlayerCharacters();
- SetupCharacterStatsUI();
- // Wait a moment for battle setup to complete, then refresh stats display
- StartCoroutine(RefreshStatsAfterSetup());
- }
- private IEnumerator RefreshStatsAfterSetup()
- {
- // Wait for battle setup to complete
- yield return new WaitForSeconds(0.5f);
- // Refresh stats display if panel is visible and character is selected
- if (isStatsPanelVisible && selectedCharacter != null)
- {
- UpdateCharacterStatsDisplay(selectedCharacter);
- }
- }
- void Update()
- {
- HandleInput();
- }
- private void InitializePlayerCharacters()
- {
- // Get player characters from GameManager if available
- if (GameManager.Instance != null)
- {
- playerCharacters.Clear();
- foreach (GameObject playerGO in GameManager.Instance.playerCharacters)
- {
- Character character = playerGO.GetComponent<Character>();
- if (character != null)
- {
- playerCharacters.Add(character);
- }
- }
- }
- else
- {
- // Fallback: find all characters (for testing without GameManager)
- Character[] characters = FindObjectsByType<Character>(FindObjectsSortMode.None);
- playerCharacters.AddRange(characters);
- }
- foreach (Character character in playerCharacters)
- {
- character.actionData.Reset();
- character.SetVisualState(ActionDecisionState.NoAction);
- }
- }
- private void HandleInput()
- {
- if (!isEnabled) return;
- // Toggle character stats panel with 'C' key
- if (Input.GetKeyDown(KeyCode.C))
- {
- ToggleStatsPanel();
- }
- if (Input.GetMouseButtonDown(0)) // Left click
- {
- HandleLeftClickDown();
- }
- else if (Input.GetMouseButton(0) && isDragging) // Left drag
- {
- HandleLeftDrag();
- }
- else if (Input.GetMouseButtonUp(0)) // Left release
- {
- HandleLeftClickUp();
- }
- else if (Input.GetMouseButtonDown(1)) // Right click
- {
- HandleRightClick();
- }
- }
- /// <summary>
- /// Check if we're currently in move targeting mode (move action selected but not yet targeted)
- /// </summary>
- private bool IsInMoveTargetingMode()
- {
- if (selectedCharacter == null) return false;
- var actionData = selectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
- return actionData != null &&
- actionData.actionType == BattleActionType.Move &&
- actionData.state == ActionDecisionState.NoAction;
- }
- private void HandleLeftClickDown()
- {
- Vector3 mouseWorldPosition = GetMouseWorldPosition();
- Character clickedCharacter = GetPlayerCharacterAtPosition(mouseWorldPosition);
- if (clickedCharacter != null)
- {
- // Start drag mode from character - this allows both move and attack by dragging
- selectedCharacter = clickedCharacter;
- isDragging = true;
- dragStartPosition = clickedCharacter.transform.position;
- // Update character stats display if panel is visible
- UpdateCharacterStatsDisplay(clickedCharacter);
- // Clear any existing action lines before starting new targeting
- ClearActionLineForCharacter(clickedCharacter);
- // Start targeting line for drag operations
- targetingLine.StartTargeting(dragStartPosition);
- // CinemachineCameraController.Instance.FocusOnCharacter(clickedCharacter.transform);
- }
- else
- {
- // Clicked empty space - start drag if we have a selected character and are in move mode
- if (selectedCharacter != null && IsInMoveTargetingMode())
- {
- isDragging = true;
- targetingLine.StartTargeting(selectedCharacter.transform.position);
- }
- }
- }
- private void HandleLeftDrag()
- {
- if (selectedCharacter == null) return;
- Vector3 mouseWorldPos = GetMouseWorldPosition();
- GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
- if (enemyAtMouse != null)
- {
- // Snap to enemy
- Vector3 enemyPos = enemyAtMouse.transform.position;
- targetingLine.UpdateTargeting(dragStartPosition, enemyPos, true);
- }
- else
- {
- // Follow mouse
- targetingLine.UpdateTargeting(dragStartPosition, mouseWorldPos, false);
- }
- }
- private void HandleLeftClickUp()
- {
- Vector3 mouseWorldPos = GetMouseWorldPosition();
- GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
- // Handle different cases based on current state
- if (isDragging && selectedCharacter != null)
- {
- // We're in active targeting mode
- if (enemyAtMouse != null)
- {
- // Attack target selected
- selectedCharacter.actionData.SetAttackTarget(enemyAtMouse);
- UpdateEnhancedActionData(selectedCharacter, BattleActionType.Attack, enemyAtMouse, mouseWorldPos);
- selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
- }
- else
- {
- // Check if user actually dragged (minimum distance threshold) OR if we're in action wheel move mode
- float dragDistance = Vector3.Distance(dragStartPosition, mouseWorldPos);
- const float minDragDistance = 0.5f; // Minimum distance to consider it a drag vs click
- bool isActionWheelMove = IsInMoveTargetingMode();
- bool isDragMove = dragDistance > minDragDistance;
- if (isActionWheelMove || isDragMove)
- {
- // Move target selected
- selectedCharacter.actionData.SetMoveTarget(mouseWorldPos);
- UpdateEnhancedActionData(selectedCharacter, BattleActionType.Move, null, mouseWorldPos);
- selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
- }
- }
- // Notify BattleActionIntegration that targeting is complete
- var integration = FindFirstObjectByType<BattleActionIntegration>();
- if (integration != null)
- {
- integration.OnTargetingComplete(selectedCharacter);
- }
- // Cleanup targeting
- targetingLine.StopTargeting();
- isDragging = false;
- selectedCharacter = null; // Clear selection after action is set
- }
- else if (selectedCharacter != null)
- {
- // Just a character selection click - notify integration but don't set actions
- var integration = FindFirstObjectByType<BattleActionIntegration>();
- if (integration != null)
- {
- integration.OnTargetingComplete(selectedCharacter);
- }
- // Don't clear selectedCharacter here - let integration handle it
- }
- // Cleanup
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- }
- private void HandleRightClick()
- {
- if (isDragging && selectedCharacter != null)
- {
- // Cancel current action
- selectedCharacter.actionData.Reset();
- selectedCharacter.SetVisualState(ActionDecisionState.NoAction);
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- }
- else
- {
- // Right click on character to reset their action
- Vector3 mouseWorldPos = GetMouseWorldPosition();
- Character clickedCharacter = GetPlayerCharacterAtPosition(mouseWorldPos);
- if (clickedCharacter != null)
- {
- clickedCharacter.actionData.Reset();
- clickedCharacter.SetVisualState(ActionDecisionState.NoAction);
- }
- }
- }
- private Vector3 GetMouseWorldPosition()
- {
- Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
- RaycastHit hit;
- // Raycast against a ground plane or existing colliders
- if (Physics.Raycast(ray, out hit, 200f))
- {
- return hit.point;
- }
- // Fallback: project onto a horizontal plane at y=0
- Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
- if (groundPlane.Raycast(ray, out float distance))
- {
- Vector3 position = ray.GetPoint(distance);
- return position;
- }
- return Vector3.zero;
- }
- private Character GetPlayerCharacterAtPosition(Vector3 worldPosition)
- {
- Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
- RaycastHit hit;
- if (Physics.Raycast(ray, out hit, 200f, playerLayerMask))
- {
- return hit.collider.GetComponent<Character>();
- }
- // Try raycast without layer mask to see what we're hitting
- if (Physics.Raycast(ray, out hit, 200f))
- {
- }
- else
- {
- }
- return null;
- }
- private GameObject GetEnemyAtPosition(Vector3 worldPosition)
- {
- Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
- RaycastHit hit;
- if (Physics.Raycast(ray, out hit, 200f, enemyLayerMask))
- {
- return hit.collider.gameObject;
- }
- return null;
- }
- public bool AllCharactersHaveActions()
- {
- foreach (var character in playerCharacters)
- {
- // Characters need actions if they have no action set
- if (character.actionData.state == ActionDecisionState.NoAction)
- return false;
- }
- return true;
- }
- public void ResetAllCharacterActions()
- {
- foreach (var character in playerCharacters)
- {
- character.actionData.Reset();
- character.SetVisualState(ActionDecisionState.NoAction);
- }
- }
- public void UpdateVisualStates()
- {
- foreach (var character in playerCharacters)
- {
- // Update visual states based on current action status
- if (character.actionData.state == ActionDecisionState.NoAction)
- {
- character.SetVisualState(ActionDecisionState.NoAction); // Pink
- }
- else if (character.HasActionSelected())
- {
- character.SetVisualState(ActionDecisionState.ActionSelected); // Green
- }
- }
- }
- public void RefreshPlayerCharacters()
- {
- InitializePlayerCharacters();
- }
- public void SetEnabled(bool enabled)
- {
- isEnabled = enabled;
- if (!enabled)
- {
- if (isDragging)
- {
- // Cancel any current dragging operation
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- }
- // Don't automatically hide action lines when disabling - let caller decide
- }
- }
- /// <summary>
- /// Check if PlayerDecisionController is currently in targeting/dragging mode
- /// </summary>
- public bool IsInTargetingMode => isDragging && selectedCharacter != null;
- /// <summary>
- /// Get the currently selected character (for action wheel integration)
- /// </summary>
- public Character GetSelectedCharacter() => selectedCharacter;
- /// <summary>
- /// Reset the controller state (for debugging/recovery)
- /// </summary>
- public void ResetState()
- {
- if (isDragging && targetingLine != null)
- {
- targetingLine.StopTargeting();
- }
- selectedCharacter = null;
- isDragging = false;
- isEnabled = true;
- }
- public void ShowActiveActionLines()
- {
- HideActiveActionLines(); // Clear any existing lines first
- foreach (var character in playerCharacters)
- {
- if (character.HasActionSelected() && !character.IsActionComplete())
- {
- GameObject lineObject = new GameObject($"ActionLine_{character.name}");
- TargetingLine line = lineObject.AddComponent<TargetingLine>();
- activeActionLines.Add(line);
- Vector3 startPos = character.transform.position + Vector3.up * 0.5f;
- if (character.actionData.targetEnemy != null)
- {
- Vector3 endPos = character.actionData.targetEnemy.transform.position + Vector3.up * 0.5f;
- line.StartTargeting(startPos);
- line.UpdateTargeting(startPos, endPos, true); // true for enemy target (red line)
- }
- else if (character.actionData.targetPosition != Vector3.zero)
- {
- line.StartTargeting(startPos);
- line.UpdateTargeting(startPos, character.actionData.targetPosition, false); // false for movement (blue line)
- }
- }
- }
- }
- public void HideActiveActionLines()
- {
- foreach (var line in activeActionLines)
- {
- if (line != null)
- {
- line.StopTargeting();
- Destroy(line.gameObject);
- }
- }
- activeActionLines.Clear();
- }
- public void ClearActionLineForCharacter(Character character)
- {
- for (int i = activeActionLines.Count - 1; i >= 0; i--)
- {
- var line = activeActionLines[i];
- if (line != null && line.gameObject.name == $"ActionLine_{character.name}")
- {
- line.StopTargeting();
- Destroy(line.gameObject);
- activeActionLines.RemoveAt(i);
- break;
- }
- }
- }
- 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)
- {
- // 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;
- }
- else if (actionType == BattleActionType.Move)
- {
- enhancedData.targetPosition = targetPosition;
- enhancedData.targetEnemy = null;
- }
- }
- }
- /// <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)
- {
- selectedCharacter = character;
- dragStartPosition = character.transform.position;
- // Update character stats display if panel is visible
- if (isStatsPanelVisible && selectedCharacter != null)
- {
- UpdateCharacterStatsDisplay(selectedCharacter);
- }
- // Store the action type for later reference
- var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
- if (enhancedData == null)
- {
- enhancedData = new EnhancedCharacterActionData();
- character.SetEnhancedActionData(enhancedData);
- }
- enhancedData.actionType = actionType;
- enhancedData.state = ActionDecisionState.NoAction; // Waiting for target
- // Start targeting mode - user needs to click to set target
- isDragging = true;
- // Clear any existing action lines before starting new targeting
- ClearActionLineForCharacter(character);
- // Start the targeting line
- targetingLine.StartTargeting(dragStartPosition);
- }
- /// <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;
- }
- }
- #region Character Stats UI
- private void SetupCharacterStatsUI()
- {
- // Get or create UIDocument component
- uiDocument = GetComponent<UIDocument>();
- if (uiDocument == null)
- {
- uiDocument = gameObject.AddComponent<UIDocument>();
- }
- // Set PanelSettings to mainSettings
- if (uiDocument.panelSettings == null)
- {
- SetupPanelSettings(uiDocument);
- }
- // Try to load UXML asset
- if (characterStatsUXML != null)
- {
- uiDocument.visualTreeAsset = characterStatsUXML;
- }
- // Check if we have content from UXML or need to create programmatically
- bool hasValidContent = uiDocument.rootVisualElement != null &&
- uiDocument.rootVisualElement.childCount > 0 &&
- uiDocument.rootVisualElement.Q("character-stats-container") != null;
- // Create UI structure programmatically only if UXML not found or invalid
- if (characterStatsUXML == null || !hasValidContent)
- {
- CreateCharacterStatsPanelProgrammatically();
- }
- // Get the stats panel
- statsPanel = uiDocument.rootVisualElement.Q("character-stats-container");
- if (statsPanel == null)
- {
- CreateCharacterStatsPanelProgrammatically();
- statsPanel = uiDocument.rootVisualElement.Q("character-stats-container");
- }
- // Apply stylesheet if available and not already applied
- if (characterStatsUSS != null && !uiDocument.rootVisualElement.styleSheets.Contains(characterStatsUSS))
- {
- uiDocument.rootVisualElement.styleSheets.Add(characterStatsUSS);
- }
- // Hide panel initially
- if (statsPanel != null)
- {
- statsPanel.style.display = DisplayStyle.None;
- }
- }
- private void CreateCharacterStatsPanelProgrammatically()
- {
- var root = uiDocument.rootVisualElement;
- root.Clear();
- // Create main container
- var container = new VisualElement();
- container.name = "character-stats-container";
- container.style.position = Position.Absolute;
- container.style.top = 10;
- container.style.right = 10;
- container.style.width = 280;
- container.style.backgroundColor = new Color(0, 0, 0, 0.8f);
- container.style.borderTopColor = container.style.borderBottomColor =
- container.style.borderLeftColor = container.style.borderRightColor = new Color(1, 1, 1, 0.3f);
- container.style.borderTopWidth = container.style.borderBottomWidth =
- container.style.borderLeftWidth = container.style.borderRightWidth = 1;
- container.style.borderTopLeftRadius = container.style.borderTopRightRadius =
- container.style.borderBottomLeftRadius = container.style.borderBottomRightRadius = 5;
- container.style.paddingTop = container.style.paddingBottom =
- container.style.paddingLeft = container.style.paddingRight = 10;
- container.style.color = Color.white;
- // Title
- var title = new Label("Character Stats");
- title.name = "title-label";
- title.style.fontSize = 16;
- title.style.color = new Color(1f, 0.84f, 0f); // Gold
- title.style.marginBottom = 10;
- title.style.unityFontStyleAndWeight = FontStyle.Bold;
- title.style.unityTextAlign = TextAnchor.MiddleCenter;
- container.Add(title);
- // Character info section
- var charInfo = new VisualElement();
- charInfo.name = "character-info";
- var charName = new Label("Character Name");
- charName.name = "character-name";
- charName.style.fontSize = 14;
- charName.style.color = new Color(0.56f, 0.93f, 0.56f); // Light green
- charName.style.unityFontStyleAndWeight = FontStyle.Bold;
- var charLevel = new Label("Level 1");
- charLevel.name = "character-level";
- charLevel.style.fontSize = 11;
- charLevel.style.color = new Color(0.87f, 0.63f, 0.87f); // Plum
- charLevel.style.marginBottom = 5;
- charInfo.Add(charName);
- charInfo.Add(charLevel);
- container.Add(charInfo);
- // Attributes section
- var attrSection = CreateStatsSection("Attributes", new string[]
- {
- "str-stat:STR: 10",
- "dex-stat:DEX: 10",
- "con-stat:CON: 10",
- "wis-stat:WIS: 10",
- "per-stat:PER: 10"
- });
- container.Add(attrSection);
- // Combat section
- var combatSection = CreateStatsSection("Combat Stats", new string[]
- {
- "health-stat:Health: 100/100",
- "attack-stat:Attack: 15",
- "ac-stat:AC: 12",
- "movement-stat:Movement: 10"
- });
- container.Add(combatSection);
- // Debug section
- var debugSection = CreateStatsSection("Debug Info", new string[]
- {
- "agent-speed-stat:Agent Speed: 3.5"
- });
- container.Add(debugSection);
- // Controls
- var controls = new VisualElement();
- var helpText = new Label("Press 'C' to toggle stats panel");
- helpText.style.fontSize = 10;
- helpText.style.color = new Color(0.8f, 0.8f, 0.8f);
- helpText.style.unityTextAlign = TextAnchor.MiddleCenter;
- helpText.style.marginTop = 5;
- controls.Add(helpText);
- container.Add(controls);
- root.Add(container);
- }
- private VisualElement CreateStatsSection(string title, string[] stats)
- {
- var section = new VisualElement();
- section.style.marginBottom = 8;
- var header = new Label(title);
- header.style.fontSize = 12;
- header.style.color = new Color(0.53f, 0.81f, 0.92f); // Sky blue
- header.style.marginBottom = 4;
- header.style.unityFontStyleAndWeight = FontStyle.Bold;
- section.Add(header);
- foreach (string stat in stats)
- {
- string[] parts = stat.Split(':');
- var label = new Label(parts.Length > 1 ? parts[1] : stat);
- if (parts.Length > 1) label.name = parts[0];
- label.style.fontSize = 11;
- label.style.color = Color.white;
- label.style.marginLeft = 5;
- label.style.marginBottom = 2;
- section.Add(label);
- }
- return section;
- }
- // New method to force refresh stats display
- public void RefreshCharacterStatsDisplay()
- {
- if (selectedCharacter != null && isStatsPanelVisible)
- {
- UpdateCharacterStatsDisplay(selectedCharacter);
- }
- }
- private void ToggleStatsPanel()
- {
- if (statsPanel == null) return;
- isStatsPanelVisible = !isStatsPanelVisible;
- statsPanel.style.display = isStatsPanelVisible ? DisplayStyle.Flex : DisplayStyle.None;
- // Update display when showing panel
- if (isStatsPanelVisible && selectedCharacter != null)
- {
- UpdateCharacterStatsDisplay(selectedCharacter);
- }
- }
- private void UpdateCharacterStatsDisplay(Character character)
- {
- if (statsPanel == null || !isStatsPanelVisible) return;
- // Update character info
- var nameLabel = statsPanel.Q<Label>("character-name");
- var levelLabel = statsPanel.Q<Label>("character-level");
- if (nameLabel != null) nameLabel.text = character.CharacterName;
- if (levelLabel != null) levelLabel.text = $"Level {character.Level}";
- // Update attributes
- UpdateStatLabel("str-stat", $"STR: {character.Strength}");
- UpdateStatLabel("dex-stat", $"DEX: {character.Dexterity}");
- UpdateStatLabel("con-stat", $"CON: {character.Constitution}");
- UpdateStatLabel("wis-stat", $"WIS: {character.Wisdom}");
- UpdateStatLabel("per-stat", $"PER: {character.Perception}");
- // Update combat stats
- UpdateStatLabel("health-stat", $"Health: {character.CurrentHealth}/{character.MaxHealth}");
- UpdateStatLabel("attack-stat", $"Attack: {character.Attack}");
- UpdateStatLabel("ac-stat", $"AC: {character.ArmorClass}");
- UpdateStatLabel("movement-stat", $"Movement: {character.MovementSpeed}");
- // Update debug info - get NavMeshAgent speed
- var agent = character.GetComponent<NavMeshAgent>();
- float agentSpeed = agent != null ? agent.speed : 0f;
- UpdateStatLabel("agent-speed-stat", $"Agent Speed: {agentSpeed:F1}");
- }
- private void UpdateStatLabel(string elementName, string text)
- {
- var label = statsPanel.Q<Label>(elementName);
- if (label != null) label.text = text;
- }
- /// <summary>
- /// Setup PanelSettings with multiple fallback methods
- /// </summary>
- private void SetupPanelSettings(UIDocument uiDoc)
- {
- // Try Resources first (original approach)
- var mainSettings = Resources.Load<PanelSettings>("MainSettings");
- if (mainSettings != null)
- {
- uiDoc.panelSettings = mainSettings;
- return;
- }
- // Try to find and reuse existing panel settings from other UI
- var existingUI = GameObject.Find("TravelUI")?.GetComponent<UIDocument>();
- if (existingUI?.panelSettings != null)
- {
- uiDoc.panelSettings = existingUI.panelSettings;
- return;
- }
- // Try to find from MainTeamSelectScript
- var mainTeamSelect = FindFirstObjectByType<MainTeamSelectScript>();
- if (mainTeamSelect != null)
- {
- var mainUIDoc = mainTeamSelect.GetComponent<UIDocument>();
- if (mainUIDoc?.panelSettings != null)
- {
- uiDoc.panelSettings = mainUIDoc.panelSettings;
- return;
- }
- }
- // Try to find any UIDocument in the scene with PanelSettings
- var allUIDocuments = FindObjectsByType<UIDocument>(FindObjectsSortMode.None);
- foreach (var doc in allUIDocuments)
- {
- if (doc.panelSettings != null && doc != uiDoc)
- {
- uiDoc.panelSettings = doc.panelSettings;
- return;
- }
- }
- #if UNITY_EDITOR
- // If still no panel settings, try to find any PanelSettings asset using Editor API
- var panelSettingsGuids = UnityEditor.AssetDatabase.FindAssets("t:PanelSettings");
- if (panelSettingsGuids.Length > 0)
- {
- var path = UnityEditor.AssetDatabase.GUIDToAssetPath(panelSettingsGuids[0]);
- var settings = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.UIElements.PanelSettings>(path);
- if (settings != null)
- {
- uiDoc.panelSettings = settings;
- return;
- }
- }
- #endif
- Debug.LogWarning("⚠️ Could not assign Panel Settings to Character Stats UI. You may need to assign it manually.");
- }
- #endregion
- }
|