using UnityEngine;

public class ObjectPickup : MonoBehaviour
{
    [Header("Настройки удержания")]
    public Transform holdPoint;       // Точка удержания объекта
    public LayerMask pickupLayer;     // Слой подбираемых объектов
    public float pickupRange = 3f;    // Дистанция, на которой можно подобрать объект
    public float maxPickupMass = 10f; // Максимальная масса подбираемого объекта

    [Header("Настройки броска")]
    public float throwForce = 10f;    // Сила броска

    private GameObject heldObject;            // Удерживаемый объект
    private Rigidbody heldObjectRb;           // Rigidbody удерживаемого объекта
    private FixedJoint holdJoint;      // Соединение для удержания объекта

    void Update()
    {
        // Проверка нажатия кнопок мыши
        if (Input.GetMouseButtonDown(0))
        {
            if (heldObject == null)
            {
                // Попытка подобрать объект
                TryPickupObject();
            }
            else
            {
                // Бросок удерживаемого объекта
                ThrowObject();
            }
        }
        else if (Input.GetMouseButtonDown(1))
        {
            // Отпускание удерживаемого объекта
            ReleaseObject();
        }
    }

    void TryPickupObject()
    {
        // Создание луча из камеры в направлении курсора мыши
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        // Проверка попадания луча в объект на заданном слое
        if (Physics.Raycast(ray, out hit, pickupRange, pickupLayer))
        {
            Rigidbody rb = hit.rigidbody;

            // Проверка, что объект имеет Rigidbody, не кинематический и масса меньше максимальной
            if (rb != null && !rb.isKinematic && rb.mass <= maxPickupMass)
            {
                PickupObject(rb);
            }
        }
    }

    void PickupObject(Rigidbody rb)
    {
        // Сохранение удерживаемого объекта и его Rigidbody
        heldObject = rb.gameObject;
        heldObjectRb = rb;

        // Замораживание вращения объекта для стабильности
        heldObjectRb.freezeRotation = true;

        holdJoint = holdPoint.gameObject.AddComponent<FixedJoint>();
        holdJoint.connectedBody = heldObjectRb;

        // Плавное перемещение объекта к точке удержания
        StartCoroutine(SmoothlyMoveObjectToHoldPoint());
    }

    System.Collections.IEnumerator SmoothlyMoveObjectToHoldPoint()
    {
        float elapsedTime = 0f;
        float moveDuration = 0.1f; // Длительность перемещения
        Vector3 startPosition = heldObjectRb.position;

        while (elapsedTime < moveDuration)
        {
            elapsedTime += Time.deltaTime;

            // Вычисление новой позиции с помощью интерполяции
            Vector3 newPosition = Vector3.Lerp(startPosition, holdPoint.position, elapsedTime / moveDuration);

            // Перемещение объекта с помощью MovePosition для корректной работы физики
            heldObjectRb.MovePosition(newPosition);

            yield return null;
        }
    }

    void ReleaseObject()
    {
        if (heldObject != null)
        {
            // Удаление соединения
            if (holdJoint != null)
            {
                Destroy(holdJoint);
            }

            // Размораживание вращения объекта
            heldObjectRb.freezeRotation = false;
            // Сброс переменных
            heldObject = null;
            heldObjectRb = null;
            holdJoint = null;
        }
    }

    void ThrowObject()
    {
        if (heldObject != null)
        {
            // Удаление соединения и размораживание вращения
            if (holdJoint != null)
            {
                Destroy(holdJoint);
            }
            heldObjectRb.freezeRotation = false;

            // Сохранение ссылки на Rigidbody перед сбросом переменных
            Rigidbody rb = heldObjectRb;

            // Сброс переменных
            heldObject = null;
            heldObjectRb = null;
            holdJoint = null;

            // Применение силы броска в направлении камеры
            Vector3 throwDirection = Camera.main.transform.forward;
            rb.AddForce(throwDirection * throwForce, ForceMode.VelocityChange);
        }
    }
}
make FixedJoint descriptions in Russian