Dynamically finding a GUI.Box in a GUI.Window object

GUI.Box scripting question…
What I need to do, is have a click / drag event for the boxes and be able to identify who is next to whom with an ID for each element. Matthew has given a few ideas on where to take this as far as a HashTable, but this doesn’t solve my mouse event problem.

Here is what I have so far, please help if you can or have an idea of what I should be doing.

Thanks
(btw this is a dynamic window, with a dynamic collection which will be based on inventory rules in my code)

96779--3763--$picture_2_170.png

Something like this:
(untested code!)

private ArrayList boxes;
private bool dragging;
private Vector2 dragOffset;


public void Awake()
{
	dragging = false;
	dragOffset = new Vector2( 0, 0 );
	boxes = new ArrayList();
	boxes.Add( new Rect( /* ... */ ) );
	// ...
}



public void OnGUI()
{
	if( Event.current.type == EventType.MouseDown )
	{
		foreach( Rect box in boxes )
		{
			if( CheckRect( Event.current.mousePosition, box ) )
			{
				dragOffset.x = Event.current.mousePosition.x - box.x;
				dragOffset.y = Event.current.mousePosition.x - box.y;
				dragging = true;
				break;
			}
		}
	}
	else if( Event.current.type == EventType.MouseUp )
	{
		dragging = false;
	}
	else if( Event.current.type == EventType.MouseDrag )
	{
		foreach( Rect box in boxes )
		{
			if( CheckRect( Event.current.mousePosition, box ) )
			{
				box.x += Event.current.mousePosition.x - dragOffset.x;
				box.y += Event.current.mousePosition.y - dragOffset.y;
				break;
			}
		}
	}

	for( int i = boxes.Length - 1; i > 0; i-- )
	{
		Rect box;
		
		box = boxes[ i ] as Rect;

		GUI.Box( box, "" );
	}
}



public static bool CheckRect( Vector2 point, Rect rect )
{
	return 	point.x >= rect.x  point.x <= rect.x + rect.width 
			point.y >= rect.y  point.y <= rect.y + rect.height;
}

Sweet, thanks for the response, I will go over this tonight and see if I can get it to work. Thanks again!

After spending a day on this, I have come to the conclusion that GUI elements are rendered in reverse order they are created, for example, the following code has the boxes BEHIND the window, instead of infront of it. It took me 3 hours to determine that it wasn’t my imagination. I also want them all as a single group unit (as in the Window is the parent to the boxes, but the boxes are allowed to be moved around on the parent ONLY, if the parent window moves, the entire collection of boxes gets moved)

I want the window behind everything:

ParentWindow = UnityEngine.GUI.Window(0, new Rect(X, Y, Width, Height), CheckWindow, "Inventory");
            
// SLOTS
int slotCounter = 0;
foreach (InventorySlot slot in Slots)
{
    UnityEngine.GUI.Box(new Rect(this.X + ((slot.XIndex + 2) * (float)Padding.X) + (slot.XIndex * Columns[0].Width), this.Y + ((slot.YIndex + 2) * (float)Padding.Y) + (slot.YIndex * Rows[0].Height), Columns[0].Width, Rows[0].Height), slotCounter.ToString());
    slotCounter++;
}

Notice how I am creating the window FIRST then the boxes NEXT, but the end result is the boxes are rendered FIRST and the window LAST meaning that the window is on top of the boxes, I was having a hell of a time clicking on the boxes, if I clicked outside of the GUI.Window, held down the mouse then dragged over top of the window, then the boxes were selectable, if I clicked on the box as it is viewable in the window, the window boarder goes white from black and I get no click event on the boxes.

This has to be a bug IMO.

No bug. That is expected behaviour. The “Desktop” of the GUI is always rendered before GUI windows. The render order of GUI windows is determined by the order in which they have been focused and

I don’t get exactly what you want. Could you explain in abstract terms the desired behaviour?

I’ll do my best to explain what I expected vs what I got (thanks again for helping me figure this out)

Imagine you have a windows form, you add controls to that form, would you want those controls to be on the form or behind the form and the form have transparency so that you can see the control you add but you can’t do anything with them.

Expected behavior is that we create a GUI.Window object, this object then is a parent, to this object we add children (buttons, labels, boxes, so on), as it stands, when adding anything to that GUI.Window all elements are ‘behind’ it, quiet literally.

Now, when we create gui elements, we should expect to see them rendered in the order in which they were created. Thus we create a GUI.Window, then we create a label and a box in that exact order. Upon gui rendering, it should go, hey, a window, good, render it, look a label now lets render that, there is a box, lets now render that since it was all created in that order.

Since I can’t “bring to front” a gui item since it has no literal identity, and no order, I have zero control. My end result is that I want to create a GUI ‘form’ per say, that has all of the elements that I desire, where I desire them and selectable as needed.

All GUI elements are missing a key ID field of type GUIParent (meaning who are they sibilings of), no Z order or a way to identify them by a unique ID at time of creation (name it perchance). So I am trying to keep within the rules of the GUI design system.

HTH in explaining what I expected vs what is going on. I see no reason why GUI.Window takes presidence over all other gui elements when it comes to render order and where it is placed in the stack. Makes no sense to me.

That is literally saying, create a new windows form, add controls, reverse order the items in the window child stack, now render. No one would ever be able to click a button or do data entry because the form is over top of everything.

Did you ever get this working, I am facing the same issue (with same use case - inventory screen).