using System.Text; using UnityEngine; using UnityEngine.UI; public class TalentTooltipUI : MonoBehaviour { public RectTransform panelRoot; public CanvasGroup canvasGroup; public Text titleText; public Text descriptionText; public Text costText; public Text modifiersText; public Text requirementsText; public Text statusText; public Text reasonText; public Vector2 screenOffset = new Vector2(22f, -18f); private bool visible; private void Awake() { if (panelRoot == null) { panelRoot = transform as RectTransform; } if (canvasGroup == null) { canvasGroup = GetComponent(); } Hide(); } private void Update() { if (!visible || panelRoot == null) { return; } panelRoot.position = Input.mousePosition + new Vector3(screenOffset.x, screenOffset.y, 0f); } public void Show(TalentData talent, TalentManager manager) { if (talent == null) { return; } if (titleText != null) { titleText.text = talent.displayName; } if (descriptionText != null) { descriptionText.text = talent.description; } if (costText != null) { costText.text = $"Стоимость: {talent.cost}"; } if (modifiersText != null) { modifiersText.text = BuildModifiersText(talent); } if (requirementsText != null) { requirementsText.text = BuildRequirementsText(talent); } if (statusText != null) { statusText.text = $"Статус: {BuildStatusText(talent, manager)}"; } if (reasonText != null) { reasonText.text = manager != null ? manager.GetBlockingReason(talent) : string.Empty; } visible = true; if (canvasGroup != null) { canvasGroup.alpha = 1f; canvasGroup.blocksRaycasts = false; } if (panelRoot != null) { panelRoot.gameObject.SetActive(true); panelRoot.SetAsLastSibling(); } } public void Hide() { visible = false; if (canvasGroup != null) { canvasGroup.alpha = 0f; canvasGroup.blocksRaycasts = false; } if (panelRoot != null) { panelRoot.gameObject.SetActive(false); } } private string BuildModifiersText(TalentData talent) { if (talent.modifiers == null || talent.modifiers.Length == 0) { return "Модификаторы: нет"; } StringBuilder builder = new StringBuilder(); builder.AppendLine("Модификаторы:"); for (int i = 0; i < talent.modifiers.Length; i++) { builder.AppendLine(FormatModifier(talent.modifiers[i])); } return builder.ToString().TrimEnd(); } private string BuildRequirementsText(TalentData talent) { if (talent.prerequisites == null || talent.prerequisites.Length == 0) { return "Требования: нет"; } StringBuilder builder = new StringBuilder("Требования: "); for (int i = 0; i < talent.prerequisites.Length; i++) { if (i > 0) { builder.Append(", "); } TalentData prerequisite = talent.prerequisites[i]; builder.Append(prerequisite != null ? prerequisite.displayName : "Missing"); } return builder.ToString(); } private string BuildStatusText(TalentData talent, TalentManager manager) { if (manager == null) { return "неизвестно"; } if (manager.IsLearned(talent)) { return "изучено"; } if (manager.CanLearn(talent)) { return "доступно"; } if (!manager.ArePrerequisitesLearned(talent)) { return "заблокировано"; } return "не хватает очков"; } private string FormatModifier(StatModifier modifier) { string statName = FormatStatName(modifier.statType); string valueText; if (modifier.modifierType == ModifierType.PercentAdd || modifier.modifierType == ModifierType.PercentMultiply) { valueText = FormatSignedNumber(modifier.value * 100f) + "%"; } else if (modifier.statType == StatType.AbilityCooldownReduction || modifier.statType == StatType.CriticalChance) { valueText = FormatSignedNumber(modifier.value) + "%"; } else { valueText = FormatSignedNumber(modifier.value); } return $"{statName} {valueText}"; } private string FormatStatName(StatType statType) { switch (statType) { case StatType.MaxHealth: return "Max Health"; case StatType.MaxMana: return "Max Mana"; case StatType.Damage: return "Damage"; case StatType.MoveSpeed: return "Move Speed"; case StatType.AbilityCooldownReduction: return "Cooldown Reduction"; case StatType.CriticalChance: return "Critical Chance"; default: return statType.ToString(); } } private string FormatSignedNumber(float value) { string sign = value >= 0f ? "+" : string.Empty; return sign + value.ToString("0.##"); } }