Home > Enterprise >  How to detect which GameObject is being collided with
How to detect which GameObject is being collided with

Time:04-20

I'm somewhat new to Unity, and I'm trying to figure out a way to add different point values to these different birds when you hit them with a rock (don't ask). It was working like this:

Destroy(other.gameObject);
player.GetComponent<PlayerController>().score  = 1;

It adds 1 point to the player when a bird is hit, but when I try to detect which bird was being hit, I get this error:

"Property or indexer 'Component.gameObject' cannot be assigned to -- it is read only"

Is there a better way to do this? Please explain to me like I'm a child or else I will probably not understand.

GameObject bird1;
GameObject bird2;
GameObject bird3;

    void Start()
    {
        bird1 = GameObject.Find("Bird1");
        bird2 = GameObject.Find("Bird2");
        bird3 = GameObject.Find("Bird3");
    }

    void OnTriggerEnter(Collider other)
    {
        if(other.gameObject = bird1)
        {
            Destroy(other.gameObject);
            player.GetComponent<PlayerController>().score  = 1;
        }
    
        else if(other.gameObject = bird2)
        {
            Destroy(other.gameObject);
            player.GetComponent<PlayerController>().score  = 2;
        }
    
        else if(other.gameObject = bird3)
        {
            Destroy(other.gameObject);
            player.GetComponent<PlayerController>().score  = 3;
        }
    }

CodePudding user response:

you can use gameObject.name.Equals() for checking which bird collided.


    void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.name.Equals("Bird1"))
        {
            Destroy(other.gameObject);
            player.GetComponent<PlayerController>().score  = 1;
        }
    
        else if(other.gameObject.name.Equals("Bird2"))
        {
            Destroy(other.gameObject);
            player.GetComponent<PlayerController>().score  = 2;
        }
    
        else if(other.gameObject.name.Equals("Bird3"))
        {
            Destroy(other.gameObject);
            player.GetComponent<PlayerController>().score  = 3;
        }
    }


CodePudding user response:

The error you're encountering is fairly straightforward. If we look at one of the if-statements:

if(other.gameObject = bird1)

The problem lies with the equality-sign you're using. A single "=" is an assignment, whereas a comparison (which is what you want here) uses two; "==".

A simple little mnemonic I sometimes use is that "It takes two to compare".

If you want to detect if the GameObject being hit is exactly this specific bird, something along what you have makes sense. But if your intent is more along the line of this kind of object that is a bird, there are a few different ways to go about it.

The first one is to use Tags. You can essentially add a string-label to objects in your game as being "this kind of thing", and run comparisons on the name to verify that what you've hit is what you want to respond to. Unity already have a few predefined tags (Untagged, Respawn, Finish, EditorOnly, MainCamera, Player, GameController), but you can create custom ones. Tags are great for doing a rough sorting. Say that you defined a custom tag named "Bird". You could then check it like so:

if(other.gameObject.tag == "Bird")

You can read more about tags here, and also see a similar usage on Unity's documentation on collisions. Do note that a Collision and a Collider are not exactly the same.

Using tags may not give you exactly what you want, however. I see that you would like to add different scores depending on what bird you hit. This could be handled by having a separate script on the birds, which contain their score-value. You can then increment the score on your PlayerController based on the value stored in the bird, which also separates the responsibilities of your objects a bit.

EDIT: here's an example on how the above could be accomplished. Say you have a small Bird-script, like so:

public class Bird : MonoBehaviour
{
    public int value;
}

Attaching this to your bird object, the value field can now be changed from within the editor. Give the bird a "Bird" tag as well. Then, if your OnTriggerEnter in your existing script is changed to something like this:

void OnTriggerEnter(Collider other)
{
    if(other.gameObject.tag == "Bird")
    {
        Bird bird = other.GetComponent<Bird>();
        player.GetComponent<PlayerController>().score  = bird.value;
        Destroy(other.gameObject);
    }
}

Then it should work nicely.

EDIT 2: as @acornTime pointed out, you can also use the CompareTag method, which is slightly faster, and handles some error cases:

other.gameObject.CompareTag("Bird");
  • Related