Screen space vs GUI space

I am trying to convert some things between GUI Space to world position. I have the screen to world working OK but am having problems getting from GUI to Scren space. I thought the only difference was GUI space has (0,0) in top,left and Screen space it is bottom,left. So to convert a gp (GUI Position) to sp (Screen Position) I would do the code below getting sp2, I tried using the GUIUtility.GUIToScreenPoint function below also.

gp = Vector2(windowRect.x+r.xMax,windowRect.x+r.yMin)
sp=GUIUtility.GUIToScreenPoint(gp)
sp2 = Vector2(gp.x,Screen.height-gp.y)
Debug.Log("sp:${sp}:sp2:${sp2}:gp:${gp}:hieght:${Screen.height}:width:${Screen.width}")

the log shows
sp:(760.0, 492.0):sp2:(575.0, 242.0):gp:(575.0, 381.0):hieght:623:width:770

Is GUIUtility.GUIToScreenPoint buggy?
or is there something wrong with my calculation of sp2?
Or does GUIUtility.GUIToScreenPoint do something else?

Cheers,
Grant

I don’t believe anything is buggy here and I sense there is some confusion about what exactly ā€œscreen spaceā€ is when using GUIToScreenPoint and ScreenToGUIPoint. When using either of those, ā€œscreen positionā€ refers to the overall position in UnityGUI screen space, so the upper-left is still (0,0) and the units are in pixels. Try this on for size:

function OnGUI () {

  GUI.BeginGroup( Rect(5.0, 5.0, 100.0, 100.0) );
	
    var gp = Vector2(2.0, 2.0);
    Debug.Log( GUIUtility.GUIToScreenPoint(gp) );
		
    var sp = Vector2(7.0, 7.0);
    Debug.Log( GUIUtility.ScreenToGUIPoint(sp) );
		
  GUI.EndGroup();
	
}

You’ll notice that I’m calling both functions from within the group. So when I declare gp it’s the position (2,2) within that group. Without knowing the group’s rect, or the rects of any other parent groups or windows, I can convert that point to a net/overall/global position in ā€œscreen spaceā€. Thus the output is (7,7) (the group is in 5, then the point is in another 2 from there). When I declare sp it’s that same net/overall/global position and when called within the group the result is the ā€œlocalā€ position for that same position. Thus the output is (2,2).

If you use either function while not in a group, window or other contained context then it does no coversion.

None of the above converts your Unity GUI position into a frame of reference needed by ScreenToWorldPoint which is what you’ll need to get a world position. ScreenToWorldPoint requires you to specify a position (x,y), using the bottom-left at (0,0). So you have to do a small conversion of the y value yourself.

1 Like

Thanks,

It was something wrong with my understanding of how GUIUtility.GUIToScreenPoint works. When thinking about how GUI layout works it make sense that it would be relative to the block, but there will probably be many newbies soon who like me don’t bother to reread the GUI manual and think about the implication, so I will put a documentation bug/enhancement report about mentioning GUIToScreenPoint is relative to current block in its scripting refernce.

cheers,
Grant

This should convert the Y to screen space to GUI space. :slight_smile:

function ScreenToGUIPoint(input:Vector2):Vector2
{
	return Vector2(input.x, Interpolate(input.y, Screen.height, 0, 0, Screen.height));
}

function Interpolate(xVar, xMin, xMax, yMin, yMax):float
{
	return ( (xVar - xMin) / (xMax - xMin) ) * (yMax - yMin) + yMin;
}

waaw, so complicated if you express that ā€˜Interpolate’ you will see its equals to Screen.height - input.y