first commit
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class QuestLogUI : MonoBehaviour
|
||||
{
|
||||
public static QuestLogUI Instance { get; private set; }
|
||||
|
||||
public GameObject root;
|
||||
public RectTransform content;
|
||||
public Font uiFont;
|
||||
public Color titleColor = new Color(1f, 0.74f, 0.25f);
|
||||
public Color textColor = new Color(0.92f, 0.9f, 0.82f);
|
||||
public Color mutedColor = new Color(0.7f, 0.7f, 0.7f);
|
||||
public KeyCode toggleKey = KeyCode.J;
|
||||
|
||||
public bool IsOpen => root != null && root.activeSelf;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(this);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
root.SetActive(false);
|
||||
}
|
||||
|
||||
Subscribe();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Subscribe();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (QuestManager.Instance != null)
|
||||
{
|
||||
QuestManager.Instance.OnQuestsChanged -= Refresh;
|
||||
}
|
||||
}
|
||||
|
||||
private void Subscribe()
|
||||
{
|
||||
if (QuestManager.Instance != null)
|
||||
{
|
||||
QuestManager.Instance.OnQuestsChanged -= Refresh;
|
||||
QuestManager.Instance.OnQuestsChanged += Refresh;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(toggleKey))
|
||||
{
|
||||
Toggle();
|
||||
}
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
if (root == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool next = !root.activeSelf;
|
||||
root.SetActive(next);
|
||||
Cursor.lockState = next ? CursorLockMode.None : CursorLockMode.Locked;
|
||||
Cursor.visible = next;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClearContent();
|
||||
|
||||
if (QuestManager.Instance == null)
|
||||
{
|
||||
CreateText("QuestManager не найден", mutedColor, 16, FontStyle.Normal);
|
||||
return;
|
||||
}
|
||||
|
||||
CreateText("Активные", titleColor, 22, FontStyle.Bold);
|
||||
if (QuestManager.Instance.ActiveQuests.Count == 0)
|
||||
{
|
||||
CreateText("Нет активных квестов", mutedColor, 16, FontStyle.Normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (QuestState state in QuestManager.Instance.ActiveQuests)
|
||||
{
|
||||
CreateQuestBlock(state);
|
||||
}
|
||||
}
|
||||
|
||||
CreateText("Завершённые", titleColor, 22, FontStyle.Bold);
|
||||
if (QuestManager.Instance.CompletedQuests.Count == 0)
|
||||
{
|
||||
CreateText("Пока пусто", mutedColor, 16, FontStyle.Normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (QuestState state in QuestManager.Instance.CompletedQuests)
|
||||
{
|
||||
CreateQuestBlock(state);
|
||||
}
|
||||
}
|
||||
|
||||
if (QuestManager.Instance.FailedQuests.Count > 0)
|
||||
{
|
||||
CreateText("Проваленные", titleColor, 22, FontStyle.Bold);
|
||||
foreach (QuestState state in QuestManager.Instance.FailedQuests)
|
||||
{
|
||||
CreateQuestBlock(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateQuestBlock(QuestState state)
|
||||
{
|
||||
if (state == null || state.questData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QuestData quest = state.questData;
|
||||
CreateText(quest.questName, titleColor, 18, FontStyle.Bold);
|
||||
CreateText(quest.description, textColor, 15, FontStyle.Normal);
|
||||
CreateText($"Статус: {state.status}", mutedColor, 14, FontStyle.Normal);
|
||||
|
||||
for (int i = 0; i < quest.goals.Count; i++)
|
||||
{
|
||||
QuestGoal goal = quest.goals[i];
|
||||
CreateText($"{goal.GetDisplayName()} {state.GetProgress(i)}/{goal.requiredAmount}", textColor, 15, FontStyle.Normal);
|
||||
}
|
||||
|
||||
float percent = QuestManager.Instance.GetQuestCompletionPercent(state);
|
||||
CreateText($"{BuildProgressBar(percent)} {Mathf.RoundToInt(percent * 100f)}%", titleColor, 15, FontStyle.Normal);
|
||||
CreateSpacer(8f);
|
||||
}
|
||||
|
||||
private string BuildProgressBar(float percent)
|
||||
{
|
||||
const int length = 10;
|
||||
int filled = Mathf.RoundToInt(Mathf.Clamp01(percent) * length);
|
||||
return new string('█', filled) + new string('░', length - filled);
|
||||
}
|
||||
|
||||
private void ClearContent()
|
||||
{
|
||||
for (int i = content.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(content.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSpacer(float height)
|
||||
{
|
||||
GameObject spacer = new GameObject("Quest Log Spacer", typeof(RectTransform));
|
||||
spacer.transform.SetParent(content, false);
|
||||
spacer.GetComponent<RectTransform>().sizeDelta = new Vector2(0f, height);
|
||||
}
|
||||
|
||||
private void CreateText(string value, Color color, int size, FontStyle style)
|
||||
{
|
||||
GameObject line = new GameObject("Quest Log Text", typeof(RectTransform), typeof(Text));
|
||||
line.transform.SetParent(content, false);
|
||||
|
||||
Text text = line.GetComponent<Text>();
|
||||
text.font = uiFont != null ? uiFont : Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
text.fontSize = size;
|
||||
text.fontStyle = style;
|
||||
text.color = color;
|
||||
text.text = value;
|
||||
text.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
text.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
|
||||
RectTransform rect = line.GetComponent<RectTransform>();
|
||||
rect.sizeDelta = new Vector2(0f, Mathf.Max(size + 10f, EstimateHeight(value, size)));
|
||||
}
|
||||
|
||||
private float EstimateHeight(string value, int size)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return size + 8f;
|
||||
}
|
||||
|
||||
int lineCount = Mathf.Max(1, Mathf.CeilToInt(value.Length / 42f));
|
||||
return lineCount * (size + 8f);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user