Raycast Not Hitting All Colliders

Hello everyone,

I’m using Unity 5.4.0 (also tried this is 5.3.4) and I’ve found some odd behavior between RaycastHit2D and GameObjects. In my script, I have left click add a tile based on the Raycast position of the mouse when no tile is found in that location and if the layer where I’m clicking is called “Floor”. This works perfectly fine, without fail, every time.

I also have it set that on right click, if a tile is hit at the mouse position, to destroy that gameObject. This works the vast majority of the time but I find that sometimes the RaycastHit2D fails to find the gameObject. To test this, I draw a 20x20 grid of tiles. Of those 400 tiles, about 90% are destroyed properly. There are some tiles though that refuse to be destroyed when I right click on them. They exist in the Hierarchy and look exactly like a working tile does in the Inspector but cannot be destroyed. Some behavior I noticed with this:

  • If I left click, it adds a new tile gameObject on top of the un-destroyable one (which shouldn’t happen if a tile is found in the mousePosition). The new tile is able to be destroyed properly but the old one still remains.
  • If I manually change any properties of the un-destroyable in the Inspector, when I switch back to the game, that tile is now able to be destroyed.
  • If I find un-destroyable tiles, ignore them, destroy some properly functioning tiles, and then return to the un-destroyable ones, on occasion some of them are then able to be destroyed properly.
  • The un-destroyable tiles appear to occur in clusters, but never in the same exact spots based on the test runs I’ve tried.

Any help or insight that can be provided on this would be great. Thank you!

public class Test : MonoBehaviour
{   
    public GameObject tile;

    void Start ()
    {
   
    }
   
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            int layerMask = ~(1 << LayerMask.NameToLayer ("Default"));
            Vector2 tilePosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast (tilePosition, Vector2.zero, Mathf.Infinity, layerMask);
            string layerName = LayerMask.LayerToName (hit.collider.gameObject.layer);

            if ((hit.collider.tag != "Tile") && (layerName == "Floor"))
            {                   
                GameObject addTile = Instantiate (tile, new Vector2((tilePosition.x -= tilePosition.x % 1), (tilePosition.y -= tilePosition.y % 1)), Quaternion.identity) as GameObject;
            }
        }

        if (Input.GetMouseButtonDown (1))
        {

            int tileMask = ~(1 << LayerMask.NameToLayer ("Default"));
            Vector2 tiledPosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
            RaycastHit2D hitTile = Physics2D.Raycast (tiledPosition, Vector2.zero, Mathf.Infinity, tileMask);

            if (hitTile.collider.tag == "Tile")
            {
                Debug.Log ("Hit");
                Destroy (hitTile.collider.gameObject);
            }   
        }
    }
}

Are you sure you want to use Physics2D.Raycast with zero direction vector?
You should probably use Physics2D.OverlapPoint instead, since you’re just looking for existing colliders where you click.