using System.Collections; using UnityEngine; using UnityEngine.UI; public class DialogueManager : MonoBehaviour { public static DialogueManager Instance { get; private set; } [Header("UI")] public GameObject dialoguePanel; public Text speakerText; public Text npcText; public Transform responseContainer; public ScrollRect responseScrollRect; public GameObject responseButtonPrefab; public Text hintText; public Text statusText; [Header("Scene References")] public Inventory playerInventory; public SimplePlayerController playerController; [Header("Typewriter")] public float characterDelay = 0.025f; public bool IsDialogueActive { get; private set; } private DialogueNode currentNode; private string currentNpcLine; private Coroutine typewriterRoutine; private bool isTyping; private string overrideSpeakerName; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; if (dialoguePanel != null) dialoguePanel.SetActive(false); } private void Update() { if (!IsDialogueActive) return; if (isTyping && (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0))) SkipTypewriter(); if (Input.GetKeyDown(KeyCode.Escape)) EndDialogue(); } public void StartDialogue(DialogueNode startNode, string npcDisplayName = null) { if (IsDialogueActive || startNode == null) return; IsDialogueActive = true; overrideSpeakerName = npcDisplayName; if (dialoguePanel != null) dialoguePanel.SetActive(true); SetHint(string.Empty); SetStatus(string.Empty); if (playerController != null) playerController.SetInputEnabled(false); else { Cursor.visible = true; Cursor.lockState = CursorLockMode.None; } ShowNode(startNode); } public void ShowNode(DialogueNode node) { if (node == null) { EndDialogue(); return; } currentNode = node; currentNpcLine = string.IsNullOrEmpty(node.npcLine) ? string.Empty : node.npcLine; if (speakerText != null) { string speaker = !string.IsNullOrEmpty(node.speakerName) ? node.speakerName : overrideSpeakerName; speakerText.text = string.IsNullOrEmpty(speaker) ? "NPC" : speaker; } ClearResponses(); if (typewriterRoutine != null) StopCoroutine(typewriterRoutine); typewriterRoutine = StartCoroutine(TypeLine(currentNpcLine)); } public void EndDialogue() { if (!IsDialogueActive) return; if (typewriterRoutine != null) { StopCoroutine(typewriterRoutine); typewriterRoutine = null; } isTyping = false; currentNode = null; ClearResponses(); if (dialoguePanel != null) dialoguePanel.SetActive(false); if (playerController != null) playerController.SetInputEnabled(true); else { Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } IsDialogueActive = false; SetStatus("Диалог завершён"); } public void OnResponseSelected(DialogueResponse response) { if (response == null) { EndDialogue(); return; } if (isTyping) { SkipTypewriter(); return; } if (!CheckRequirements(response)) { string requiredName = response.requiredItem != null ? response.requiredItem.itemName : "предмет"; SetStatus(!string.IsNullOrEmpty(response.unavailableText) ? response.unavailableText : "Нужен предмет: " + requiredName); return; } ApplyResponseEffects(response); if (response.endsDialogue || response.nextNode == null) EndDialogue(); else ShowNode(response.nextNode); } public void CreateResponseButton(DialogueResponse response, bool interactable, string buttonText) { if (responseContainer == null) return; GameObject buttonObject = responseButtonPrefab != null ? Instantiate(responseButtonPrefab, responseContainer) : CreateFallbackButton(responseContainer); buttonObject.name = interactable ? "ResponseButton" : "ResponseButton_Disabled"; buttonObject.SetActive(true); Text label = buttonObject.GetComponentInChildren(true); if (label != null) { label.text = buttonText; label.color = interactable ? Color.white : new Color(0.68f, 0.7f, 0.73f, 1f); } Button button = buttonObject.GetComponent