Unity3D: How to move an object in relation with another object?

I have a physics enabled sphere in my scene and a character that i can move around using WASD. now what i want is that as soon as player hits the ball it should not be physics enabled anymore and move along with player as like the player is holding it in the hands.

What i have tried so far: i was able to do it but not at all perfect how i want it to be. i tried OnCollisionEnter to detect the collision, i made the sphere a child of the player, i used isKinematic = true as soon as collision is detected and i used Vector3.MoveTowards for the object to follow the position as the player.

I have attached two reference videos below Reference Clip(The style i am aiming for):RefrenceClip - YouTube

MyVersion(This is what i am able to do):MyVersion - YouTube

overall, if you watch the clips you can see how my version is very rigid, stucky, buggy, not so light weight feeling at all. Cut me a slack as well if i did anything way wrong, i started unity like just in the previous month.

This is my Player script through which i am controlling it all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MonoBehaviour
{
    public float MoveSpeed;
    [SerializeField]private Rigidbody playerRig;
    [SerializeField] private Rigidbody ballRig;
    [SerializeField] private GameObject Ball;
    [SerializeField] private GameObject heldObj;

    private bool isTouching = false;
    private Vector3 offset = new Vector3(0, 1, 3);


    private Vector3 force;
    public float jump;  
    private bool isGrounded = true;

    private void Start()
    {
        Ball = GameObject.FindGameObjectWithTag("Ball");
        ballRig.GetComponent<Rigidbody>();
        playerRig.GetComponent<Rigidbody>();
    }
    void Update()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        playerRig.velocity = new Vector3(x*MoveSpeed, playerRig.velocity.y,z*MoveSpeed);

        Vector3 vel = playerRig.velocity;
        vel.y = 0;
        
        if (vel.x != 0 || vel.z != 0) 
        {
         
            transform.forward = vel;
        }
       if(transform.position.y < -10)
        {
            GameOver();
        }

        ReleaseTheBall();


        if (isTouching == true)
        {
            
           ballRig.transform.position = Vector3.MoveTowards(ballRig.transform.position, playerRig.transform.position, 5f);
           
        }
    }
    void Jump()
    {           
        force = new Vector3(0, jump, 0);
        if (Input.GetKeyDown(KeyCode.Space) && isGrounded == true)
        {
            isGrounded = false;
            playerRig.AddForce(force, ForceMode.Impulse);          
        }
       
    }
    private void OnCollisionEnter(Collision collision)
    {
        
        if(collision.gameObject.tag == "Ball" && heldObj == null)
        {
            ballRig.isKinematic = true;
           // ballRig.constraints = RigidbodyConstraints.FreezeRotation;
            ballRig.transform.parent = playerRig.transform;
            isTouching = true;
            Debug.Log(" BALL PICKED UP AND MOVING ");
            heldObj = Ball;
        }
    }
    public void ReleaseTheBall()
    {
        if (Input.GetKeyDown(KeyCode.Space) && heldObj != null)
        {
            isTouching = false;
            heldObj = null;
            ballRig.transform.parent = null;
            //ballRig.constraints = RigidbodyConstraints.None;
            ballRig.isKinematic = false;

            //Vector3 forceDirection = new Vector3(playerRig.transform.position.x, 0, playerRig.transform.position.z);
            Vector3 rotationDirection = new Vector3(playerRig.transform.rotation.x, playerRig.transform.rotation.y, playerRig.transform.rotation.z);
            ballRig.AddForce(new Vector3(transform.position.x,0,transform.position.z) * 5, ForceMode.Impulse);
            ballRig.AddTorque(rotationDirection * 1);
            Debug.Log("BALL RELEASED");
           
           


        }
    }
    public void GameOver()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
  
}

i know there could be some very inefficient lines of code here, feel free to call out those lines as well. So, basically what i want is that i want my player to pick up the ball as soon as it hits it and the ball should move exactly like player as if he is holding the ball in his hands and when i hit the spacebar i want the ball to be released into the direction i am looking(this part is also very tricky for me), what i am trying to do is i want to do exactly like in the refrence clip. Thanks a lot in advance.

one more thing, when i stop pressing any key to move(WASD), my player transform keeps changing values up and down and it slightly starts moving. i mean when i dont press any key, it still kinda moves.

Hi @wonwoo2774 ,

first of all every time you’re dealing with Rigidbodies, you should keep related code in FixedUpdate, not Update. Do this and you should get rid of strange objects behavior.

BUT checking Input in FixedUpdate isn’t a good idea, so keep it in Update. (I have on mind the method relasing the ball).

If you need to keep a child of the player in the same relative position, try this:

if (isTouching == true)
{
        ballRig.transform.localPosition = offset;
}

It works fine, there is no need to use Vector3.MoveTowards(). Also it makes perfect use of the offset variable you’ve created earlier.

To relase ball in the direction the player is facing, you can simply use Transform.forward, like that:

ballRig.AddForce(transform.forward * 20, ForceMode.Impulse);

Also consider moving portions of your code to separate private methods, e.g. from Update (it’s a little messy).