Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Raycast problems!

Discussion in 'Scripting' started by Benzaboy2003, Jul 17, 2017.

  1. Benzaboy2003

    Benzaboy2003

    Joined:
    Jul 17, 2017
    Posts:
    25
    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?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerAbilities : MonoBehaviour {
    6.  
    7.     public int TreeHealth = 100;
    8.     public int ObjectDamage = 10;
    9.     public GameObject Tree;
    10.  
    11.     public int Wood = 0;
    12.    
    13.     void Update () {
    14.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    15.         RaycastHit hitInfo;
    16.  
    17.         if (Physics.Raycast(ray, 5)) {
    18.  
    19.             if (hitInfo.collider.tag == "tree") {
    20.  
    21.                 if (Input.GetMouseButtonDown(0)){
    22.                     TreeHealth -= ObjectDamage;
    23.                     Wood += 5;
    24.                     Debug.Log(TreeHealth);
    25.                 }
    26.             }
    27.  
    28.         }
    29.  
    30.         if (TreeHealth <= 0) {
    31.             Destroy(Tree);
    32.         }
    33.        
    34.  
    35.         if (Input.GetKeyDown(KeyCode.Tab)) {
    36.             Debug.Log("Wood: " + Wood);
    37.         }
    38.     }
    39. }
    40.  
     
  2. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    Your "hitInfo" isn't being populated anywhere.. you do that in the call to Physics.Raycast.
    ex:
    Code (csharp):
    1. if (Physics.Raycast(ray, 5, out hitInfo)) {
     
  3. Benzaboy2003

    Benzaboy2003

    Joined:
    Jul 17, 2017
    Posts:
    25
    then do i put this inside it?
    Code (CSharp):
    1. if (hitInfo.collider.tag == "tree") {
    2.  
    3.                 if (Input.GetMouseButtonDown(0)){
    4.                     TreeHealth -= ObjectDamage;
    5.                     Wood += 5;
    6.                     Debug.Log(TreeHealth);
    7.                 }
    8.             }
     
  4. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    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 :)

    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.
     
  5. Benzaboy2003

    Benzaboy2003

    Joined:
    Jul 17, 2017
    Posts:
    25
    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?
     
  6. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    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:

    Code (csharp):
    1. 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"
     
  7. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Why is CompareTag preffered?
     
  8. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    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.
     
    MCrafterzz likes this.
  9. Benzaboy2003

    Benzaboy2003

    Joined:
    Jul 17, 2017
    Posts:
    25
    thanks mate, helped a lot. it works!
     
  10. cstooch

    cstooch

    Joined:
    Apr 16, 2014
    Posts:
    354
    No prob! Glad you got it to work.