Unity 2D Raycast Issue with Multiple Units on Screen. Is This A Bug in Unity?

Hi,

I’m making a 2D top down RTS style game and would like to know whether the issue I’m having Is a Unity Bug itself or if it’s my code.

The issue happens when I have more than one unit on the screen and try to select either of them the raycast I perform Hits the floor. So, it’s almost as if my unit’s colliders don’t exist. Whats weird is that all my code works when only one unit is active in the scene. This leads me to believe it is my code I just don’t see where the error is.

Any help is greatly appreciated. Thankyou

P.S. Here is the script I believe is housing the issue.

public class UnitSelector : MonoBehaviour 
{
    RaycastHit2D hit;
    RaycastHit2D hit2;

    public List<Collider2D> selectedList; // Create the list
    public List<GameObject> friendlyUnits;

    bool isEnemy;
    bool found;

	// Use this for initialization
	void Start () 
    {
        selectedList = new List<Collider2D>(); // Make it exsist
        friendlyUnits = new List<GameObject>();
	}
	
	// Update is called once per frame
	void Update () 
    {
        friendlyUnits.Clear(); // Clear the List so it Updates constantly
 
        foreach(GameObject friendly in GameObject.FindGameObjectsWithTag("BlueSoldier"))// check the world for all friendly units
        {
            friendlyUnits.Add(friendly); // and Add them to the List
        }
        if(Input.GetMouseButtonDown(0))// If I Left Click
        {
            hit = Physics2D.Raycast(new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y), Vector2.zero, 0f);

            if(hit.collider.tag == "BlueSoldier")
            {
                Debug.Log("Hit: " + hit.collider.tag);
                isEnemy = false;

                if (!Input.GetKey(KeyCode.LeftControl))
                {
                    DeselectUnits();
                }

                for(int i =0;i<selectedList.Count && !found;i++)
                {
                    if(hit.collider == selectedList*)*

{
found = true;
}
}
if(!found)
{
Debug.Log(“Preparing to Add”);
selectedList.Add(hit.transform.collider2D);
Debug.Log(“Added”);
selectedList[selectedList.Count-1].transform.SendMessage(“SelectUnit”, true);
}
}
else
{
Debug.Log("Hit: "+hit.collider.tag);
//selectedList[selectedList.Count - 1].transform.SendMessage(“SelectUnit”, false);
//selectedList.Clear();
}
}
if(Input.GetMouseButtonDown(1))//If I Right Click
{
hit2 = Physics2D.Raycast(new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y), Vector2.zero, 0f);
if(hit2.collider.tag == “Floor”)
{
Debug.Log(“Floor Clicked”);
selectedList.ForEach(MoveUnit);
}
}

  • }*

Looks like you need to set found back to false. After you’ve clicked on one unit, it’s set to true, but I don’t see anything that sets it back. The second time you click on something, it will be as if it’s already found (and therefore already selected).

It may be easier to use local variables, so that their value resets each time the function is called.

My solution was the floor collider or asset was on the same depth plane as the units. I just moved the floor down on the z and that seemed to work.

Physics2D.Raycast performs a raycast in 2d space. You passed total nonsense to the function. You didn’t even specify a direction of the raycast (as you pass “Vector2.zero”) and set the ray lenth to “0”. Such a setup should actually never hit anything.

You might want to use Physics2D.GetRayIntersection or Physics2D.GetRayIntersectionAll instead and use the proper 3d ray which you can get easily with Camera.main.ScreenPointToRay.

edit

As for how to ignore the floor collider: Just use layers (5)