|
@@ -1,6 +1,9 @@
|
|
|
|
|
+using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
|
using Unity.VisualScripting;
|
|
using Unity.VisualScripting;
|
|
|
using UnityEngine;
|
|
using UnityEngine;
|
|
|
|
|
+using UnityEngine.UIElements;
|
|
|
|
|
+using UnityEngine.AI;
|
|
|
|
|
|
|
|
public class PlayerDecisionController : MonoBehaviour
|
|
public class PlayerDecisionController : MonoBehaviour
|
|
|
{
|
|
{
|
|
@@ -22,6 +25,13 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
private bool isEnabled = true;
|
|
private bool isEnabled = true;
|
|
|
private List<TargetingLine> activeActionLines = new List<TargetingLine>();
|
|
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()
|
|
void Awake()
|
|
|
{
|
|
{
|
|
|
mainCamera = Camera.main;
|
|
mainCamera = Camera.main;
|
|
@@ -34,9 +44,24 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
|
|
|
|
|
void Start()
|
|
void Start()
|
|
|
{
|
|
{
|
|
|
-
|
|
|
|
|
InitializePlayerCharacters();
|
|
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)
|
|
|
|
|
+ {
|
|
|
|
|
+ Debug.Log("🔄 Refreshing stats after battle setup completion");
|
|
|
|
|
+ UpdateCharacterStatsDisplay(selectedCharacter);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Update()
|
|
void Update()
|
|
@@ -78,6 +103,12 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
{
|
|
{
|
|
|
if (!isEnabled) return;
|
|
if (!isEnabled) return;
|
|
|
|
|
|
|
|
|
|
+ // Toggle character stats panel with 'C' key
|
|
|
|
|
+ if (Input.GetKeyDown(KeyCode.C))
|
|
|
|
|
+ {
|
|
|
|
|
+ ToggleStatsPanel();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (Input.GetMouseButtonDown(0)) // Left click
|
|
if (Input.GetMouseButtonDown(0)) // Left click
|
|
|
{
|
|
{
|
|
|
HandleLeftClickDown();
|
|
HandleLeftClickDown();
|
|
@@ -102,10 +133,10 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
private bool IsInMoveTargetingMode()
|
|
private bool IsInMoveTargetingMode()
|
|
|
{
|
|
{
|
|
|
if (selectedCharacter == null) return false;
|
|
if (selectedCharacter == null) return false;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
var actionData = selectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
|
|
var actionData = selectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
|
|
|
- return actionData != null &&
|
|
|
|
|
- actionData.actionType == BattleActionType.Move &&
|
|
|
|
|
|
|
+ return actionData != null &&
|
|
|
|
|
+ actionData.actionType == BattleActionType.Move &&
|
|
|
actionData.state == ActionDecisionState.NoAction;
|
|
actionData.state == ActionDecisionState.NoAction;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -120,9 +151,12 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
selectedCharacter = clickedCharacter;
|
|
selectedCharacter = clickedCharacter;
|
|
|
isDragging = true;
|
|
isDragging = true;
|
|
|
dragStartPosition = clickedCharacter.transform.position;
|
|
dragStartPosition = clickedCharacter.transform.position;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
Debug.Log($"🖱️ Starting drag from character {clickedCharacter.CharacterName}");
|
|
Debug.Log($"🖱️ Starting drag from character {clickedCharacter.CharacterName}");
|
|
|
|
|
|
|
|
|
|
+ // Update character stats display if panel is visible
|
|
|
|
|
+ UpdateCharacterStatsDisplay(clickedCharacter);
|
|
|
|
|
+
|
|
|
// Clear any existing action lines before starting new targeting
|
|
// Clear any existing action lines before starting new targeting
|
|
|
ClearActionLineForCharacter(clickedCharacter);
|
|
ClearActionLineForCharacter(clickedCharacter);
|
|
|
|
|
|
|
@@ -168,7 +202,7 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
{
|
|
{
|
|
|
Vector3 mouseWorldPos = GetMouseWorldPosition();
|
|
Vector3 mouseWorldPos = GetMouseWorldPosition();
|
|
|
GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
|
|
GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Handle different cases based on current state
|
|
// Handle different cases based on current state
|
|
|
if (isDragging && selectedCharacter != null)
|
|
if (isDragging && selectedCharacter != null)
|
|
|
{
|
|
{
|
|
@@ -181,22 +215,22 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
|
|
selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
|
|
|
Debug.Log($"⚔️ Attack target set for {selectedCharacter.CharacterName}");
|
|
Debug.Log($"⚔️ Attack target set for {selectedCharacter.CharacterName}");
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
// Check if user actually dragged (minimum distance threshold) OR if we're in action wheel move mode
|
|
// Check if user actually dragged (minimum distance threshold) OR if we're in action wheel move mode
|
|
|
float dragDistance = Vector3.Distance(dragStartPosition, mouseWorldPos);
|
|
float dragDistance = Vector3.Distance(dragStartPosition, mouseWorldPos);
|
|
|
const float minDragDistance = 0.5f; // Minimum distance to consider it a drag vs click
|
|
const float minDragDistance = 0.5f; // Minimum distance to consider it a drag vs click
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
bool isActionWheelMove = IsInMoveTargetingMode();
|
|
bool isActionWheelMove = IsInMoveTargetingMode();
|
|
|
bool isDragMove = dragDistance > minDragDistance;
|
|
bool isDragMove = dragDistance > minDragDistance;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (isActionWheelMove || isDragMove)
|
|
if (isActionWheelMove || isDragMove)
|
|
|
{
|
|
{
|
|
|
// Move target selected
|
|
// Move target selected
|
|
|
selectedCharacter.actionData.SetMoveTarget(mouseWorldPos);
|
|
selectedCharacter.actionData.SetMoveTarget(mouseWorldPos);
|
|
|
UpdateEnhancedActionData(selectedCharacter, BattleActionType.Move, null, mouseWorldPos);
|
|
UpdateEnhancedActionData(selectedCharacter, BattleActionType.Move, null, mouseWorldPos);
|
|
|
selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
|
|
selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (isActionWheelMove)
|
|
if (isActionWheelMove)
|
|
|
{
|
|
{
|
|
|
Debug.Log($"👟 Move target set for {selectedCharacter.CharacterName} (action wheel mode)");
|
|
Debug.Log($"👟 Move target set for {selectedCharacter.CharacterName} (action wheel mode)");
|
|
@@ -277,7 +311,6 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
// Raycast against a ground plane or existing colliders
|
|
// Raycast against a ground plane or existing colliders
|
|
|
if (Physics.Raycast(ray, out hit, 200f))
|
|
if (Physics.Raycast(ray, out hit, 200f))
|
|
|
{
|
|
{
|
|
|
- Debug.Log($"🌍 Mouse world position: {hit.point} (hit: {hit.collider.gameObject.name})");
|
|
|
|
|
return hit.point;
|
|
return hit.point;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -286,11 +319,9 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
if (groundPlane.Raycast(ray, out float distance))
|
|
if (groundPlane.Raycast(ray, out float distance))
|
|
|
{
|
|
{
|
|
|
Vector3 position = ray.GetPoint(distance);
|
|
Vector3 position = ray.GetPoint(distance);
|
|
|
- Debug.Log($"🌍 Mouse world position (fallback plane): {position}");
|
|
|
|
|
return position;
|
|
return position;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Debug.Log($"❌ Could not determine mouse world position");
|
|
|
|
|
return Vector3.zero;
|
|
return Vector3.zero;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -330,7 +361,7 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
Debug.Log($"🎯 Enemy detected: {hit.collider.gameObject.name} on layer {hit.collider.gameObject.layer}");
|
|
Debug.Log($"🎯 Enemy detected: {hit.collider.gameObject.name} on layer {hit.collider.gameObject.layer}");
|
|
|
return hit.collider.gameObject;
|
|
return hit.collider.gameObject;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Debug: Check what we're hitting without layer mask
|
|
// Debug: Check what we're hitting without layer mask
|
|
|
if (Physics.Raycast(ray, out hit, 200f))
|
|
if (Physics.Raycast(ray, out hit, 200f))
|
|
|
{
|
|
{
|
|
@@ -340,7 +371,7 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
{
|
|
{
|
|
|
Debug.Log($"❌ No raycast hit detected at mouse position");
|
|
Debug.Log($"❌ No raycast hit detected at mouse position");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -536,6 +567,12 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
selectedCharacter = character;
|
|
selectedCharacter = character;
|
|
|
dragStartPosition = character.transform.position;
|
|
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
|
|
// Store the action type for later reference
|
|
|
var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
|
|
var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
|
|
|
if (enhancedData == null)
|
|
if (enhancedData == null)
|
|
@@ -548,7 +585,7 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
|
|
|
|
|
// Start targeting mode - user needs to click to set target
|
|
// Start targeting mode - user needs to click to set target
|
|
|
isDragging = true;
|
|
isDragging = true;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Clear any existing action lines before starting new targeting
|
|
// Clear any existing action lines before starting new targeting
|
|
|
ClearActionLineForCharacter(character);
|
|
ClearActionLineForCharacter(character);
|
|
|
|
|
|
|
@@ -575,4 +612,321 @@ public class PlayerDecisionController : MonoBehaviour
|
|
|
Debug.Log("❌ Targeting cancelled");
|
|
Debug.Log("❌ Targeting cancelled");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ #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;
|
|
|
|
|
+ Debug.Log("✓ Character Stats UI: UXML asset applied");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 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)
|
|
|
|
|
+ {
|
|
|
|
|
+ Debug.LogWarning("Stats panel not found, creating fallback");
|
|
|
|
|
+ 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);
|
|
|
|
|
+ Debug.Log("✓ Character Stats UI: USS stylesheet applied");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Hide panel initially
|
|
|
|
|
+ if (statsPanel != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ statsPanel.style.display = DisplayStyle.None;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Debug.Log("Character Stats UI setup complete");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ 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)
|
|
|
|
|
+ {
|
|
|
|
|
+ Debug.Log("🔄 Force refreshing character stats display");
|
|
|
|
|
+ UpdateCharacterStatsDisplay(selectedCharacter);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void ToggleStatsPanel()
|
|
|
|
|
+ {
|
|
|
|
|
+ if (statsPanel == null) return;
|
|
|
|
|
+
|
|
|
|
|
+ isStatsPanelVisible = !isStatsPanelVisible;
|
|
|
|
|
+ statsPanel.style.display = isStatsPanelVisible ? DisplayStyle.Flex : DisplayStyle.None;
|
|
|
|
|
+
|
|
|
|
|
+ Debug.Log($"📊 Character stats panel: {(isStatsPanelVisible ? "Shown" : "Hidden")}");
|
|
|
|
|
+
|
|
|
|
|
+ // Update display when showing panel
|
|
|
|
|
+ if (isStatsPanelVisible && selectedCharacter != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ UpdateCharacterStatsDisplay(selectedCharacter);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void UpdateCharacterStatsDisplay(Character character)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (statsPanel == null || !isStatsPanelVisible) return;
|
|
|
|
|
+
|
|
|
|
|
+ Debug.Log($"🔄 Updating stats display for {character.CharacterName}");
|
|
|
|
|
+ Debug.Log($" Character component reference: {character.GetInstanceID()}");
|
|
|
|
|
+ Debug.Log($" Character object name: {character.gameObject.name}");
|
|
|
|
|
+ Debug.Log($" Character stats: STR:{character.Strength} DEX:{character.Dexterity} CON:{character.Constitution} WIS:{character.Wisdom} PER:{character.Perception}");
|
|
|
|
|
+ Debug.Log($" Movement Speed: {character.MovementSpeed}");
|
|
|
|
|
+
|
|
|
|
|
+ // 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}");
|
|
|
|
|
+
|
|
|
|
|
+ Debug.Log($"📊 Updated stats display for {character.CharacterName}");
|
|
|
|
|
+ }
|
|
|
|
|
+ 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;
|
|
|
|
|
+ Debug.Log("✓ Character Stats UI: Applied MainSettings from Resources");
|
|
|
|
|
+ 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;
|
|
|
|
|
+ Debug.Log("✓ Character Stats UI: Panel Settings assigned from TravelUI");
|
|
|
|
|
+ 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;
|
|
|
|
|
+ Debug.Log("✓ Character Stats UI: Panel Settings assigned from MainTeamSelectScript");
|
|
|
|
|
+ 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;
|
|
|
|
|
+ Debug.Log($"✓ Character Stats UI: Panel Settings assigned from {doc.gameObject.name}");
|
|
|
|
|
+ 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;
|
|
|
|
|
+ Debug.Log($"✓ Character Stats UI: Panel Settings auto-assigned: {settings.name}");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+ Debug.LogWarning("⚠️ Could not assign Panel Settings to Character Stats UI. You may need to assign it manually.");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #endregion
|
|
|
}
|
|
}
|