Efficient Raycast

Hi all,

I’ve got this question about raycasting. In my project there are some objects with different tags like enemy’s, items, npc’s etc. for the enemy’s and npc’s i want to detect them from a long range and for the items and talking to npc’s i want to do this only at short distance. is there a more efficient way of doing this than i am currently doing? because i have to make 2 different if loops to check all the items. in this stage it’s still do-able but later on when i use a lot more tags for other objects it’s going to be messy.

void Update()
    {
        //raycast detection of objects
        cam = Camera.main.transform;
        ray = new Ray(cam.position, cam.forward);
        Debug.DrawRay(ray.origin, hit.point, Color.green);
        //detect enemy
        if (Physics.Raycast(ray, out hit, 50.0f))
        {
            if (hit.transform.tag == "Enemy") // assign the comparison result to is enemy    
            {
                isEnemy = true;
                isItem = false;
                isNpc = false;
                enemy = hit.collider.gameObject.GetComponent<EnemyClass>();
            }
            else if (hit.transform.tag == "NPC")
            {
                isNpc = true;
                isEnemy = false;
                isItem = false;
                npc = hit.collider.gameObject.GetComponent<NPCClass>();
            }

        }
        else
        {
            isEnemy = false;
            isItem = false;
            isNpc = false;
        }
        if (Physics.Raycast(ray, out hit, 5.0f))
        {
            if (hit.transform.tag == "Item")
            {
                isItem = true;
                isEnemy = false;
                isNpc = false;
                item = hit.collider.gameObject.GetComponent<ItemClass>();

                //keycodes
                if (Input.GetKeyDown(KeyCode.E))
                {
                    playerClass.inventory.Add((GameObject)Instantiate(hit.collider.gameObject));
                    Destroy(hit.collider.gameObject);
                }
            }
            else if (hit.transform.tag == "Enemy") // assign the comparison result to is enemy  
            {
                isEnemy = true;
                isItem = false;
                isNpc = false;
                enemy = hit.collider.gameObject.GetComponent<EnemyClass>();
            }
            else if (hit.transform.tag == "NPC")
            {
                isNpc = true;
                isEnemy = false;
                isItem = false;
                npc = hit.collider.gameObject.GetComponent<NPCClass>();
                if (Input.GetKeyDown(KeyCode.E))
                {
                    npc.Talk();
                }
            }
            else
            {
                isEnemy = false;
                isItem = false;
                isNpc = false;
            }

        }

I’ve got another question about the item storing in my inventory. how do i add a copy of the object in my inventory List? because the way i am doing this currently is based on reference instead on value so i get a error when i delete the current object

if (Input.GetKeyDown(KeyCode.E))
{
       playerClass.inventory.Add((GameObject)Instantiate(hit.collider.gameObject));
       Destroy(hit.collider.gameObject);
}

I have already fixed the unnecessary code with hit.distance like below.

   void Update()
    {
        //raycast detection of objects
        cam = Camera.main.transform;
        ray = new Ray(cam.position, cam.forward);
        Debug.DrawRay(ray.origin, hit.point, Color.green);
        //detect enemy
        if (Physics.Raycast(ray, out hit, 30.0f))
        {
            if (hit.transform.tag == "Enemy")
            {// assign the comparison result to is enemy    
                isEnemy = true;
                isItem = false;
                isNpc = false;
                enemy = hit.collider.gameObject.GetComponent<EnemyClass>();
            }
            else if (hit.transform.tag == "Item"  hit.distance < 5)
            {
                isItem = true;
                isEnemy = false;
                isNpc = false;
                item = hit.collider.gameObject.GetComponent<ItemClass>();

                //keycodes
                if (Input.GetKeyDown(KeyCode.E))
                {
                    playerClass.inventory.Add((GameObject)Instantiate(hit.collider.gameObject));
                    Destroy(hit.collider.gameObject);
                }
            }
            else if (hit.transform.tag == "NPC")
            {
                isNpc = true;
                isEnemy = false;
                isItem = false;
                npc = hit.collider.gameObject.GetComponent<NPCClass>();

                if (hit.distance < 5)
                {
                    isInSight = true;
                }
                else isInSight = false;

                if (Input.GetKeyDown(KeyCode.E)&isInSight)
                {
                    npc.Talk();
                }
            }
            else
            {
                isEnemy = false;
                isItem = false;
                isNpc = false;
            }
        }
    }