My script for grabbing and carrying objects in 2D doesn't work properly.

For the most part, I can pick up, carry and drop one object with no problems. However when I add another object with the same tag. It picks up the previous object.

I wish I could show a video, however the file size is too big.

Code:

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

public class ActionScript : MonoBehaviour
{
    private bool canHold;
    [SerializeField]
    private string grabbableTag;

    [SerializeField]
    private float distance;

    private GameObject items;
    public GameObject tempParent;
    public GameObject placePos;
    public bool isHolding;
    public LayerMask whatIsGrabbable;

    public Transform player;
    public Transform holdPos;
    public Transform rayPos2;



    void Start()
    {
        items = GameObject.FindWithTag("Grabbable");
        items.GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        PickAndDrop(); 
    }

    private void PickAndDrop()
    {
        {

            Vector2 checkPos = rayPos2.position;
            Physics2D.queriesStartInColliders = false;
            RaycastHit2D hit = Physics2D.Raycast(checkPos, transform.right * transform.localScale.x, distance, whatIsGrabbable);
            {
                if (hit.collider != null && items.tag == "Grabbable" && Input.GetKeyDown(KeyCode.E))
                {
                    canHold = true;
                    if (canHold)
                    {
                        isHolding = true;
                        items.GetComponent<Rigidbody2D>().isKinematic = true;
                        items.transform.eulerAngles = new Vector3(0, 0, 0);
                        items.transform.SetParent(holdPos);
                        items.transform.position = tempParent.transform.position;
                    }
                }
                else if (isHolding && Input.GetKeyDown(KeyCode.E))
                {
                    canHold = true;
                    isHolding = false;
                    items.GetComponent<Rigidbody2D>().isKinematic = false;
                    items.transform.eulerAngles = new Vector3(0, 0, 0);
                    items.transform.SetParent(null, true);
                    items.transform.position = placePos.transform.position;
                }
            }
               

        }
    }

    private void OnDrawGizmos()
    {
        Vector2 checkPos = rayPos2.position;
        Gizmos.color = Color.green;

        Gizmos.DrawLine(checkPos, (Vector2)checkPos + (Vector2)transform.right * transform.localScale.x * distance);
    }
}

This line in your start method items = GameObject.FindWithTag("Grabbable"); gets the first object with that tag in the scene, and forgets about the rest. You dont even need a reference to these, since your hit.collisionInfo from your raycast should handle this for you:


In here:

items.GetComponent<Rigidbody2D>().isKinematic = true;
items.transform.eulerAngles = new Vector3(0, 0, 0);
items.transform.SetParent(holdPos);
items.transform.position = tempParent.transform.position;

And here:

items.GetComponent<Rigidbody2D>().isKinematic = false;
items.transform.eulerAngles = new Vector3(0, 0, 0);
items.transform.SetParent(null, true);
items.transform.position = placePos.transform.position;

You can replace items with hit.collider.gameObject and put it in an if statement, so that it only works if the hit.collider.gameObject.tag == "Grabbable"; @AmateurProgramming

@Llama_w_2Ls I tried that and I got an error.

NullReferenceException: Object reference not set to an instance of an object

New Code:

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

public class ActionScript : MonoBehaviour
{
    private bool canHold;
    [SerializeField]
    private string grabbableTag;

    [SerializeField]
    private float distance;

    private GameObject items;
    Vector3 itemPos;
    public GameObject tempParent;
    public GameObject placePos;
    public bool isHolding;
    public LayerMask whatIsGrabbable;
    [SerializeField]
    private float checkHoldRadius;

    public Transform player;
    public Transform holdPos;
    public Transform rayPos2;



    void Start()
    {
    }

    void Update()
    {
        PickAndDrop(); 
    }

    private void PickAndDrop()
    {
        {

            Vector2 checkPos = rayPos2.position;
            Physics2D.queriesStartInColliders = false;
            RaycastHit2D hit = Physics2D.Raycast(checkPos, transform.right * transform.localScale.x, distance, whatIsGrabbable);
            {
                if (hit.collider.gameObject.tag == "Grabbable" && Input.GetKeyDown(KeyCode.E))
                {
                    canHold = true;
                    if (canHold)
                    {
                        isHolding = true;
                        hit.collider.gameObject.GetComponent<Rigidbody2D>().isKinematic = true;
                        hit.collider.gameObject.transform.eulerAngles = new Vector3(0, 0, 0);
                        hit.collider.gameObject.transform.SetParent(holdPos);
                        hit.collider.gameObject.transform.position = tempParent.transform.position;
                    }
                }
                else if (isHolding && Input.GetKeyDown(KeyCode.E))
                {
                    canHold = true;
                    isHolding = false;
                    hit.collider.gameObject.GetComponent<Rigidbody2D>().isKinematic = false;
                    hit.collider.gameObject.transform.eulerAngles = new Vector3(0, 0, 0);
                    hit.collider.gameObject.transform.SetParent(null, true);
                    hit.collider.gameObject.transform.position = placePos.transform.position;
                }
            }
               

        }
    }

    private void OnDrawGizmos()
    {
        Vector2 checkPos = rayPos2.position;
        Gizmos.color = Color.green;

        Gizmos.DrawLine(checkPos, (Vector2)checkPos + (Vector2)transform.right * transform.localScale.x * distance);
    }
}