using System; using System.Collections.Generic; using UnityEngine; public class NPC : MonoBehaviour { [Serializable] public class DialogueOption { public string playerReply; public string npcReply; public bool closeAfterSelection; public bool requiresAllNotes; public string unavailableReply; } [SerializeField] private string npcName = "Смотритель"; [SerializeField] private string openingLine = "Вы нашли что-нибудь интересное?"; [SerializeField] private List dialogueOptions = new List(); [SerializeField] private Renderer npcRenderer; [SerializeField] private Material defaultMaterial; [SerializeField] private Material highlightMaterial; private bool playerInRange; private bool hasRegisteredConversation; public string NPCName => npcName; public string OpeningLine => openingLine; public IReadOnlyList DialogueOptions => dialogueOptions; public void Configure( string characterName, string introLine, Renderer targetRenderer, Material baseMaterial, Material selectedMaterial, List options) { npcName = characterName; openingLine = introLine; npcRenderer = targetRenderer; defaultMaterial = baseMaterial; highlightMaterial = selectedMaterial; dialogueOptions = options ?? new List(); } private void Awake() { if (npcRenderer == null) { npcRenderer = GetComponentInChildren(); } if (defaultMaterial == null && npcRenderer != null) { defaultMaterial = npcRenderer.sharedMaterial; } SetHighlighted(false); } private void Update() { if (playerInRange && !GameUIState.IsAnyBlockingUIOpen && Input.GetKeyDown(KeyCode.E)) { Interact(); } } public void SetPlayerInRange(bool isInRange) { playerInRange = isInRange; SetHighlighted(isInRange); if (isInRange) { InteractionPromptUI.Instance?.ShowPrompt(this, "Нажмите E"); } else { InteractionPromptUI.Instance?.HidePrompt(this); } } public void Interact() { DialogueUI.Instance?.ShowDialogue(this); } public bool IsOptionAvailable(DialogueOption option) { if (option == null) { return false; } return !option.requiresAllNotes || (QuestManager.Instance != null && QuestManager.Instance.HasCollectedAllNotes); } public string GetOptionLabel(DialogueOption option) { if (option == null) { return string.Empty; } if (IsOptionAvailable(option)) { return option.playerReply; } var requiredNotes = QuestManager.Instance != null ? QuestManager.Instance.TotalNotes : 3; return $"{option.playerReply} (нужно {requiredNotes} записки)"; } public void SelectOption(DialogueOption option) { if (option == null) { return; } if (!IsOptionAvailable(option)) { var fallbackReply = string.IsNullOrWhiteSpace(option.unavailableReply) ? "Сначала найди все записки, потом мы продолжим этот разговор." : option.unavailableReply; DialogueUI.Instance?.ShowFollowUp(npcName, fallbackReply); return; } if (!hasRegisteredConversation) { hasRegisteredConversation = true; QuestManager.Instance?.NPCTalked(); } if (option.closeAfterSelection || string.IsNullOrWhiteSpace(option.npcReply)) { DialogueUI.Instance?.CloseDialogue(); return; } DialogueUI.Instance?.ShowFollowUp(npcName, option.npcReply); } private void SetHighlighted(bool highlighted) { if (npcRenderer == null) { return; } var targetMaterial = highlighted && highlightMaterial != null ? highlightMaterial : defaultMaterial; if (targetMaterial != null) { npcRenderer.material = targetMaterial; } } }