- Home /
Want to get the location of the GameView Window
I'm trying to make a macro recorder/player for the Unity editor, and I'm having trouble with the mouse input. I'm using this library (https://inputsimulator.codeplex.com/) to set the mouse position and simulate clicks, as I couldn't find a way to do it in Unity. The problem is that I need to know the location of the currently active game view in order to determine where on the monitor to position the cursor.
The following code:
public static EditorWindow GetMainGameView()
{
System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly;
Type type = assembly.GetType("UnityEditor.GameView");
EditorWindow gameview = EditorWindow.GetWindow(type);
return gameview;
}
gets me a reference to the GameView, but I couldn't find the information I needed in that class (position.x and position.y only tell me the offset of the drawing area relative to the tab). So does anyone know how I can find the GameView location relative to the monitor in Windows?
Same problem here: I need the position of my rendering pane relative to the screen as I need to transform special pointer input data, which is given in screen pixels.
Answer by St0fF · Mar 09, 2015 at 01:08 PM
I think I got it figured out ...
EDIT: changed it all again.
EDIT 2: added a windows implementation of wkwan's idea (see comments)
The short way on Windows:
parameters: master.width / master.height is the resolution we wanted to have
Screen.width / Screen.height is what Unity is running atm.
This solution is used to convert screen-coordinate input into pixel-exact positions referring to a (master.width, master.height) - resolution.
[StructLayout( LayoutKind.Sequential )]
public struct POINT
{
public int X;
public int Y;
public static implicit operator Vector2( POINT p )
{
return new Vector2( p.X, p.Y );
}
}
[DllImport( "user32.dll" )][return: MarshalAs( UnmanagedType.Bool )]
static extern bool GetCursorPos( out POINT lpPoint );
public static void Init( PanoramaMaster master )
{
Vector2 inputCursor = Input.mousePosition;
// flip input Cursor y (as the Reference "0" is the last scanline)
inputCursor.y = Screen.height - 1 - inputCursor.y;
POINT p;
GetCursorPos( out p );
renderRegionOffset = p - inputCursor;
renderRegionScale = new Vector2( (float) master.width / Screen.width, (float) master.height / Screen.height );
Debug.Log( "Scale: " + renderRegionScale + "\nOffset: " + renderRegionOffset + "\n" );
}
Don't do it like this: Earlier I came up with the following function, which gets the offset of the gameView's rendering region within its containing window's client region. I.e. Unity, or the window around a stand-alone gameview. Then I found some nice WinAPI references to find the missing pieces (window position, size of decorations):
[DllImport( "user32.dll" )]
static extern int GetSystemMetrics( SystemMetric smIndex );
[DllImport( "user32.dll" )]
static extern IntPtr GetActiveWindow();
[DllImport( "user32.dll", SetLastError = true )]
static extern bool GetWindowRect( IntPtr hwnd, out RECT lpRect );
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;
public override string ToString()
{
return string.Format( System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom );
}
}
public enum SystemMetric : int
{
SM_CXSCREEN = 0, // 0x00
SM_CYSCREEN = 1, // 0x01
SM_CXVSCROLL = 2, // 0x02
SM_CYHSCROLL = 3, // 0x03
SM_CYCAPTION = 4, // 0x04
SM_CXBORDER = 5, // 0x05
SM_CYBORDER = 6, // 0x06
// [...] shortened ...
}
public static Vector2 PixelOffsetFromScreen()
{
System.Type T = System.Type.GetType( "UnityEditor.GameView,UnityEditor" );
EditorWindow gameview = EditorWindow.GetWindow( T );
Rect Pom = gameview.position;
System.Reflection.MethodInfo RenderRect = T.GetMethod( "GetMainGameViewRenderRect", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static );
Rect ReRe = (Rect) RenderRect.Invoke( null, null );
RECT WinR;
GetWindowRect( GetActiveWindow(), out WinR );
int bw = GetSystemMetrics( SystemMetric.SM_CXBORDER );
int bh = GetSystemMetrics( SystemMetric.SM_CYBORDER );
int ch = GetSystemMetrics( SystemMetric.SM_CYCAPTION );
// try to retrieve the Window's client rect and its position on screen
Vector2 Res;
Res = new Vector2( WinR.Left + bw + Pom.xMin + ReRe.xMin, WinR.Top + ch + bh + Pom.yMin + ReRe.yMin );
return Res;
}
The final cut it needs: make it also work with a compiled game, where there's no editor available ...
Sorry for really late reply, I didn't see your response. Anyways, I found a way of doing that doesn't require GetWindow(), so it should work in the case where there's no editor. I just used an operating system call (had to do it separately for Win and $$anonymous$$ac) to get the current position of the cursor. Since Input.mousePosition gives you the mouse position relative to the bottom left of the GameView, and the operating system gives you the mouse position relative to the top left of the entire screen, you can take those numbers in addition to Screen.width and Screen.height to calculate the bounds of the GameView.
Wow, excellent idea - I'll probably have a try with that, as it severely reduces code in case of windows. Thank you very much!
Your answer
Follow this Question
Related Questions
Editor Window - How to center a window. 3 Answers
Create a custom fullscreen game view window 0 Answers
Change gameview ratio / resolution using a custom inspector? 1 Answer
How to change aspect ratio of Game View from Unity Editor scripting API 2 Answers
Need Help getting 4 different GUIS on 4 Different Viewport Cameras 0 Answers