raycast and detect tags

I have a script that raycasts and if it collides with something, you can press “E” to pick it up

When you pick it up I have another script that goes with it to make a checkmark show up on your screen.

Right now the raycast can’t tell what pickup-able objects are so I want to have it check for the objects tag. Does anyone know how to do that? here is my pick up script.

using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using UnityEngine;
using Vector3 = UnityEngine.Vector3;

public class PickUp1 : MonoBehaviour
{

    public static bool IngredientCollected1 = false;
    public Renderer rend;



    void Start()
    {
        rend = GetComponent<Renderer>();
        rend.enabled = true;
    }

    void Update()
    {
        RaycastHit hit;

        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit))
        {
            if (Input.GetKey("e"))
            {
                PickUpFunction();
            }
        }
    }



    void PickUpFunction()
    {



        GetComponent<Rigidbody>().useGravity = false;
        rend.enabled = false;
        IngredientCollected1 = true;
        gameObject.transform.Translate(0, 300, 0);
    }
}

Look up the CompareTag() method.

@Kurt-Dekker I see it and I know how to use it, but I can’t find a spot where I can put it in the if statement and it is valid and doesn’t give an error.

So for starters… I wouldn’t raycast EVERY frame, then check if “e” is down.

Instead, check if “e” was pressed, then do the raycast. This will be more efficient. (note the difference between GetKey, and GetKeyDown… I don’t know what functionality you want though. If you want it to scan while holding, or only when first pressed down).

As for checking the tag. The version of Raycast you’re using sets the ‘out hit’ that you passed in. On it is a reference to the Collider, Transform, etc:

Access that to call CompareTag. CompareTag is a member of Components and GameObjects alike. So you can call it on the collider, the transform, the rigidbody (if one exists), or even the gameObject of those.

if(hit.transform.CompareTag("MyTag"))

Note… this all hinges on the GameObject that the Collider is attached to is tagged, and not say some parent GameObject.

In unrelated pointers… you can always say “transform.forward” instead of “transform.TransformDirection(Vector3.forward)”. They’re both the same, one just shorter than the other.

2 Likes

@lordofduct Thank you for your response!

I tried to do transform.forward earlier but it wasn’t working. I swapped around the key press check and the raycast. It still doesn’t like it when I put compare tag in that context. Do you know why? I’m really new so this is probably a rookie mistake but it has red squiggles under hit in hit.transform.CompareTag(“tag”) It says "Use of unnassigned local variable ‘hit’ " Thanks!

the hit.transform.CompareTag needs to be inside the block that results from Physics.Raycast being true. It’s not assigned until after the ‘out’ has occurred.

if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit))
{
    if(hit.transform.CompareTag("MyTag"))
    {
        //do stuff
    }
}

If it’s still not working, try tossing in some debug.log’s, or attaching the debugger and stepping through the code, and see what ‘hit’ is referencing for targets.

1 Like

If that’s not working the longer form lord posted won’t work either. Press pause in the scene, go study the objects in question, see which way their red, green and blue axes are pointed (make sure you have LOCAL coordinates selected in the upper left corner of the editor), and the blue is transform.forward.

Yes, what Lord said: this is ALWAYS a good strategy. Get numbers. Answer these questions:

  • “is this code even running?” (you would be surprised a lot!)

  • “what data is going into these decisions?” (numbers, strings, booleans, etc.)

No way anyone outside of your computer can tell you what those numbers are. It’s up to you and Debug.Log() is always the first and easiest starting point. Attaching the debugger is great too but a breakpoint freezes the game solid, which makes it less useful in interactive software except in truly instantaneous cases of debugging a problem.

Ok so I just added in a bunch of debug.logs and they are very useful! I found that When my raycast hits and I press E, it runs. I also found that while it checks if the objects tag is = to (“random tag”) The if statement works. But where I get stuck is when I call the function called “PickUpFunction” It doesn’t like it, and it also gives me and error when it reaches that part in the code. Here it is. I know why it is giving the error, because in the PickUpFunction it is requesting a rigidbody, but it doesn’t give me anywhere in the inspector to give it a reference. And here is my code once again, but with all Debug.Log’s in place.

using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using UnityEngine;
using Vector3 = UnityEngine.Vector3;

public class PickUp1 : MonoBehaviour
{

    public static bool IngredientCollected1 = false;





    void Update()
    {
        RaycastHit hit;

        if (Input.GetKeyDown("e"))
        {
            if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit))
            {
                Debug.Log("Raycast Hit!");
                if (hit.transform.CompareTag("Selectable")) Debug.Log("Object is selectable");
                {
                    Debug.Log("If statement successful");
                    PickUpFunction();
                }
            }
        }
    }
      
        public void PickUpFunction()
    {

        GetComponent<Rigidbody>().useGravity = false;
        IngredientCollected1 = true;
        gameObject.transform.Translate(0, 1000, 0);
    }
}

The error says exactly what the problem is… you’re trying to access a Rigidbody on something that doesn’t have one.

In your case you’re calling ‘GetComponent’ on the script in question (not what was returned from the raycast).

When you just say “GetComponent” that’s the same as saying “this.GetComponent” rather than say “hit.transform.GetComponent” (note that hit has a ref to the rigidbody already built in).

From the sounds of your error, this script is attached to your “Main Camera”. Which doesn’t have a rigidbody.

You probably meant to pass the target you hit to ‘PickUpFunction’ maybe as a parameter?

public void PickUpFunction(Transform targ)
{
    var rb = targ.GetComponent<Rigidbody>();
    if(rb != null) rb.useGravity = false;
    //so on, so forth

NOTE - the hit target also doesn’t necessarily have a rigidbody either. And you should probably check if it’s null before accessing it.

Thank you for the solution! I still have a problem, as I don’t know how to call the function under the if E key pressed statement. I tried finding a solution but all it showed me was how to call a function from ANOTHER script. Do you know how I can call it? Currently I am trying to call it on line 28.

using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using UnityEngine;
using Vector3 = UnityEngine.Vector3;

public class PickUp1 : MonoBehaviour
{

    public static bool IngredientCollected1 = false;





    void Update()
    {
        RaycastHit hit;

        if (Input.GetKeyDown("e"))
        {
            if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit))
            {
                Debug.Log("Raycast Hit!");
                if (hit.transform.CompareTag("Selectable")) Debug.Log("Object is selectable");
                {
                    Debug.Log("If statement successful");
                    PickUpFunction();
                }
            }
        }
    }
       
        public void PickUpFunction(Transform targ)
    {

        var rb = targ.GetComponent<Rigidbody>();
        if (rb != null) rb.useGravity = false;
        IngredientCollected1 = true;
        gameObject.transform.Translate(0, 1000, 0);
    }
}

Do you know how to add distance?

Yes, you add distance using the addition operator.

Now, if you have an actual problem, here is how to communicate to complete strangers on a public forum:

First, start your own fresh post - it’s FREE!

Second, how to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, especially any errors you see
  • links to documentation you used to cross-check your work (CRITICAL!!!)