Search Unity

RaycastAll script not working

Discussion in 'Scripting' started by Holocene, Oct 19, 2016.

  1. Holocene

    Holocene

    Joined:
    Feb 21, 2009
    Posts:
    347
    I'm trying to use the following code I've cobbled together, but it's doesn't appear to work- not changing my objects tag as desired.
    Any ideas?

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. public class RaycastAllToGold : MonoBehaviour {
    5.      private Camera main;
    6.      private Ray ray;
    7.      void Update() {
    8.        
    9.             if (Input.GetMouseButtonDown(0))
    10.     {
    11.          ray = main.ScreenPointToRay(Input.mousePosition);
    12.          RaycastHit[] hits;
    13.          hits = Physics.RaycastAll(ray);
    14.          int i = 0;
    15.          while (i < hits.Length) {
    16.              RaycastHit hit = hits[i];
    17.              Debug.Log (hit.collider.gameObject.name);
    18.              i++;
    19.            
    20.                               if (hit.collider.gameObject.tag == "Gold")    {
    21.        
    22.        
    23. hit.collider.gameObject.tag = "Gold_Pickup";
    24.          }
    25.      }
    26. }
    27.  
    28. }}
    29.  
     
  2. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class RaycastAllToGold : MonoBehaviour
    5. {
    6.     private Camera main;
    7.     private Ray ray;
    8.  
    9.     void Update()
    10.     {
    11.         if (Input.GetMouseButtonDown(0))
    12.         {
    13.             ray = main.ScreenPointToRay(Input.mousePosition);
    14.  
    15.             RaycastHit[] hits;
    16.             hits = Physics.RaycastAll(ray);
    17.  
    18.             int i = 0;
    19.             while (i < hits.Length)
    20.             {
    21.                 RaycastHit hit = hits[i];
    22.                 Debug.Log (hit.collider.gameObject.name);
    23.                 i++;
    24.  
    25.                 if (hit.collider.gameObject.tag == "Gold")
    26.                 {
    27.                     hit.collider.gameObject.tag = "Gold_Pickup";
    28.                 }
    29.             }
    30.         }
    31.     }
    32. }
    Just gonna leave that there so it's readable.

    Does "Gold_Pickup" already exist in the Tags & Layers Manager, written out exactly like that with the same capitalization and underscore? You can only switch objects to tags that exist already. Also, this is exactly the situation where you use a for loop instead of a while loop.
    Code (csharp):
    1. for(int i = 0; i < hits.Length; i++)
    2. {
    3.     // Do Stuff
    4. }
     
  3. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    It just so happens that today I just wrote a nice and simple class using SOLID principals that allows you to do this directly in the inspector (for OnClicks, but making one for OnDown is extremely similar)

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.Events;
    5.  
    6. [System.Serializable]public class BaseEventDataEvent:UnityEvent<BaseEventData>{}
    7.  
    8.  
    9. public class OnDownDispatcher : MonoBehaviour, IPointerDownHandler
    10. {
    11.     public BaseEventDataEvent OnDown = new BaseEventDataEvent();
    12.  
    13.     #region IPointerDownHandler implementation
    14.     public void OnPointerDown(PointerEventData eventData)
    15.     {
    16.         OnDown.Invoke(eventData);
    17.     }
    18.     #endregion
    19. }
    20.  
    extremely simple class, extremely reusable.

    All it does is expose the OnPointerdown handler to the inspector, leaving all the context sensitive logic to be handled there. Put each of these component on the gameobjects with the Gold tag and you should be able to,via the inspector, add all the actions you want to happen the moment your mouse presses that object, including having its tag set to "Gold_Pickup".

    This is using the IPointerHandlers which means theres a couple of requirements in the scene to make this work, don't worry they're all very simple
    1. You'll need an EventSystem gameobject (if you made a canvas in the scene it'll automatically make one, otherwise you can add one via Create->UI->EventSystem). Make sure to never have more than one in any scene.
    2. The gameobject with this script will need one of 3 components depending on the situation: A Collider if its a 3d object, a Collider2D if its a 2D Object, or a Image component if its in a Canvas.
    3. You'll also need a Raycaster component, specific one also depends on the same situation: A Physics Raycaster (for 3D) or Physics 2D Raycaster (for 2D) on your Camera, or a Graphics Raycaster on the parent Canvas
     
  4. Holocene

    Holocene

    Joined:
    Feb 21, 2009
    Posts:
    347
    Thanks for your excellent suggestions!
    Really like your solution, Joshua.

    Thanks!