I want to make a FPS Object Grab - Drop System but I don't know how can I do it properly

I want to make a system where items can be picked up, carried and dropped by holding them in front of the camera like in many games, I have a prototype but it doesn’t work fully.
For example, when I pick up an object and look towards the ground, the object interacts with the colliders and applies force to the character (even though there is the Rigidbody > Exclude Layers turned on for the Player).
But if I turn off the colliders, this time it passes through other objects, a situation I don’t want to happen. When I pick up a Grabable object, I don’t want it to apply any force, but I want the collider to be on (except Player’s collider) and when I let it go, it falls where it is.
Also, when I move an object, I want it to move smoothly, but now it moves with a blurry image.
I am open to all your advice :expressionless:

  • A grabable object:

using System.Collections;
using System.Collections.Generic;
using MyScripts;
using UnityEngine;

public class ObjectGrabbable : MonoBehaviour, IGrabbable
{
    private Rigidbody objectRigidbody;
    private Transform objectGrabPointTransform;
    const int cubeMass = 1;
    const float cubeAngularDrag = 0.05f;

    private void Awake()
    {
        objectRigidbody = GetComponent<Rigidbody>();
    }

    public void Grab(Transform objectGrabPointTransform)
    {
        this.objectGrabPointTransform = objectGrabPointTransform;
        objectRigidbody.useGravity = false;
        objectRigidbody.mass = 0.01f;
        objectRigidbody.angularDrag = cubeAngularDrag;
        objectRigidbody.detectCollisions = false;

    }

    public void Drop()
    {   
        this.objectGrabPointTransform = null;
        objectRigidbody.useGravity = true;
        objectRigidbody.mass = cubeMass;
        objectRigidbody.detectCollisions = true;
    }

    private void FixedUpdate()
    {
        if (objectGrabPointTransform != null)
        {
            float lerpSpeed = 10f;
            Vector3 newPosition = Vector3.Slerp(
                transform.position,
                objectGrabPointTransform.position,
                Time.deltaTime * lerpSpeed
            );
            objectRigidbody.MovePosition(newPosition);
        }
    }
}
  • Player:
using System.Collections;
using System.Collections.Generic;
using MyScripts;
using Sirenix.OdinInspector;
using UnityEngine;

public class PlayerPickUpDrop : MonoBehaviour
{
    [SerializeField]
    private Transform playerCameraTransform;

    [Title("Where to place the grabbable object:")]
    [SerializeField]
    private Transform objectGrabPointTransform;

    [SerializeField]
    private LayerMask pickUpLayerMask;

    private IGrabbable objectGrabbable;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            Debug.Log("E Pressed");
            if (objectGrabbable == null)
            {
                // Not carrying an object, try to grab
                 Debug.Log("Try Pickup Grabbable");
                float pickUpDistance = 4f;
                if (
                    Physics.Raycast(
                        playerCameraTransform.position,
                        playerCameraTransform.forward,
                        out RaycastHit raycastHit,
                        pickUpDistance,
                        pickUpLayerMask
                    )
                )
                {
                    Debug.Log("Raycast Hit " + raycastHit.transform.gameObject);
                    if (raycastHit.transform.TryGetComponent(out objectGrabbable))
                    {
                        Debug.Log("Pickup Grabbable");
                        objectGrabbable.Grab(objectGrabPointTransform);
                    }
                }
            }   
            else
            {
                // Currently carrying something, drop
                 Debug.Log("Drop Grabbable " + objectGrabbable);
                objectGrabbable.Drop();
                objectGrabbable = null;
            }
        }
    }
}

The reason why your grabbed object isn’t smooth is because you’re using MovePosition on a non kinematic rigidbody. When using MovePosition interpolation only works on a kinematic rigidbody.

MovePosition also won’t be blocked by collisions and so it’s probably of no use to you.

A simple method for dragging a rigidbody around:

using UnityEngine;
public class ObjectGrabbable : MonoBehaviour
{
Rigidbody rb;

	void Start()
	{
		rb=GetComponent<Rigidbody>();
	}

	void OnMouseDrag()
	{
        Vector3 p=Camera.main.ScreenToWorldPoint(Input.mousePosition+Vector3.forward*3);
        rb.AddForce(p-transform.position-rb.velocity*0.2f,ForceMode.VelocityChange);
	}
}

The grabbed rigidbody will lag behind a little but you can improve it further by also adding the cursor’s velocity to the grab point.

How can add the cursor’s velocity to the grab point?

Also

How can I solve the problem that when the object hits any collider it will rotate (angularly)? Maybe by adding angularDrag, but how else?

Thank you.