Kursach_StealthAction/Assets/Scripts/NotePickup.cs

150 lines
4.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// Интерактивная сюжетная записка в 3D мире.
/// Игрок может подойти, увидеть подсказку и нажать [E] для открытия полноэкранного документа.
/// </summary>
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<Collider>();
if (col == null)
{
var sc = gameObject.AddComponent<SphereCollider>();
sc.isTrigger = true;
sc.radius = interactionDistance;
}
}
private Transform LocatePlayer()
{
if (cachedPlayerTransform != null) return cachedPlayerTransform;
var pm = Object.FindAnyObjectByType<PlayerMovement>();
if (pm != null) { cachedPlayerTransform = pm.transform; return cachedPlayerTransform; }
var ph = Object.FindAnyObjectByType<PlayerHealth>();
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<PlayerMovement>() != 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!");
}
}
}