using UnityEngine; using UnityEngine.InputSystem; /// /// Интерактивная сюжетная записка в 3D мире. /// Игрок может подойти, увидеть подсказку и нажать [E] для открытия полноэкранного документа. /// public class NotePickup : MonoBehaviour { [Header("Настройки кода лифта")] [Tooltip("Порядковый номер в коде: 0 = 1-я цифра, 1 = 2-я цифра, 2 = 3-я цифра, 3 = 4-я цифра")] public int digitPosition = 0; [Header("Сюжетное описание")] public string noteTitle = "ЗАПИСКА ИССЛЕДОВАТЕЛЯ"; public string sectorName = "СЕКТОР АРХИВА"; [TextArea(3, 8)] public string storyText = "Мы заблокировали лифт в нижний уровень, чтобы задержать биомассу. Если кто-то выжил, введите код в терминал..."; [Header("Дистанция взаимодействия")] public float interactionDistance = 3.6f; [Header("Визуальное покачивание и свечение")] public bool animateHover = true; public float hoverSpeed = 2.0f; public float hoverHeight = 0.05f; private Vector3 initialPos; private static Transform cachedPlayerTransform; private void Start() { initialPos = transform.position; LocatePlayer(); var col = GetComponent(); if (col == null) { var sc = gameObject.AddComponent(); sc.isTrigger = true; sc.radius = interactionDistance; } } private Transform LocatePlayer() { if (cachedPlayerTransform != null) return cachedPlayerTransform; var pm = Object.FindAnyObjectByType(); if (pm != null) { cachedPlayerTransform = pm.transform; return cachedPlayerTransform; } var ph = Object.FindAnyObjectByType(); if (ph != null) { cachedPlayerTransform = ph.transform; return cachedPlayerTransform; } var pTag = GameObject.FindWithTag("Player"); if (pTag != null) { cachedPlayerTransform = pTag.transform; return cachedPlayerTransform; } var pName = GameObject.Find("Player"); if (pName != null) { cachedPlayerTransform = pName.transform; return cachedPlayerTransform; } if (Camera.main != null) { return Camera.main.transform; } return null; } private void Update() { if (animateHover) { float newY = initialPos.y + Mathf.Sin(Time.time * hoverSpeed) * hoverHeight; transform.position = new Vector3(initialPos.x, newY, initialPos.z); } if (NoteViewerUI.Instance != null && NoteViewerUI.Instance.IsOpen) return; if (Time.timeScale == 0f) return; Transform player = LocatePlayer(); if (player == null) return; float dist3D = Vector3.Distance(transform.position, player.position); float distXZ = Vector2.Distance(new Vector2(transform.position.x, transform.position.z), new Vector2(player.position.x, player.position.z)); bool inRange = dist3D <= interactionDistance || distXZ <= (interactionDistance * 0.9f); if (inRange) { if (CheckInteractInput()) { Interact(); } } } private void OnTriggerStay(Collider other) { if (NoteViewerUI.Instance != null && NoteViewerUI.Instance.IsOpen) return; if (Time.timeScale == 0f) return; if (other.CompareTag("Player") || other.GetComponentInParent() != null) { if (CheckInteractInput()) { Interact(); } } } private bool CheckInteractInput() { var keyboard = Keyboard.current; if (keyboard != null) { if (keyboard.eKey.wasPressedThisFrame || keyboard.fKey.wasPressedThisFrame || keyboard.enterKey.wasPressedThisFrame) { return true; } } #if ENABLE_LEGACY_INPUT_MANAGER if (Input.GetKeyDown(KeyCode.E) || Input.GetKeyDown(KeyCode.F) || Input.GetKeyDown(KeyCode.Return)) { return true; } #endif return false; } public void Interact() { int digit = 0; if (LevelCodeManager.Instance != null) { digit = LevelCodeManager.Instance.GetDigit(digitPosition); } if (NoteViewerUI.Instance != null) { NoteViewerUI.Instance.OpenNote(digitPosition, digit, sectorName, noteTitle, storyText); } else { Debug.LogError("[NotePickup] NoteViewerUI.Instance is NULL!"); } } }