using UnityEngine; // Обязательно добавляем библиотеку новой системы ввода using UnityEngine.InputSystem; public class ObjectThrower : MonoBehaviour { [Header("Настройки подбора")] public float pickupRange = 3f; public Transform holdPosition; public LayerMask pickupLayer; [Header("Настройки броска")] public float chargeRate = 15f; public float maxThrowForce = 25f; private float currentThrowForce = 0f; private GameObject heldObject; private Rigidbody heldObjectRb; private Camera mainCamera; void Start() { mainCamera = Camera.main; } void Update() { if (Time.timeScale == 0f) return; // Защита от ошибок, если клавиатура не подключена if (Keyboard.current == null) return; // 1. Подбор и выбрасывание (вместо Input.GetKeyDown) if (Keyboard.current.eKey.wasPressedThisFrame) { if (heldObject == null) TryPickup(); else DropObject(); } // 2. Накопление силы и бросок if (heldObject != null) { // Пока клавиша зажата (вместо Input.GetKey) if (Keyboard.current.qKey.isPressed) { currentThrowForce += chargeRate * Time.deltaTime; currentThrowForce = Mathf.Clamp(currentThrowForce, 0, maxThrowForce); } // Когда клавишу отпустили (вместо Input.GetKeyUp) if (Keyboard.current.qKey.wasReleasedThisFrame) { ThrowObject(); } } } private void TryPickup() { // Создаем луч из камеры вперед Ray ray = new Ray(mainCamera.transform.position, mainCamera.transform.forward); // SphereCastAll пускает "толстый" луч радиусом 0.5 метра на длину 20 метров. // Он пробивает спину игрока и собирает ВСЕ объекты на пути в массив hits. RaycastHit[] hits = Physics.SphereCastAll(ray, 0.5f, 20f, pickupLayer); // Перебираем все, во что врезался наш толстый луч foreach (RaycastHit hit in hits) { // Ищем первый попавшийся предмет с нужным тегом if (hit.collider.CompareTag("Throwable")) { // Проверяем, стоит ли персонаж достаточно близко к предмету (pickupRange) float distanceToPlayer = Vector3.Distance(transform.position, hit.transform.position); if (distanceToPlayer <= pickupRange) { heldObject = hit.collider.gameObject; heldObjectRb = heldObject.GetComponent(); // Отключаем физику на время удержания heldObjectRb.isKinematic = true; heldObjectRb.useGravity = false; // Прикрепляем к руке heldObject.transform.SetParent(holdPosition); heldObject.transform.localPosition = Vector3.zero; heldObject.transform.localRotation = Quaternion.identity; // Как только успешно взяли предмет — прерываем цикл, чтобы не взять два сразу break; } } } } private void DropObject() { heldObject.transform.SetParent(null); heldObjectRb.isKinematic = false; heldObjectRb.useGravity = true; heldObject = null; heldObjectRb = null; currentThrowForce = 0f; } private void ThrowObject() { heldObject.transform.SetParent(null); heldObjectRb.isKinematic = false; heldObjectRb.useGravity = true; Ray ray = new Ray(mainCamera.transform.position, mainCamera.transform.forward); Vector3 targetPoint; if (Physics.Raycast(ray, out RaycastHit hit, 50f)) { targetPoint = hit.point; } else { targetPoint = ray.GetPoint(50f); } Vector3 throwDirection = (targetPoint - holdPosition.position).normalized; heldObjectRb.AddForce(throwDirection * currentThrowForce, ForceMode.Impulse); heldObject = null; heldObjectRb = null; currentThrowForce = 0f; } }