Raycast problems!

I’ve worked this code using only 1 object as a public game object, but now i would like to use tags for multiple objects. It wont recognise hit info on line 19, can anyone help?

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

public class PlayerAbilities : MonoBehaviour {

    public int TreeHealth = 100;
    public int ObjectDamage = 10;
    public GameObject Tree;

    public int Wood = 0;
   
    void Update () {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;

        if (Physics.Raycast(ray, 5)) {

            if (hitInfo.collider.tag == "tree") {

                if (Input.GetMouseButtonDown(0)){
                    TreeHealth -= ObjectDamage;
                    Wood += 5;
                    Debug.Log(TreeHealth);
                }
            }

        }

        if (TreeHealth <= 0) {
            Destroy(Tree);
        }
       

        if (Input.GetKeyDown(KeyCode.Tab)) {
            Debug.Log("Wood: " + Wood);
        }
    }
}

Your “hitInfo” isn’t being populated anywhere… you do that in the call to Physics.Raycast.
ex:

if (Physics.Raycast(ray, 5, out hitInfo)) {

then do i put this inside it?

if (hitInfo.collider.tag == "tree") {

                if (Input.GetMouseButtonDown(0)){
                    TreeHealth -= ObjectDamage;
                    Wood += 5;
                    Debug.Log(TreeHealth);
                }
            }

Off the top of my head, I think you’re close…

It seems odd that your player would have the tree health in it. I would think that the health would be on your tree, or else all trees will share the same health. You’d still check if the tag is tree, and if mouse button is down, but you would probably want to call some sort of function from the tree you collided with to reduce its health, and in the tree somewhere (update, for example), still check if it’s health is <0, and destroy it. Don’t do that in the player unless you only have one tree in your whole game, which I doubt you do :slight_smile:

And that said, I told you how to do this all in your tree using OnMouseDown. That would be a lot easier… not sure why you preferred this approach, but it’s up to you.

I see you said have the health on the tree, a bit of a stupid question but how do I look at the info on the tree if im to do this?

I keep pushing you towards OnMouseDown, but you’re ignoring that, soooooooo…

If you want to do it from the player using a raycast, you could code a function in your tree script. Let’s call it Damage.

From inside your raycast check (the if statement part), you’d do something like this:

hitInfo.collider.GetComponent<Tree>().Damage();

This assumes a few things:

  • Your tree has a script on it named Tree
  • Your Tree script has a method in it called Damage(). You can give it a parameter for the amount of damage, if you like.

Also, it will still work, but the preferred method to compare a tag is:
hitInfo.collider.CompareTag(“tree”) instead of hitInfo.collider.tag == “tree”

Why is CompareTag preffered?

It does not allocate memory to do the comparison, and is faster, according to this post (as well as others if you look around):
http://answers.unity3d.com/questions/40975/why-does-comparetag-exist.html

That said, I think there might be a bit of debate as to just how much faster it is (unless you’re repeating a lot of checks), although, I think any time you can avoid extra garbage collection, you should.

That said, I think using layers / layer masks for collisions is the even quicker solution, but I didn’t want to add more confusion.

1 Like

thanks mate, helped a lot. it works!

No prob! Glad you got it to work.