using UnityEngine; using System.Collections; using Player; // Подключаем для доступа к PlayerController [RequireComponent(typeof(Outline))] public class InspectableObject : MonoBehaviour, IInteractable { [Header("Настройки Осмотра")] [Tooltip("Точка перед камерой, куда будет перемещаться объект. Если пусто, будет рассчитано автоматически.")] [SerializeField] private Transform inspectPoint; [Tooltip("Дополнительное смещение позиции объекта в режиме осмотра.")] [SerializeField] private Vector3 positionOffset = Vector3.zero; [Tooltip("Дополнительное вращение объекта в режиме осмотра (в градусах).")] [SerializeField] private Vector3 rotationOffset = Vector3.zero; [Tooltip("Скорость анимации приближения и отдаления.")] [SerializeField] private float animationSpeed = 8f; [Tooltip("Время, которое объект будет находиться перед камерой.")] [SerializeField] private float holdDuration = 3f; [Tooltip("Звук, проигрываемый при начале осмотра.")] [SerializeField] private AudioClip inspectSound; [Tooltip("Текст подсказки для взаимодействия.")] [SerializeField] private string description = "Осмотреть"; private bool _isInspecting = false; private Vector3 _originalPosition; private Quaternion _originalRotation; private Transform _originalParent; private PlayerController _playerController; private AudioSource _audioSource; void Start() { _playerController = FindObjectOfType(); _audioSource = GetComponent(); if (_audioSource == null) { _audioSource = gameObject.AddComponent(); } if (inspectPoint == null) { var mainCamera = Camera.main; if (mainCamera != null) { GameObject generatedPoint = new GameObject($"{name}_InspectPoint"); generatedPoint.transform.SetParent(mainCamera.transform); generatedPoint.transform.localPosition = new Vector3(0, 0, 0.8f); generatedPoint.transform.localRotation = Quaternion.identity; inspectPoint = generatedPoint.transform; } else { Debug.LogError("Камера с тэгом 'MainCamera' не найдена! Осмотр объектов может работать некорректно.", this); } } } public string GetDescription() { return _isInspecting ? "" : description; } public void Interact() { if (_isInspecting || _playerController == null || inspectPoint == null) { return; } StartCoroutine(InspectRoutine()); } private IEnumerator InspectRoutine() { _isInspecting = true; _playerController.inputLocked = true; _originalPosition = transform.position; _originalRotation = transform.rotation; _originalParent = transform.parent; transform.SetParent(null); if (inspectSound != null) { _audioSource.PlayOneShot(inspectSound); } // *** ГЛАВНОЕ ИЗМЕНЕНИЕ: Рассчитываем целевую позицию и поворот с учетом смещений *** Vector3 targetPosition = inspectPoint.position + inspectPoint.TransformDirection(positionOffset); Quaternion targetRotation = inspectPoint.rotation * Quaternion.Euler(rotationOffset); // --- Фаза 1: Приближение к камере --- float journey = 0f; while (journey < 1f) { journey += Time.deltaTime * animationSpeed; transform.position = Vector3.Lerp(_originalPosition, targetPosition, journey); transform.rotation = Quaternion.Slerp(_originalRotation, targetRotation, journey); yield return null; } transform.position = targetPosition; transform.rotation = targetRotation; // --- Фаза 2: Удержание перед камерой --- yield return new WaitForSeconds(holdDuration); // --- Фаза 3: Возвращение на место --- Vector3 currentPos = transform.position; Quaternion currentRot = transform.rotation; journey = 0f; while (journey < 1f) { journey += Time.deltaTime * animationSpeed; transform.position = Vector3.Lerp(currentPos, _originalPosition, journey); transform.rotation = Quaternion.Slerp(currentRot, _originalRotation, journey); yield return null; } // --- Фаза 4: Восстановление состояния --- transform.position = _originalPosition; transform.rotation = _originalRotation; transform.SetParent(_originalParent); _playerController.inputLocked = false; _isInspecting = false; } }