using UnityEngine; using UnityEngine.UI; public class QuestTrackerUI : MonoBehaviour { public RectTransform content; public Text outputText; public Font uiFont; public Color titleColor = new Color(1f, 0.74f, 0.25f); public Color textColor = new Color(0.92f, 0.9f, 0.82f); private float refreshTimer; private string lastSignature; private void OnEnable() { Subscribe(); Refresh(); } private void Start() { Subscribe(); Refresh(); } private void OnDisable() { if (QuestManager.Instance != null) { QuestManager.Instance.OnQuestsChanged -= Refresh; } } private void Update() { refreshTimer -= Time.unscaledDeltaTime; if (refreshTimer > 0f) { return; } refreshTimer = 0.25f; Subscribe(); string signature = BuildSignature(); if (signature != lastSignature) { lastSignature = signature; Refresh(); } } private void Subscribe() { if (QuestManager.Instance != null) { QuestManager.Instance.OnQuestsChanged -= Refresh; QuestManager.Instance.OnQuestsChanged += Refresh; } } public void Refresh() { if (outputText != null) { outputText.text = BuildDisplayText(); return; } if (content == null) { return; } ClearContent(); if (QuestManager.Instance == null || QuestManager.Instance.ActiveQuests.Count == 0) { CreateLine("Нет активных квестов", textColor, 15); return; } foreach (QuestState state in QuestManager.Instance.ActiveQuests) { if (state.questData == null) { continue; } CreateLine(state.questData.questName, titleColor, 16); for (int i = 0; i < state.questData.goals.Count; i++) { QuestGoal goal = state.questData.goals[i]; CreateLine($"{goal.GetDisplayName()} {state.GetProgress(i)}/{goal.requiredAmount}", textColor, 14); } } } private string BuildDisplayText() { if (QuestManager.Instance == null || QuestManager.Instance.ActiveQuests.Count == 0) { return "Нет активных квестов"; } System.Text.StringBuilder builder = new System.Text.StringBuilder(); foreach (QuestState state in QuestManager.Instance.ActiveQuests) { if (state.questData == null) { continue; } builder.AppendLine(state.questData.questName); for (int i = 0; i < state.questData.goals.Count; i++) { QuestGoal goal = state.questData.goals[i]; builder.Append(" ") .Append(goal.GetDisplayName()) .Append(' ') .Append(state.GetProgress(i)) .Append('/') .Append(goal.requiredAmount) .AppendLine(); } } return builder.Length > 0 ? builder.ToString().TrimEnd() : "Нет активных квестов"; } private string BuildSignature() { if (QuestManager.Instance == null) { return "quests:null"; } System.Text.StringBuilder builder = new System.Text.StringBuilder(); foreach (QuestState state in QuestManager.Instance.ActiveQuests) { if (state.questData == null) { continue; } builder.Append(state.questData.questId).Append(':').Append(state.status).Append(':'); for (int i = 0; i < state.goalProgress.Count; i++) { builder.Append(state.goalProgress[i]).Append(','); } builder.Append('|'); } return builder.ToString(); } private void ClearContent() { for (int i = content.childCount - 1; i >= 0; i--) { Destroy(content.GetChild(i).gameObject); } } private void CreateLine(string value, Color color, int size) { GameObject line = new GameObject("Quest Tracker Line", typeof(RectTransform), typeof(Text)); line.transform.SetParent(content, false); Text text = line.GetComponent(); text.font = uiFont != null ? uiFont : Resources.GetBuiltinResource("Arial.ttf"); text.fontSize = size; text.color = color; text.text = value; RectTransform rect = line.GetComponent(); rect.sizeDelta = new Vector2(0f, size + 8f); } }