Detecting GUI rects/elements in other gameobjects

Im trying to adjust my SpawnPoint class so that when it tries to spawn something underneath my GUI it finds another location. However it never interrupts the location of the GUI elements correctly.

For simplicity sake I have reduced alot of the code into a test.

So my HudController.cs defines a rect which mirrors the button.

 public Rect shieldsButtonRect = new Rect(Screen.width - 50, Screen.height - 25, 50, 25);
        public Vector3 shieldsButtonPosition;

		public HudController ()
		{
		}
	
		void OnGUI () 
		{
            shieldsButtonPosition = GUIUtility.GUIToScreenPoint(shieldsButtonRect.position);

			//shields up (auto deactivates)
			if(GUI.Button(new Rect (Screen.width - 50,Screen.height - 25,50,25), shieldHudIcon)){
				tbc.activateShield();
			}

This is just a Test class (below). Im trying to have my gameobject (a cube) spawn directly on my gui elements so that I know i have the coordinates/position right. Like I said this is just a test and my SpawnPoint (see below) is what eventually will use the Rect to say: If the button rect contains spawnpoint find another location.

GameObject hudGO = GameObject.FindGameObjectWithTag("Hud");
                HudController hc = hudGO.GetComponent<HudController>();

		Vector3 pos2 = Camera.main.ScreenToWorldPoint(hc.shieldsButtonRect.position);
		
            pos2.x /= 2;

            pos2.y /= 2;
            pos2.y *= -1;
            transform.position = pos2;

^After further debugging this is the closest I could get it without manipulating the x and y to much. This positioned the Test (cube) just below and to the left of the desired area (the gui button that matches the rect)

Above is my test; below is the implementation, put here more for reference because if I can get the above working I can translate it to the below.

Like I said the eventual goal here is that when my SpawnPoint class creates a spawn point it will check if shieldButtonRect.Contains the proposed spawnpoint. If it does, find another random spawnpoint. But my problem is that these Rects never line up with their respective gui element and so contains never returns true.

SpawnPoint.cs

public Vector3 getSpawnPointAtRandomInsideBounds() {
    						if (Camera.main == null) {
    								return new Vector3 (0f, 0f, -1.0f);
    						}
    
    						Vector3 returnVal = new Vector3 (0f, 0f, 0f);
    						while (doesCollideWithHud(returnVal) || returnVal.Equals(new Vector3(0f,0f,0f))) {
    								float screenX = Random.Range (0.0f, Camera.main.pixelWidth);
    								float screenY = Random.Range (0.0f, Camera.main.pixelHeight);
    								float ScreenZ = Random.Range (Camera.main.nearClipPlane, Camera.main.farClipPlane);
    								returnVal = Camera.main.ScreenToWorldPoint (new Vector3 (screenX, screenY, ScreenZ));
    				//returnVal = new Vector3(8,-5,0);
    						}
    						return returnVal;
    				}
    private bool doesCollideWithHud (Vector3 preposedPosition)
    		{
    			Rect shieldButton = new Rect (Screen.width - 50, Screen.height - 25, 50, 25);
    
    			if(shieldButton.Contains(preposedPosition)){
    				return true;
    			}
    			Rect pauseButton = new Rect (Screen.width - 30,0,30,30);
    			if(pauseButton.Contains(preposedPosition)){
    				return true;
    			}
    			Rect hudHealthArea = new Rect (0, Screen.height - 60, 70, 30);
    			if(hudHealthArea.Contains(preposedPosition)){
    				return true;
    			}
    			Rect hudScoreArea = new Rect (0, Screen.height - 30, 70, 30);
    			if(hudScoreArea.Contains(preposedPosition)){
    				return true;
    			}
    
    			return false;
    		}

I needed this for 2 purposes. I didnt want objects spawning underneath my gui and I didnt want gui clicks to move the character (towards the gui object).

So my fix has 2 pieces to it.

First I moved all gui elements to the bottom in a line which was the whole screen width and a max of 30px height.

In my spawner’s code I was doing

public Vector3 getSpawnPointAtRandomInsideBounds() {
			if (Camera.main == null) {
				return new Vector3(0f, 0f, -1.0f);
			}
			
			Vector3 returnVal = new Vector3(0f, 0f, 0f);
			
			float screenX = Random.Range(0.0f, Camera.main.pixelWidth);
			float screenY = Random.Range(30.0f, Camera.main.pixelHeight);
			float ScreenZ = Random.Range(Camera.main.nearClipPlane, Camera.main.farClipPlane);
			return Camera.main.ScreenToWorldPoint(new Vector3(screenX, screenY, ScreenZ));
		}

After putting the gui at the bottom all I had to do in order to prevent spawning underneath it was to change that to the above to

float screenY = Random.Range(30.0f, Camera.main.pixelHeight);

Next was to stop the clicks from moving the character towards the gui element. For this I added a method and a switch so that the Hud catches the click first, and if its on one of its elements it makes my player ignore it.

//GUI method to switch the bool in my player object
//signify we are clicking gui
            Event e = Event.current;
            if (e.type == EventType.MouseDown && guiGroupRect.Contains(e.mousePosition)) {
                playerController.guiClick = true;
            } else if (e.type == EventType.MouseDown && !guiGroupRect.Contains(e.mousePosition)) {
                playerController.guiClick = false;
            }

next was just to switch movement based on if guiClick is true or not

if (Input.GetButton("Fire1") && !guiClick) {
                Vector3 moveToward = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                moveDirection = moveToward - currentPosition;
                moveDirection.z = 0;
                moveDirection.Normalize();
            }
            Vector3 target = moveDirection * MOVE_SPEED + currentPosition;
            transform.position = Vector3.Lerp(currentPosition, target, Time.deltaTime);

This might not be the most elegant solution but it works for me (at least for the time being).